diff options
author | Federico Bond <federicobond@gmail.com> | 2016-12-13 10:59:53 +0800 |
---|---|---|
committer | Federico Bond <federicobond@gmail.com> | 2016-12-13 11:32:37 +0800 |
commit | de720e643d8c54c613356bfcdcb6c49984460a17 (patch) | |
tree | 68cf22d6ab999f316ff3ec967029015b3aae6df5 | |
parent | 1c3605362d6018f5ab72cc84c7511fb49c15d126 (diff) | |
download | dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.tar dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.tar.gz dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.tar.bz2 dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.tar.lz dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.tar.xz dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.tar.zst dexon-solidity-de720e643d8c54c613356bfcdcb6c49984460a17.zip |
Improve error message when trying to modify constant variables
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 7 | ||||
-rw-r--r-- | libsolidity/ast/ASTAnnotations.h | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 11 |
3 files changed, 19 insertions, 1 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 7235b57a..e414e27c 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1529,6 +1529,8 @@ bool TypeChecker::visit(Identifier const& _identifier) !!annotation.referencedDeclaration, "Referenced declaration is null after overload resolution." ); + auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(annotation.referencedDeclaration); + annotation.isConstant = variableDeclaration != nullptr && variableDeclaration->isConstant(); annotation.isLValue = annotation.referencedDeclaration->isLValue(); annotation.type = annotation.referencedDeclaration->type(); if (!annotation.type) @@ -1612,7 +1614,10 @@ void TypeChecker::requireLValue(Expression const& _expression) { _expression.annotation().lValueRequested = true; _expression.accept(*this); - if (!_expression.annotation().isLValue) + + if (_expression.annotation().isConstant) + typeError(_expression.location(), "Cannot assign to a constant variable."); + else if (!_expression.annotation().isLValue) typeError(_expression.location(), "Expression has to be an lvalue."); } diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 768e56db..9c4c3ae8 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -154,6 +154,8 @@ struct ExpressionAnnotation: ASTAnnotation { /// Inferred type of the expression. TypePointer type; + /// Whether the expression is a constant variable + bool isConstant = false; /// Whether it is an LValue (i.e. something that can be assigned to). bool isLValue = false; /// Whether the expression is used in a context where the LValue is actually required. diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index a4e601f7..576421fd 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -4865,6 +4865,17 @@ BOOST_AUTO_TEST_CASE(does_not_warn_msg_value_in_modifier_following_non_payable_p CHECK_SUCCESS_NO_WARNINGS(text); } +BOOST_AUTO_TEST_CASE(assignment_to_constant) +{ + char const* text = R"( + contract c { + uint constant a = 1; + function f() { a = 2; } + } + )"; + CHECK_ERROR(text, TypeError, "Cannot assign to a constant variable."); +} + BOOST_AUTO_TEST_SUITE_END() } |