[SMTChecker] Support delete

This commit is contained in:
Leonardo Alt 2019-05-06 18:24:15 +02:00
parent e99efec085
commit 2139c20776
8 changed files with 151 additions and 0 deletions

View File

@ -7,6 +7,7 @@ Language Features:
Compiler Features:
* SMTChecker: Support inherited state variables.
* SMTChecker: Support tuple assignments and function calls with multiple return values.
* SMTChecker: Support ``delete``.
Bugfixes:

View File

@ -546,6 +546,30 @@ void SMTChecker::endVisit(UnaryOperation const& _op)
);
break;
}
case Token::Delete:
{
auto const& subExpr = _op.subExpression();
if (auto decl = identifierToVariable(subExpr))
{
newValue(*decl);
setZeroValue(*decl);
}
else
{
solAssert(knownExpr(subExpr), "");
auto const& symbVar = m_expressions[&subExpr];
symbVar->increaseIndex();
setZeroValue(*symbVar);
if (dynamic_cast<IndexAccess const*>(&_op.subExpression()))
arrayIndexAssignment(_op.subExpression(), symbVar->currentValue());
else
m_errorReporter.warning(
_op.location(),
"Assertion checker does not yet implement \"delete\" for this expression."
);
}
break;
}
default:
m_errorReporter.warning(
_op.location(),

View File

@ -0,0 +1,21 @@
pragma experimental SMTChecker;
contract C
{
uint[] a;
function f(bool b) public {
a[2] = 3;
require(b);
if (b)
delete a;
else
delete a[2];
// Assertion fails as false positive because
// setZeroValue for arrays needs \forall i . a[i] = 0
// which is still unimplemented.
assert(a[2] == 0);
}
}
// ----
// Warning: (118-119): Condition is always true.
// Warning: (297-314): Assertion violation happens here

View File

@ -0,0 +1,15 @@
pragma experimental SMTChecker;
contract C
{
uint[][] a;
function f() public {
require(a[2][3] == 4);
delete a;
// Fails as false positive.
// setZeroValue needs forall for arrays.
assert(a[2][3] == 0);
}
}
// ----
// Warning: (194-214): Assertion violation happens here

View File

@ -0,0 +1,17 @@
pragma experimental SMTChecker;
contract C
{
uint[] a;
function f(bool b) public {
a[2] = 3;
require(!b);
if (b)
delete a;
else
delete a[2];
assert(a[2] == 0);
}
}
// ----
// Warning: (119-120): Condition is always false.

View File

@ -0,0 +1,19 @@
pragma experimental SMTChecker;
contract C
{
uint[][] a;
function f(bool b) public {
require(a[2][3] == 4);
if (b)
delete a;
else
delete a[2];
// Fails as false positive since
// setZeroValue for arrays needs forall
// which is unimplemented.
assert(a[2][3] == 0);
}
}
// ----
// Warning: (266-286): Assertion violation happens here

View File

@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C
{
uint[] a;
function g() internal {
delete a;
}
function h() internal {
delete a[2];
}
function f(bool b) public {
a[2] = 3;
require(b);
if (b)
g();
else
h();
// Assertion fails as false positive because
// setZeroValue for arrays needs \forall i . a[i] = 0
// which is still unimplemented.
assert(a[2] == 0);
}
}
// ----
// Warning: (201-202): Condition is always true.
// Warning: (367-384): Assertion violation happens here

View File

@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C
{
struct S
{
uint x;
}
function f(bool b) public {
S memory s;
s.x = 2;
if (b)
delete s;
else
delete s.x;
assert(s.x == 0);
}
}
// ----
// Warning: (73-192): Function state mutability can be restricted to pure
// Warning: (103-113): Assertion checker does not yet support the type of this variable.
// Warning: (117-120): Assertion checker does not yet support this expression.
// Warning: (117-124): Assertion checker does not yet implement such assignments.
// Warning: (165-168): Assertion checker does not yet support this expression.
// Warning: (158-168): Assertion checker does not yet implement "delete" for this expression.
// Warning: (179-182): Assertion checker does not yet support this expression.
// Warning: (172-188): Assertion violation happens here