From a7150f85a686bd2e96c01aa71f02fb0d762e0dd0 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Thu, 12 Jul 2018 16:17:30 +0200 Subject: [PATCH] Ensures an empty use of var keyword is caught with the proper error message. --- libsolidity/analysis/TypeChecker.cpp | 21 +++++++++++++++++-- .../parsing/tuples_decl_without_rhs.sol | 7 +++++++ .../syntaxTests/types/var_empty_decl_0.sol | 9 ++++++++ .../syntaxTests/types/var_empty_decl_1.sol | 8 +++++++ .../syntaxTests/types/var_empty_decl_2.sol | 9 ++++++++ .../syntaxTests/types/var_empty_decl_3.sol | 7 +++++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/parsing/tuples_decl_without_rhs.sol create mode 100644 test/libsolidity/syntaxTests/types/var_empty_decl_0.sol create mode 100644 test/libsolidity/syntaxTests/types/var_empty_decl_1.sol create mode 100644 test/libsolidity/syntaxTests/types/var_empty_decl_2.sol create mode 100644 test/libsolidity/syntaxTests/types/var_empty_decl_3.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 8536e9341..d2fb92817 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -709,6 +710,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) // TypeChecker at the VariableDeclarationStatement level. TypePointer varType = _variable.annotation().type; solAssert(!!varType, "Failed to infer variable type."); + if (_variable.value()) expectType(*_variable.value(), *varType); if (_variable.isConstant()) @@ -1079,10 +1081,25 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { // No initial value is only permitted for single variables with specified type. if (_statement.declarations().size() != 1 || !_statement.declarations().front()) - m_errorReporter.fatalTypeError(_statement.location(), "Assignment necessary for type detection."); + { + if (boost::algorithm::all_of_equal(_statement.declarations(), nullptr)) + { + // The syntax checker has already generated an error for this case (empty LHS tuple). + solAssert(m_errorReporter.hasErrors(), ""); + + // It is okay to return here, as there are no named components on the + // left-hand-side that could cause any damage later. + return false; + } + else + // Bailing out *fatal* here, as those (untyped) vars may be used later, and diagnostics wouldn't be helpful then. + m_errorReporter.fatalTypeError(_statement.location(), "Use of the \"var\" keyword is disallowed."); + } + VariableDeclaration const& varDecl = *_statement.declarations().front(); if (!varDecl.annotation().type) - m_errorReporter.fatalTypeError(_statement.location(), "Assignment necessary for type detection."); + m_errorReporter.fatalTypeError(_statement.location(), "Use of the \"var\" keyword is disallowed."); + if (auto ref = dynamic_cast(type(varDecl).get())) { if (ref->dataStoredIn(DataLocation::Storage)) diff --git a/test/libsolidity/syntaxTests/parsing/tuples_decl_without_rhs.sol b/test/libsolidity/syntaxTests/parsing/tuples_decl_without_rhs.sol new file mode 100644 index 000000000..dba3e7acc --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/tuples_decl_without_rhs.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + (uint a, uint b, uint c); + } +} +// ---- +// ParserError: (76-77): Expected '=' but got ';' diff --git a/test/libsolidity/syntaxTests/types/var_empty_decl_0.sol b/test/libsolidity/syntaxTests/types/var_empty_decl_0.sol new file mode 100644 index 000000000..51b949def --- /dev/null +++ b/test/libsolidity/syntaxTests/types/var_empty_decl_0.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure { + var (); + var (,); + } +} +// ---- +// SyntaxError: (52-58): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty. +// SyntaxError: (68-75): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty. diff --git a/test/libsolidity/syntaxTests/types/var_empty_decl_1.sol b/test/libsolidity/syntaxTests/types/var_empty_decl_1.sol new file mode 100644 index 000000000..20a004ff9 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/var_empty_decl_1.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure { + var a; + a.NeverReachedByParser(); + } +} +// ---- +// TypeError: (52-57): Use of the "var" keyword is disallowed. diff --git a/test/libsolidity/syntaxTests/types/var_empty_decl_2.sol b/test/libsolidity/syntaxTests/types/var_empty_decl_2.sol new file mode 100644 index 000000000..de2abc9ae --- /dev/null +++ b/test/libsolidity/syntaxTests/types/var_empty_decl_2.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure { + var (b, c); + b.WeMustNotReachHere(); + c.FailsToLookupToo(); + } +} +// ---- +// TypeError: (52-62): Use of the "var" keyword is disallowed. diff --git a/test/libsolidity/syntaxTests/types/var_empty_decl_3.sol b/test/libsolidity/syntaxTests/types/var_empty_decl_3.sol new file mode 100644 index 000000000..26ee824e4 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/var_empty_decl_3.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + var (d, e,); + } +} +// ---- +// TypeError: (52-63): Use of the "var" keyword is disallowed.