Skip to content

Commit 36ab23f

Browse files
authored
ExprEngine: Handle pointers to struct as function argument (danmar#2945)
1 parent 81c3ac7 commit 36ab23f

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

lib/exprengine.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,8 +2625,19 @@ static std::string execute(const Token *start, const Token *end, Data &data)
26252625
if (!structVal1)
26262626
structVal1 = createVariableValue(*structToken->variable(), data);
26272627
auto structVal = std::dynamic_pointer_cast<ExprEngine::StructValue>(structVal1);
2628-
if (!structVal)
2629-
throw ExprEngineException(tok2, "Unhandled assignment in loop");
2628+
if (!structVal) {
2629+
// Handle pointer to a struct
2630+
if (auto structPtr = std::dynamic_pointer_cast<ExprEngine::ArrayValue>(structVal1)) {
2631+
if (structPtr && structPtr->pointer && !structPtr->data.empty()) {
2632+
auto indexValue = std::make_shared<ExprEngine::IntRange>("0", 0, 0);
2633+
for (auto val: structPtr->read(indexValue)) {
2634+
structVal = std::dynamic_pointer_cast<ExprEngine::StructValue>(val.second);
2635+
}
2636+
}
2637+
}
2638+
if (!structVal)
2639+
throw ExprEngineException(tok2, "Unhandled assignment in loop");
2640+
}
26302641

26312642
data.assignStructMember(tok2, &*structVal, memberName, memberValue);
26322643
continue;

test/testexprengine.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ class TestExprEngine : public TestFixture {
114114
TEST_CASE(structMember2);
115115
TEST_CASE(structMember3);
116116

117+
TEST_CASE(pointerToStructInLoop);
118+
117119
TEST_CASE(ternaryOperator1);
118120
#endif
119121
}
@@ -816,6 +818,20 @@ class TestExprEngine : public TestFixture {
816818
ASSERT_EQUALS(expected, expr(code, "=="));
817819
}
818820

821+
void pointerToStructInLoop() {
822+
const char code[] = "struct S { int x; };\n"
823+
"void foo(struct S *s) {\n"
824+
" while (1)\n"
825+
" s->x = 42; \n"
826+
"}";
827+
828+
const char expected[] = "(and (>= $3 (- 2147483648)) (<= $3 2147483647))\n"
829+
"(= $3 42)\n"
830+
"z3::sat\n";
831+
832+
ASSERT_EQUALS(expected, expr(code, "=="));
833+
}
834+
819835

820836
void ternaryOperator1() {
821837
const char code[] = "void foo(signed char x) {\n"

0 commit comments

Comments
 (0)