Skip to content

Commit 7d72dd2

Browse files
Merge pull request diffblue#252 from diffblue/issue207and178
Fix write_stack to correctly complete types for index_exprt expressions
2 parents d51a65c + 6daabd2 commit 7d72dd2

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
write-stack-address-of.c
3+
--variable --structs --pointers --verify
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[func1.assertion.1\] .* func1.a == 0: Unknown$
7+
--
8+
^warning: ignoring
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
typedef unsigned short uint16;
2+
3+
struct st {
4+
uint16 data1;
5+
} str1;
6+
7+
extern struct {
8+
struct st data2;
9+
} g_sts;
10+
11+
void func1(uint16 a)
12+
{
13+
// Expect the assert to be 'Unknown' because we would expect 'a' to be TOP
14+
// here because p->data1 passed in as argument should be TOP.
15+
__CPROVER_assert(a == 0, "func1.a == 0");
16+
}
17+
18+
void func2(struct st *p)
19+
{
20+
func1(p->data1);
21+
}
22+
23+
void main(void)
24+
{
25+
const int s_map_data[] = { 2, 10, 20, 100, 110 };
26+
27+
int *p_map_x = &s_map_data[1];
28+
int *p_map_y = p_map_x + 1 ;
29+
30+
// Tests that the write_stack handles &smap_data[1]
31+
__CPROVER_assert(*p_map_y == 20, "*main.p_map_y == 20");
32+
33+
func2(&g_sts.data2);
34+
}

src/analyses/variable-sensitivity/write_stack.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ exprt write_stackt::to_expression() const
188188
}
189189
new_expr.op0()=access_expr;
190190

191+
// If neccesary, complete the type of the new access expression
192+
entry->adjust_access_type(new_expr);
193+
191194
access_expr=new_expr;
192195
}
193196
}

src/analyses/variable-sensitivity/write_stack_entry.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ exprt simple_entryt::get_access_expr() const
3535
return simple_entry;
3636
}
3737

38+
/// For a simple entry, no type adjustment is needed for the access expression
39+
void simple_entryt::adjust_access_type(exprt &expr) const
40+
{
41+
}
42+
3843
offset_entryt::offset_entryt(abstract_object_pointert offset_value):
3944
offset(offset_value)
4045
{
@@ -46,13 +51,28 @@ offset_entryt::offset_entryt(abstract_object_pointert offset_value):
4651
}
4752

4853
/// Get the expression part needed to read this stack entry. For offset entries
49-
/// this is an index expression with the index() part the offset
50-
/// \return The expression to read this part of the stack
54+
/// this is an index expression with the index() part the offset.
55+
/// It is important to note that the returned index_exprt does not have a type,
56+
/// so it will be necessary for the caller to update the type whenever the index
57+
/// expression is completed using `adjust_access_type` on the resulting exprt.
58+
/// \return The untyped expression to read this part of the stack
5159
exprt offset_entryt::get_access_expr() const
5260
{
61+
// This constructs a something that is basicallyt '(null)[offset])'
62+
// meaning that we don't know what the type is at this point, as the
63+
// array part will be filled in later.
5364
return index_exprt(exprt(), offset->to_constant());
5465
}
5566

67+
/// For an offset entry, the type of the access expression can only be
68+
/// determined once the access expression has been completed with the next
69+
/// entry on the write stack.
70+
void offset_entryt::adjust_access_type(exprt &expr) const
71+
{
72+
PRECONDITION(expr.id() == ID_index);
73+
expr.type()=expr.op0().type().subtype();
74+
}
75+
5676
/// Try to combine a new stack element with the current top of the stack. This
5777
/// will succeed if they are both offsets as we can combine these offsets into
5878
/// the sum of the offsets

src/analyses/variable-sensitivity/write_stack_entry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class write_stack_entryt
2525
public:
2626
virtual ~write_stack_entryt() = default;
2727
virtual exprt get_access_expr() const=0;
28+
virtual void adjust_access_type(exprt &expr) const = 0;
2829
virtual bool try_squash_in(
2930
std::shared_ptr<const write_stack_entryt> new_entry,
3031
const abstract_environmentt &enviroment,
@@ -36,6 +37,7 @@ class simple_entryt:public write_stack_entryt
3637
public:
3738
explicit simple_entryt(exprt expr);
3839
virtual exprt get_access_expr() const override;
40+
virtual void adjust_access_type(exprt &expr) const override;
3941
private:
4042
exprt simple_entry;
4143
};
@@ -45,6 +47,7 @@ class offset_entryt:public write_stack_entryt
4547
public:
4648
explicit offset_entryt(abstract_object_pointert offset_value);
4749
virtual exprt get_access_expr() const override;
50+
virtual void adjust_access_type(exprt &expr) const override;
4851
virtual bool try_squash_in(
4952
std::shared_ptr<const write_stack_entryt> new_entry,
5053
const abstract_environmentt &enviroment,

0 commit comments

Comments
 (0)