Skip to content

Commit 22f7a1a

Browse files
author
Daniel Kroening
committed
better precision of value_set on unions
1 parent d33bd22 commit 22f7a1a

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

regression/cbmc/union10/union_list.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <assert.h>
2+
3+
struct list_item
4+
{
5+
struct list_item * previous;
6+
};
7+
8+
struct List
9+
{
10+
unsigned something;
11+
struct list_item * index, end;
12+
};
13+
14+
union U
15+
{
16+
struct List my_list;
17+
};
18+
19+
int main() {
20+
union U u;
21+
22+
u.my_list.index = &( u.my_list.end );
23+
u.my_list.end.previous = u.my_list.index;
24+
struct list_item *p1 = u.my_list.index;
25+
struct list_item *p2 = p1->previous;
26+
struct list_item *p3 = p2->previous;
27+
assert(p3!=0); // should pass
28+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
union_list.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/pointer-analysis/value_set.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Daniel Kroening, [email protected]
1616

1717
#include <util/arith_tools.h>
1818
#include <util/base_type.h>
19+
#include <util/byte_operators.h>
1920
#include <util/c_types.h>
2021
#include <util/pointer_offset_size.h>
2122
#include <util/simplify_expr.h>
@@ -1755,9 +1756,23 @@ exprt value_sett::make_member(
17551756
assert(src.operands().size()==1);
17561757
return make_member(src.op0(), component_name, ns);
17571758
}
1759+
else if(src.id()==ID_byte_extract_little_endian ||
1760+
src.id()==ID_byte_extract_big_endian)
1761+
{
1762+
const typet subtype=struct_union_type.component_type(component_name);
1763+
const auto &byte_extract_expr = to_byte_extract_expr(src);
1764+
if(struct_union_type.id()==ID_union &&
1765+
subtype==byte_extract_expr.op().type() &&
1766+
byte_extract_expr.offset().is_zero())
1767+
{
1768+
// rewrite byte_extract(X, 0).member to X
1769+
// if the type of X is that of the member
1770+
return byte_extract_expr.op();
1771+
}
1772+
}
17581773

17591774
// give up
1760-
typet subtype=struct_union_type.component_type(component_name);
1775+
const typet subtype=struct_union_type.component_type(component_name);
17611776
member_exprt member_expr(src, component_name, subtype);
17621777

17631778
return member_expr;

0 commit comments

Comments
 (0)