Skip to content

Commit dee1c11

Browse files
authored
Merge pull request #6668 from ethereum/smt_fix_short_circuit
Fix short circuit with assignments
2 parents 36c78ba + 80712f4 commit dee1c11

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

libsolidity/formal/SMTChecker.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,17 +1230,16 @@ void SMTChecker::booleanOperation(BinaryOperation const& _op)
12301230
{
12311231
// @TODO check that both of them are not constant
12321232
_op.leftExpression().accept(*this);
1233-
auto touchedVars = touchedVariables(_op.leftExpression());
12341233
if (_op.getOperator() == Token::And)
12351234
{
12361235
auto indicesAfterSecond = visitBranch(&_op.rightExpression(), expr(_op.leftExpression()));
1237-
mergeVariables(touchedVars, !expr(_op.leftExpression()), copyVariableIndices(), indicesAfterSecond);
1236+
mergeVariables(touchedVariables(_op.rightExpression()), !expr(_op.leftExpression()), copyVariableIndices(), indicesAfterSecond);
12381237
defineExpr(_op, expr(_op.leftExpression()) && expr(_op.rightExpression()));
12391238
}
12401239
else
12411240
{
12421241
auto indicesAfterSecond = visitBranch(&_op.rightExpression(), !expr(_op.leftExpression()));
1243-
mergeVariables(touchedVars, expr(_op.leftExpression()), copyVariableIndices(), indicesAfterSecond);
1242+
mergeVariables(touchedVariables(_op.rightExpression()), expr(_op.leftExpression()), copyVariableIndices(), indicesAfterSecond);
12441243
defineExpr(_op, expr(_op.leftExpression()) || expr(_op.rightExpression()));
12451244
}
12461245
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pragma experimental SMTChecker;
2+
3+
contract C
4+
{
5+
bool b;
6+
function f() public {
7+
if ((b = false) && (b == true)) {}
8+
if ((b == false) && (b = true)) {}
9+
if ((b = false) && (b = true)) {}
10+
if ((b == false) && (b == true)) {}
11+
if ((b = true) && b) {}
12+
}
13+
}
14+
// ----
15+
// Warning: (84-110): Condition is always false.
16+
// Warning: (121-147): Condition is always true.
17+
// Warning: (158-183): Condition is always false.
18+
// Warning: (194-221): Condition is always false.
19+
// Warning: (232-247): Condition is always true.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
pragma experimental SMTChecker;
2+
3+
contract C
4+
{
5+
bool b;
6+
function g(bool _b) internal returns (bool) {
7+
b = _b;
8+
return b;
9+
}
10+
function f() public {
11+
if (g(false) && (b == true)) {}
12+
if ((b == false) && g(true)) {}
13+
if (g(false) && g(true)) {}
14+
if (g(false) && (b == true)) {}
15+
if (g(true) && b) {}
16+
}
17+
}
18+
// ----
19+
// Warning: (156-179): Condition is always false.
20+
// Warning: (190-213): Condition is always true.
21+
// Warning: (224-243): Condition is always false.
22+
// Warning: (254-277): Condition is always false.
23+
// Warning: (288-300): Condition is always true.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pragma experimental SMTChecker;
2+
3+
contract C
4+
{
5+
bool b;
6+
function f() public {
7+
if ((b = true) || (b == false)) {}
8+
if ((b == true) || (b = false)) {}
9+
if ((b = true) || (b = false)) {}
10+
if ((b == true) || (b == false)) {}
11+
if ((b = false) || b) {}
12+
}
13+
}
14+
// ----
15+
// Warning: (84-110): Condition is always true.
16+
// Warning: (121-147): Condition is always true.
17+
// Warning: (158-183): Condition is always true.
18+
// Warning: (194-221): Condition is always true.
19+
// Warning: (232-248): Condition is always false.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
pragma experimental SMTChecker;
2+
3+
contract C
4+
{
5+
bool b;
6+
function g(bool _b) internal returns (bool) {
7+
b = _b;
8+
return b;
9+
}
10+
function f() public {
11+
if (g(true) || (b == false)) {}
12+
if ((b == true) || g(false)) {}
13+
if (g(true) || g(false)) {}
14+
if (g(true) || (b == false)) {}
15+
if (g(false) || b) {}
16+
}
17+
}
18+
// ----
19+
// Warning: (156-179): Condition is always true.
20+
// Warning: (190-213): Condition is always true.
21+
// Warning: (224-243): Condition is always true.
22+
// Warning: (254-277): Condition is always true.
23+
// Warning: (288-301): Condition is always false.

0 commit comments

Comments
 (0)