Skip to content

Commit fd0f92d

Browse files
smowtontautschnig
authored andcommitted
Symex-dereference: simplify after deref
This is generally useful because it turns member-of-if into if-of-member, which avoids repeatedly quoting large complex if expressions in a with_exprt, but it is especially good for field sensitivity as it puts member expressions directly on top of symbol expressions, which field sensitivity knows how to deal with.
1 parent 3fe7c67 commit fd0f92d

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--bounds-check --32 --program-only
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
byte_update

src/goto-symex/symex_dereference.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Daniel Kroening, [email protected]
1616
#include <util/byte_operators.h>
1717
#include <util/c_types.h>
1818
#include <util/exception_utils.h>
19+
#include <util/expr_util.h>
1920
#include <util/invariant.h>
2021
#include <util/pointer_offset_size.h>
2122

@@ -389,4 +390,23 @@ void goto_symext::dereference(
389390
// dereferencing may introduce new symbol_exprt
390391
// (like __CPROVER_memory)
391392
state.rename(expr, ns, goto_symex_statet::L1);
393+
394+
// dereferencing is likely to introduce new member-of-if constructs --
395+
// for example, "x->field" may have become "(x == &o1 ? o1 : o2).field"
396+
// Simplify (which converts that to (x == &o1 ? o1.field : o2.field)) before
397+
// applying field sensitivity, which can turn such field-of-symbol expressions
398+
// into atomic SSA expressions, but would have to rewrite all of 'o1'
399+
// otherwise.
400+
// make the structure of the lhs as simple as possible to avoid,
401+
// Similarly, (b ? s1 : s2).member=X results in
402+
// (b ? s1 : s2)=(b ? s1 : s2) with member:=X and then
403+
// s1=b ? ((b ? s1 : s2) with member:=X) : s1
404+
// when all we need is
405+
// s1=s1 with member:=X [and guard b]
406+
// s2=s2 with member:=X [and guard !b]
407+
do_simplify(expr);
408+
// make sure simplify has not re-introduced any dereferencing that
409+
// had previously been cleaned away
410+
INVARIANT(
411+
!has_subexpr(expr, ID_dereference), "simplify re-introduced dereferencing");
392412
}

0 commit comments

Comments
 (0)