mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #14198 from ethereum/disallow-immutable-initialization-in-try-catch
Disallow immutable initialization in try catch statements
This commit is contained in:
commit
347c966f08
@ -22,6 +22,7 @@ Bugfixes:
|
|||||||
* Antlr Grammar: Fix discrepancy with the parser, which allowed octal numbers.
|
* Antlr Grammar: Fix discrepancy with the parser, which allowed octal numbers.
|
||||||
* Antlr Grammar: Fix of a discrepancy with the parser, which allowed numbers followed by an identifier with no whitespace.
|
* Antlr Grammar: Fix of a discrepancy with the parser, which allowed numbers followed by an identifier with no whitespace.
|
||||||
* Antlr Grammar: Stricter rules for function definitions. The grammar will no longer accept as valid free functions having specifiers which are exclusive to contract functions.
|
* Antlr Grammar: Stricter rules for function definitions. The grammar will no longer accept as valid free functions having specifiers which are exclusive to contract functions.
|
||||||
|
* Immutables: Disallow initialization of immutables in try/catch statements.
|
||||||
* SMTChecker: Fix false positives in ternary operators that contain verification targets in its branches, directly or indirectly.
|
* SMTChecker: Fix false positives in ternary operators that contain verification targets in its branches, directly or indirectly.
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,6 +132,19 @@ bool ImmutableValidator::visit(WhileStatement const& _whileStatement)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImmutableValidator::visit(TryStatement const& _tryStatement)
|
||||||
|
{
|
||||||
|
ScopedSaveAndRestore constructorGuard{m_inTryStatement, true};
|
||||||
|
|
||||||
|
_tryStatement.externalCall().accept(*this);
|
||||||
|
|
||||||
|
for (auto&& clause: _tryStatement.clauses())
|
||||||
|
if (clause)
|
||||||
|
clause->accept(*this);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ImmutableValidator::endVisit(IdentifierPath const& _identifierPath)
|
void ImmutableValidator::endVisit(IdentifierPath const& _identifierPath)
|
||||||
{
|
{
|
||||||
if (auto const callableDef = dynamic_cast<CallableDeclaration const*>(_identifierPath.annotation().referencedDeclaration))
|
if (auto const callableDef = dynamic_cast<CallableDeclaration const*>(_identifierPath.annotation().referencedDeclaration))
|
||||||
@ -217,6 +230,12 @@ void ImmutableValidator::analyseVariableReference(VariableDeclaration const& _va
|
|||||||
_expression.location(),
|
_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 an if statement."
|
||||||
);
|
);
|
||||||
|
else if (m_inTryStatement)
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
4130_error,
|
||||||
|
_expression.location(),
|
||||||
|
"Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement."
|
||||||
|
);
|
||||||
else if (m_initializedStateVariables.count(&_variableReference))
|
else if (m_initializedStateVariables.count(&_variableReference))
|
||||||
{
|
{
|
||||||
if (!read)
|
if (!read)
|
||||||
|
@ -55,6 +55,7 @@ private:
|
|||||||
bool visit(MemberAccess const& _memberAccess);
|
bool visit(MemberAccess const& _memberAccess);
|
||||||
bool visit(IfStatement const& _ifStatement);
|
bool visit(IfStatement const& _ifStatement);
|
||||||
bool visit(WhileStatement const& _whileStatement);
|
bool visit(WhileStatement const& _whileStatement);
|
||||||
|
bool visit(TryStatement const& _tryStatement);
|
||||||
void endVisit(IdentifierPath const& _identifierPath);
|
void endVisit(IdentifierPath const& _identifierPath);
|
||||||
void endVisit(Identifier const& _identifier);
|
void endVisit(Identifier const& _identifier);
|
||||||
void endVisit(Return const& _return);
|
void endVisit(Return const& _return);
|
||||||
@ -78,6 +79,7 @@ private:
|
|||||||
bool m_inLoop = false;
|
bool m_inLoop = false;
|
||||||
bool m_inBranch = false;
|
bool m_inBranch = false;
|
||||||
bool m_inCreationContext = true;
|
bool m_inCreationContext = true;
|
||||||
|
bool m_inTryStatement = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
contract A
|
||||||
|
{
|
||||||
|
uint256 public immutable variable;
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
B b;
|
||||||
|
try b.foo(variable = 1)
|
||||||
|
{
|
||||||
|
variable = 2;
|
||||||
|
}
|
||||||
|
catch Panic(uint)
|
||||||
|
{
|
||||||
|
variable = 3;
|
||||||
|
}
|
||||||
|
catch Error(string memory)
|
||||||
|
{
|
||||||
|
variable = 4;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
variable = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract B
|
||||||
|
{
|
||||||
|
function foo(uint256) external pure
|
||||||
|
{
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >=byzantium
|
||||||
|
// ----
|
||||||
|
// TypeError 4130: (108-116): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
|
||||||
|
// TypeError 4130: (144-152): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
|
||||||
|
// TypeError 4130: (216-224): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
|
||||||
|
// TypeError 4130: (297-305): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
|
||||||
|
// TypeError 4130: (357-365): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
|
Loading…
Reference in New Issue
Block a user