aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-04-11 23:44:44 +0800
committerchriseth <chris@ethereum.org>2018-04-12 04:00:21 +0800
commitb5a696ad48780bf0614eef2a737a2e89963d4640 (patch)
treefcc1d4e910eef36fef15fca3e036f3039146450c
parent52f68d3b63d65c31215e683899b96b27e2e24ee1 (diff)
downloaddexon-solidity-b5a696ad48780bf0614eef2a737a2e89963d4640.tar.gz
dexon-solidity-b5a696ad48780bf0614eef2a737a2e89963d4640.tar.zst
dexon-solidity-b5a696ad48780bf0614eef2a737a2e89963d4640.zip
Properly cope with constructor headers.
-rw-r--r--libsolidity/parsing/Parser.cpp9
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol8
3 files changed, 21 insertions, 3 deletions
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index ea092a74..2d8ca7d3 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -365,9 +365,10 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(
Token::Value token = m_scanner->currentToken();
if (_allowModifiers && token == Token::Identifier)
{
- // If the name is empty, then this can either be a modifier (fallback function declaration)
+ // If the name is empty (and this is not a constructor),
+ // then this can either be a modifier (fallback function declaration)
// or the name of the state variable (function type name plus variable).
- if (result.name->empty() && (
+ if ((result.name->empty() && !result.isConstructor) && (
m_scanner->peekNextToken() == Token::Semicolon ||
m_scanner->peekNextToken() == Token::Assign
))
@@ -385,7 +386,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(
if (
(result.visibility == Declaration::Visibility::External || result.visibility == Declaration::Visibility::Internal) &&
result.modifiers.empty() &&
- result.name->empty()
+ (result.name->empty() && !result.isConstructor)
)
break;
parserError(string(
@@ -437,6 +438,7 @@ ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(A
FunctionHeaderParserResult header = parseFunctionHeader(false, true, _contractName);
if (
+ header.isConstructor ||
!header.modifiers.empty() ||
!header.name->empty() ||
m_scanner->currentToken() == Token::Semicolon ||
@@ -802,6 +804,7 @@ ASTPointer<FunctionTypeName> Parser::parseFunctionType()
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
FunctionHeaderParserResult header = parseFunctionHeader(true, false);
+ solAssert(!header.isConstructor, "Tried to parse type as constructor.");
return nodeFactory.createNode<FunctionTypeName>(
header.parameters,
header.returnParameters,
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol
new file mode 100644
index 00000000..95ebc179
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol
@@ -0,0 +1,7 @@
+contract C {
+ // Fool parser into parsing a constructor as a function type.
+ constructor() x;
+}
+// ----
+// Warning: (83-99): Modifiers of functions without implementation are ignored.
+// DeclarationError: (97-98): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
new file mode 100644
index 00000000..b7763d28
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
@@ -0,0 +1,8 @@
+contract C {
+ // Fool parser into parsing a constructor as a function type.
+ function f() {
+ constructor() x;
+ }
+}
+// ----
+// ParserError: (118-118): Expected token Semicolon got 'Identifier'