Merge pull request #4507 from ethereum/v050-var-keyword-trace-removals

Ensures an empty use of var keyword is caught with the proper non-fatal error message
This commit is contained in:
Alex Beregszaszi 2018-08-01 10:59:26 +01:00 committed by GitHub
commit 21888e246b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 2 deletions

View File

@ -22,6 +22,7 @@
#include <libsolidity/analysis/TypeChecker.h>
#include <memory>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/reversed.hpp>
@ -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<ReferenceType const*>(type(varDecl).get()))
{
if (ref->dataStoredIn(DataLocation::Storage))

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
(uint a, uint b, uint c);
}
}
// ----
// ParserError: (76-77): Expected '=' but got ';'

View File

@ -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.

View File

@ -0,0 +1,8 @@
contract C {
function f() public pure {
var a;
a.NeverReachedByParser();
}
}
// ----
// TypeError: (52-57): Use of the "var" keyword is disallowed.

View File

@ -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.

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
var (d, e,);
}
}
// ----
// TypeError: (52-63): Use of the "var" keyword is disallowed.