Skip to content

Commit bcce848

Browse files
authored
Merge pull request #3135 from tautschnig/union-arithmetic
Include pointer offset in counterexample output
2 parents d3612cc + e140d16 commit bcce848

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <assert.h>
2+
3+
typedef struct
4+
{
5+
int inta;
6+
int intb;
7+
} struct_t;
8+
9+
typedef union {
10+
int intaa;
11+
struct_t structbb;
12+
} union_struct_t;
13+
14+
int main()
15+
{
16+
union_struct_t uuu;
17+
char *ptr = (char *)&uuu.structbb.intb;
18+
int A[2];
19+
int *ip = &A[1];
20+
uuu.structbb.intb = 1;
21+
assert(0);
22+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--trace
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
ptr=\(char \*\)&uuu!0@1 \+ 4(l+)? \(.*\)$
7+
ip=A!0@1 \+ 1(l+)? \(.*\)$
8+
^VERIFICATION FAILED$
9+
--
10+
^warning: ignoring

src/solvers/flattening/pointer_logic.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening, [email protected]
1717
#include <util/invariant.h>
1818
#include <util/pointer_offset_size.h>
1919
#include <util/prefix.h>
20+
#include <util/simplify_expr.h>
2021
#include <util/std_expr.h>
2122

2223
bool pointer_logict::is_dynamic_object(const exprt &expr) const
@@ -104,29 +105,40 @@ exprt pointer_logict::pointer_expr(
104105
// https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
105106
if(subtype.id() == ID_empty)
106107
subtype = char_type();
107-
const exprt deep_object =
108+
exprt deep_object =
108109
get_subexpression_at_offset(object_expr, pointer.offset, subtype, ns);
109110
CHECK_RETURN(deep_object.is_not_nil());
111+
simplify(deep_object, ns);
110112
if(deep_object.id() != byte_extract_id())
111-
return address_of_exprt(deep_object, type);
113+
return typecast_exprt::conditional_cast(
114+
address_of_exprt(deep_object), type);
112115

113116
const byte_extract_exprt &be = to_byte_extract_expr(deep_object);
117+
const address_of_exprt base(be.op());
114118
if(be.offset().is_zero())
115-
return address_of_exprt(be.op(), type);
119+
return typecast_exprt::conditional_cast(base, type);
116120

117-
const auto subtype_bytes = pointer_offset_size(subtype, ns);
118-
CHECK_RETURN(subtype_bytes.has_value() && *subtype_bytes > 0);
119-
if(*subtype_bytes > pointer.offset)
121+
const auto object_size = pointer_offset_size(be.op().type(), ns);
122+
if(object_size.has_value() && *object_size <= 1)
120123
{
121-
return plus_exprt(
122-
address_of_exprt(be.op(), pointer_type(char_type())),
123-
from_integer(pointer.offset, index_type()));
124+
return typecast_exprt::conditional_cast(
125+
plus_exprt(base, from_integer(pointer.offset, pointer_diff_type())),
126+
type);
127+
}
128+
else if(object_size.has_value() && pointer.offset % *object_size == 0)
129+
{
130+
return typecast_exprt::conditional_cast(
131+
plus_exprt(
132+
base, from_integer(pointer.offset / *object_size, pointer_diff_type())),
133+
type);
124134
}
125135
else
126136
{
127-
return plus_exprt(
128-
address_of_exprt(be.op(), pointer_type(char_type())),
129-
from_integer(pointer.offset / *subtype_bytes, index_type()));
137+
return typecast_exprt::conditional_cast(
138+
plus_exprt(
139+
typecast_exprt(base, pointer_type(char_type())),
140+
from_integer(pointer.offset, pointer_diff_type())),
141+
type);
130142
}
131143
}
132144

0 commit comments

Comments
 (0)