diff --git a/Changelog.md b/Changelog.md index d5ff1204c..da14b7d16 100644 --- a/Changelog.md +++ b/Changelog.md @@ -25,6 +25,7 @@ Bugfixes: * Allow `type(Contract).name` for abstract contracts and interfaces. * Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions. * Type Checker: Disallow ``using for`` directive inside interfaces. + * Immutables: Disallow assigning immutables more than once during their declaration. ### 0.7.0 (2020-07-28) diff --git a/libsolidity/analysis/ImmutableValidator.cpp b/libsolidity/analysis/ImmutableValidator.cpp index 5af640e58..f6fe498ea 100644 --- a/libsolidity/analysis/ImmutableValidator.cpp +++ b/libsolidity/analysis/ImmutableValidator.cpp @@ -34,10 +34,12 @@ void ImmutableValidator::analyze() for (ContractDefinition const* contract: linearizedContracts) for (VariableDeclaration const* stateVar: contract->stateVariables()) if (stateVar->value()) - { + m_initializedStateVariables.emplace(stateVar); + + for (ContractDefinition const* contract: linearizedContracts) + for (VariableDeclaration const* stateVar: contract->stateVariables()) + if (stateVar->value()) stateVar->value()->accept(*this); - solAssert(m_initializedStateVariables.emplace(stateVar).second, ""); - } for (ContractDefinition const* contract: linearizedContracts) if (contract->constructor()) diff --git a/test/libsolidity/syntaxTests/immutable/variable_declaration_already.sol b/test/libsolidity/syntaxTests/immutable/variable_declaration_already.sol new file mode 100644 index 000000000..6c204d05e --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/variable_declaration_already.sol @@ -0,0 +1,10 @@ +contract C { + uint immutable z = 2; + uint immutable x = z = y = 3; + uint immutable y = 5; +} +// ---- +// TypeError 1581: (62-63): Immutable variables can only be initialized inline or assigned directly in the constructor. +// TypeError 1574: (62-63): Immutable state variable already initialized. +// TypeError 1581: (66-67): Immutable variables can only be initialized inline or assigned directly in the constructor. +// TypeError 1574: (66-67): Immutable state variable already initialized. diff --git a/test/libsolidity/syntaxTests/immutable/variable_declaration_value.sol b/test/libsolidity/syntaxTests/immutable/variable_declaration_value.sol new file mode 100644 index 000000000..db8dd6494 --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/variable_declaration_value.sol @@ -0,0 +1,6 @@ +contract C { + int immutable x = x = 5; +} +// ---- +// TypeError 1581: (35-36): Immutable variables can only be initialized inline or assigned directly in the constructor. +// TypeError 1574: (35-36): Immutable state variable already initialized.