Skip to content

Commit 1c7926f

Browse files
authored
Merge pull request #3974 from tautschnig/simplify-byte-extract-ext
Simplify byte_extract(constant, o, t) when sizeof(t) < sizeof(constant)
2 parents 04fac41 + 919d265 commit 1c7926f

File tree

4 files changed

+82
-4
lines changed

4 files changed

+82
-4
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <assert.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
5+
void sort_items_by_criteria(int *item, int left, int right)
6+
{
7+
int lidx = left, ridx = (left + right) / 2 + 1,
8+
lsize = (left + right) / 2 - left + 1;
9+
int tmp;
10+
11+
if(right - left < 1)
12+
return;
13+
sort_items_by_criteria(item, left, (left + right) / 2);
14+
sort_items_by_criteria(item, (left + right) / 2 + 1, right);
15+
16+
while(ridx <= right && lidx < ridx)
17+
{
18+
if(item[lidx] > item[ridx])
19+
{
20+
tmp = item[ridx];
21+
memmove(item + lidx + 1, item + lidx, lsize * sizeof(int));
22+
item[lidx] = tmp;
23+
++ridx;
24+
++lsize;
25+
}
26+
++lidx;
27+
--lsize;
28+
}
29+
}
30+
31+
int main(int argc, char *argv[])
32+
{
33+
int a[7] = {0};
34+
35+
// CBMC in some past version reported wrong results for 256, -2147221455,
36+
// -2147221455, -2147221455, 16, -2147483600, 16384
37+
a[0] = 256;
38+
a[1] = -2147221455;
39+
a[2] = -2147221455;
40+
a[3] = -2147221455;
41+
a[4] = 16;
42+
a[5] = -2147483600;
43+
a[6] = 16384;
44+
45+
sort_items_by_criteria(a, 0, 6);
46+
47+
printf("%d %d %d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
48+
49+
assert(a[0] == -2147483600);
50+
return 0;
51+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
constant.c
3+
--unwind 17
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
^Generated \d+ VCC\(s\), 0 remaining after simplification$
8+
--
9+
^warning: ignoring

regression/cbmc-library/memmove-01/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ int main(int argc, char *argv[])
3232
{
3333
int a[7];
3434

35-
//CBMC reports wrong results for 256, -2147221455, -2147221455, -2147221455, 16, -2147483600, 16384
35+
// CBMC in some past version reported wrong results for 256, -2147221455,
36+
// -2147221455, -2147221455, 16, -2147483600, 16384
3637
a[0] = 256;
3738
a[1] = -2147221455;
3839
a[2] = -2147221455;

src/util/simplify_expr.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,9 +1779,26 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr)
17791779
const auto bits=
17801780
expr2bits(expr.op(), expr.id()==ID_byte_extract_little_endian);
17811781

1782-
// exact match of length only - otherwise we might lose bits of
1783-
// flexible array members at the end of a struct
1784-
if(bits.has_value() && mp_integer(bits->size()) == *el_size + *offset * 8)
1782+
// make sure we don't lose bits with structs containing flexible array members
1783+
const bool struct_has_flexible_array_member = has_subtype(
1784+
expr.type(),
1785+
[&](const typet &type) {
1786+
if(type.id() != ID_struct && type.id() != ID_struct_tag)
1787+
return false;
1788+
1789+
const struct_typet &st = to_struct_type(ns.follow(type));
1790+
const auto &comps = st.components();
1791+
if(comps.empty() || comps.back().type().id() != ID_array)
1792+
return false;
1793+
1794+
const auto size =
1795+
numeric_cast<mp_integer>(to_array_type(comps.back().type()).size());
1796+
return !size.has_value() || *size <= 1;
1797+
},
1798+
ns);
1799+
if(
1800+
bits.has_value() && mp_integer(bits->size()) >= *el_size + *offset * 8 &&
1801+
!struct_has_flexible_array_member)
17851802
{
17861803
std::string bits_cut = std::string(
17871804
bits.value(),

0 commit comments

Comments
 (0)