SMTChecker: External function call with struct member is not getter

if a struct has a member that is a function pointer with `external`
attribute, and such a member is called, it is currently incorrectly
treated as a public getter in SMTEncoder.

The proposed fix is to make SMTEncoder::publicGetter more strict in
deciding whether an expression is a public getter.
The added condition, that the access happens on a state variable, is
exactly what is checked later with an assertion that is currently
failing.
This commit is contained in:
Martin Blicha 2023-05-26 14:10:33 +02:00
parent bb16f61e1c
commit 8ca453f82e
2 changed files with 35 additions and 1 deletions

View File

@ -2839,7 +2839,8 @@ smtutil::Expression SMTEncoder::contractAddressValue(FunctionCall const& _f)
VariableDeclaration const* SMTEncoder::publicGetter(Expression const& _expr) const { VariableDeclaration const* SMTEncoder::publicGetter(Expression const& _expr) const {
if (auto memberAccess = dynamic_cast<MemberAccess const*>(&_expr)) if (auto memberAccess = dynamic_cast<MemberAccess const*>(&_expr))
return dynamic_cast<VariableDeclaration const*>(memberAccess->annotation().referencedDeclaration); if (auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(memberAccess->annotation().referencedDeclaration))
return variableDeclaration->isStateVariable() ? variableDeclaration : nullptr;
return nullptr; return nullptr;
} }

View File

@ -0,0 +1,33 @@
struct S {
function() external returns (uint) x;
}
contract C {
function X() public pure returns (uint) {
return 1;
}
uint y;
uint z;
function setZ(uint _z) public {
z = _z;
}
function f() public returns (uint) {
S memory s;
s.x = this.X;
require(y == 0);
require(z == 0);
uint ret = s.x();
assert(y == 0); // should hold
assert(z == 0); // can report violation due to overapproximation after externall call s.x()
return ret;
}
}
// ----
// Warning 6328: (431-445): CHC: Assertion violation happens here.
// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them.