Skip to content

Commit 1c12b4f

Browse files
authored
ExprEngine: Handling cases when for condition is always false (danmar#2984)
1 parent bd22070 commit 1c12b4f

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

lib/exprengine.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,6 +2669,10 @@ static std::string execute(const Token *start, const Token *end, Data &data)
26692669
data.assignValue(tok, varid, loopValues);
26702670
tok = tok->linkAt(1);
26712671
loopValues->loopScope = tok->next()->scope();
2672+
// Check whether the condition expression is always false
2673+
if (tok->next() && (initValue > lastValue)) {
2674+
tok = tok->next()->link();
2675+
}
26722676
continue;
26732677
}
26742678
}

test/testexprengine.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class TestExprEngine : public TestFixture {
7979
TEST_CASE(switch2);
8080

8181
TEST_CASE(for1);
82+
TEST_CASE(forAlwaysFalse1);
8283

8384
TEST_CASE(while1);
8485
TEST_CASE(while2);
@@ -660,6 +661,22 @@ class TestExprEngine : public TestFixture {
660661
expr(code, "=="));
661662
}
662663

664+
void forAlwaysFalse1() {
665+
const char code[] = "int f() {\n"
666+
" int a = 19;\n"
667+
" for (int i = 0; i < 0; i++)\n"
668+
" a += 8;\n"
669+
" for (int i = 0; i < 1; i++)\n"
670+
" a += 23;\n"
671+
" for (int i = 100; i >= 1; i--)\n"
672+
" a += 23;\n"
673+
" return a == 42;\n"
674+
"}";
675+
const char expected[] = "(and (>= $4 (- 2147483648)) (<= $4 2147483647))\n"
676+
"(= (+ $4 23) 42)\n"
677+
"z3::sat\n";
678+
ASSERT_EQUALS(expected, expr(code, "=="));
679+
}
663680

664681
void while1() {
665682
const char code[] = "void f(int y) {\n"

0 commit comments

Comments
 (0)