Disallow initialization of immutables in for loops and ternary expressions

This commit is contained in:
Nikola Matic 2023-05-16 15:45:11 +02:00
parent 1250ee778d
commit 9d91899cc4
6 changed files with 57 additions and 2 deletions

View File

@ -9,6 +9,7 @@ Compiler Features:
Bugfixes:
* Immutables: Disallow initialization of immutables in for loops and ternary expressions.
* SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine.

View File

@ -73,6 +73,16 @@ bool ImmutableValidator::visit(Assignment const& _assignment)
return false;
}
bool ImmutableValidator::visit(Conditional const& _conditional)
{
ScopedSaveAndRestore branchGuard{m_inBranch, true};
_conditional.condition().accept(*this);
_conditional.trueExpression().accept(*this);
_conditional.falseExpression().accept(*this);
return false;
}
bool ImmutableValidator::visit(FunctionDefinition const& _functionDefinition)
{
@ -132,6 +142,21 @@ bool ImmutableValidator::visit(WhileStatement const& _whileStatement)
return false;
}
bool ImmutableValidator::visit(ForStatement const& _forStatement)
{
ScopedSaveAndRestore forLoopGuard{m_inLoop, true};
if (auto&& initializationExpression = _forStatement.initializationExpression())
initializationExpression->accept(*this);
if (auto&& condition = _forStatement.condition())
condition->accept(*this);
if (auto&& loopExpression = _forStatement.loopExpression())
loopExpression->accept(*this);
_forStatement.body().accept(*this);
return false;
}
bool ImmutableValidator::visit(TryStatement const& _tryStatement)
{
ScopedSaveAndRestore constructorGuard{m_inTryStatement, true};
@ -228,7 +253,7 @@ void ImmutableValidator::analyseVariableReference(VariableDeclaration const& _va
m_errorReporter.typeError(
4599_error,
_expression.location(),
"Cannot write to immutable here: Immutable variables cannot be initialized inside an if statement."
"Cannot write to immutable here: Immutable variables cannot be initialized inside a conditional (if/ternary) statement."
);
else if (m_inTryStatement)
m_errorReporter.typeError(

View File

@ -50,11 +50,13 @@ public:
private:
bool visit(Assignment const& _assignment);
bool visit(Conditional const& _conditional);
bool visit(FunctionDefinition const& _functionDefinition);
bool visit(ModifierDefinition const& _modifierDefinition);
bool visit(MemberAccess const& _memberAccess);
bool visit(IfStatement const& _ifStatement);
bool visit(WhileStatement const& _whileStatement);
bool visit(ForStatement const& _forStatement);
bool visit(TryStatement const& _tryStatement);
void endVisit(IdentifierPath const& _identifierPath);
void endVisit(Identifier const& _identifier);

View File

@ -6,4 +6,4 @@ contract C {
}
}
// ----
// TypeError 4599: (86-87): Cannot write to immutable here: Immutable variables cannot be initialized inside an if statement.
// TypeError 4599: (86-87): Cannot write to immutable here: Immutable variables cannot be initialized inside a conditional (if/ternary) statement.

View File

@ -0,0 +1,12 @@
contract C {
uint immutable x;
constructor() {
for (x = 1; x < 10; ++x)
x = 5;
}
}
// ----
// TypeError 6672: (68-69): Cannot write to immutable here: Immutable variables cannot be initialized inside a loop.
// TypeError 6672: (85-86): Cannot write to immutable here: Immutable variables cannot be initialized inside a loop.
// TypeError 6672: (100-101): Cannot write to immutable here: Immutable variables cannot be initialized inside a loop.

View File

@ -0,0 +1,15 @@
contract A
{
uint256 immutable x;
uint256 y = 0;
constructor(bool _branch)
{
_branch ? x = 1 : y = 2;
_branch ? y = 3 : x = 4;
}
}
// ----
// TypeError 4599: (112-113): Cannot write to immutable here: Immutable variables cannot be initialized inside a conditional (if/ternary) statement.
// TypeError 4599: (153-154): Cannot write to immutable here: Immutable variables cannot be initialized inside a conditional (if/ternary) statement.