Skip to content

Commit 4c37fd6

Browse files
committed
Fix and optimize byte_extract lowering
1) Do not construct elements that would never be used. Handling of arrays was broken before and mis-optimised for large arrays. 2) lower_byte_operators must not use bit-level operators on pointers 3) Ensure that lowering of unions and vectors is performed properly as well. 4) byte_extract lowering over Java strings
1 parent f0f5fbb commit 4c37fd6

File tree

4 files changed

+415
-107
lines changed

4 files changed

+415
-107
lines changed

regression/cbmc/union10/main.c

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
typedef struct
2+
{
3+
union {
4+
int access[256];
5+
};
6+
} S1;
7+
8+
typedef struct
9+
{
10+
int c;
11+
} S2;
12+
13+
static S1 (* const l[1]) = {((S1 *) ((0x50000000UL) + 0x00000) )};
14+
15+
void main()
16+
{
17+
__CPROVER_allocated_memory(0x50000000UL, sizeof(S1));
18+
l[0]->access[0] = 0;
19+
__CPROVER_assert(l[0]->access[0] == 0, "holds");
20+
__CPROVER_assert(l[0]->access[1] == 0, "should fail");
21+
__CPROVER_allocated_memory(0x40000000UL + 0x40000, sizeof(S2));
22+
((S2 *) ((0x40000000UL) + 0x40000))->c = 0x0707;
23+
}

regression/cbmc/union10/test.desc

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--pointer-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[main\.assertion\.2\] should fail: FAILURE$
7+
^\*\* 1 of 14 failed
8+
^VERIFICATION FAILED$
9+
--
10+
^warning: ignoring
11+
--
12+
Despite the large array inside the union, the test should complete within 10
13+
seconds. Simplify extractbits(concatenation(...)) is essential to make this
14+
possible.

src/solvers/flattening/boolbv_member.cpp

+37-54
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Author: Daniel Kroening, [email protected]
1212
#include <util/byte_operators.h>
1313
#include <util/arith_tools.h>
1414
#include <util/c_types.h>
15+
#include <util/invariant.h>
1516

1617
bvt boolbvt::convert_member(const member_exprt &expr)
1718
{
@@ -20,67 +21,49 @@ bvt boolbvt::convert_member(const member_exprt &expr)
2021

2122
const bvt &struct_bv=convert_bv(struct_op);
2223

23-
if(struct_op_type.id()==ID_union)
24-
{
25-
return convert_bv(
26-
byte_extract_exprt(byte_extract_id(),
27-
struct_op,
28-
from_integer(0, index_type()),
29-
expr.type()));
30-
}
31-
else if(struct_op_type.id()==ID_struct)
32-
{
33-
const irep_idt &component_name=expr.get_component_name();
34-
const struct_typet::componentst &components=
35-
to_struct_type(struct_op_type).components();
24+
const irep_idt &component_name = expr.get_component_name();
25+
const struct_union_typet::componentst &components =
26+
to_struct_union_type(struct_op_type).components();
3627

37-
std::size_t offset=0;
28+
std::size_t offset = 0;
3829

39-
for(struct_typet::componentst::const_iterator
40-
it=components.begin();
41-
it!=components.end();
42-
it++)
43-
{
44-
const typet &subtype=it->type();
45-
std::size_t sub_width=boolbv_width(subtype);
30+
for(struct_union_typet::componentst::const_iterator it = components.begin();
31+
it != components.end();
32+
++it)
33+
{
34+
const typet &subtype = it->type();
35+
const std::size_t sub_width = boolbv_width(subtype);
4636

47-
if(it->get_name()==component_name)
37+
if(it->get_name() == component_name)
38+
{
39+
if(!base_type_eq(subtype, expr.type(), ns))
4840
{
49-
if(!base_type_eq(subtype, expr.type(), ns))
50-
{
51-
#if 0
52-
std::cout << "DEBUG " << expr.pretty() << "\n";
53-
#endif
54-
55-
error().source_location=expr.find_source_location();
56-
error() << "member: component type does not match: "
57-
<< subtype.pretty() << " vs. "
58-
<< expr.type().pretty() << eom;
59-
throw 0;
60-
}
61-
62-
bvt bv;
63-
bv.resize(sub_width);
64-
assert(offset+sub_width<=struct_bv.size());
65-
66-
for(std::size_t i=0; i<sub_width; i++)
67-
bv[i]=struct_bv[offset+i];
68-
69-
return bv;
41+
#if 0
42+
std::cout << "DEBUG " << expr.pretty() << "\n";
43+
#endif
44+
45+
error().source_location = expr.find_source_location();
46+
error() << "member: component type does not match: " << subtype.pretty()
47+
<< " vs. " << expr.type().pretty() << eom;
48+
throw 0;
7049
}
7150

72-
offset+=sub_width;
51+
bvt bv;
52+
bv.resize(sub_width);
53+
DATA_INVARIANT(
54+
offset + sub_width <= struct_bv.size(), "member access outside struct");
55+
56+
for(std::size_t i = 0; i < sub_width; i++)
57+
bv[i] = struct_bv[offset + i];
58+
59+
return bv;
7360
}
7461

75-
error().source_location=expr.find_source_location();
76-
error() << "component " << component_name
77-
<< " not found in structure" << eom;
78-
throw 0;
79-
}
80-
else
81-
{
82-
error().source_location=expr.find_source_location();
83-
error() << "member takes struct or union operand" << eom;
84-
throw 0;
62+
if(struct_op_type.id() == ID_struct)
63+
offset += sub_width;
8564
}
65+
66+
error().source_location = expr.find_source_location();
67+
error() << "component " << component_name << " not found in structure" << eom;
68+
throw 0;
8669
}

0 commit comments

Comments
 (0)