Skip to content

Commit bcb25ed

Browse files
authored
Merge pull request #5669 from tautschnig/decl-side-effect
Cleanup side effects in declaration initialisers
2 parents 95097a8 + e63f895 commit bcb25ed

File tree

4 files changed

+56
-5
lines changed

4 files changed

+56
-5
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
int foo()
2+
{
3+
__CPROVER_assert(0, "");
4+
}
5+
6+
int main()
7+
{
8+
struct
9+
{
10+
int a : 2;
11+
} b;
12+
int c;
13+
short d;
14+
// this is to make sure the fix for the below assignment does not introduce a
15+
// new bug
16+
d |= b.a = c >= 0;
17+
18+
// we previously weren't able to handle the below
19+
short a = (a ^= 0) || foo();
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
Invariant check failed
9+
--
10+
This example previously failed with an unhandled side effect in symex.

src/goto-programs/goto_convert.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,10 +633,15 @@ void goto_convertt::convert_decl(
633633
// Decl must be visible before initializer.
634634
copy(tmp, DECL, dest);
635635

636-
code_assignt assign(code.op0(), initializer);
637-
assign.add_source_location()=tmp.source_location();
636+
clean_expr(initializer, dest, mode);
638637

639-
convert_assign(assign, dest, mode);
638+
if(initializer.is_not_nil())
639+
{
640+
code_assignt assign(code.op0(), initializer);
641+
assign.add_source_location() = tmp.source_location();
642+
643+
convert_assign(assign, dest, mode);
644+
}
640645
}
641646

642647
// now create a 'dead' instruction -- will be added after the

src/goto-programs/goto_convert_side_effect.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,24 @@ void goto_convertt::remove_assignment(
128128
// revert assignment in the expression to its LHS
129129
if(result_is_used)
130130
{
131-
exprt lhs;
132-
lhs.swap(to_binary_expr(expr).op0());
131+
exprt lhs = to_binary_expr(expr).op0();
132+
// assign_* statements can have an lhs operand with a different type than
133+
// that of the overall expression, because of integer promotion (which may
134+
// have introduced casts to the lhs).
135+
if(expr.type() != lhs.type())
136+
{
137+
// Skip over those type casts, but also
138+
// make sure the resulting expression has the same type as before.
139+
DATA_INVARIANT(
140+
lhs.id() == ID_typecast,
141+
id2string(expr.id()) +
142+
" expression with different operand type expected to have a "
143+
"typecast");
144+
DATA_INVARIANT(
145+
to_typecast_expr(lhs).op().type() == expr.type(),
146+
id2string(expr.id()) + " type mismatch in lhs operand");
147+
lhs = to_typecast_expr(lhs).op();
148+
}
133149
expr.swap(lhs);
134150
}
135151
else

0 commit comments

Comments
 (0)