Skip to content

Commit 43cc18d

Browse files
committed
Use a specialised endianness map for flattening
The bit width of flattened expressions need not coincide with the size of data types at source code level. Thus the mapping needs to be adjusted.
1 parent 3e2ab6f commit 43cc18d

File tree

8 files changed

+101
-17
lines changed

8 files changed

+101
-17
lines changed

src/solvers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ SRC = $(BOOLEFORCE_SRC) \
127127
flattening/boolbv_vector.cpp \
128128
flattening/boolbv_width.cpp \
129129
flattening/boolbv_with.cpp \
130+
flattening/bv_endianness_map.cpp \
130131
flattening/bv_minimize.cpp \
131132
flattening/bv_pointers.cpp \
132133
flattening/bv_utils.cpp \

src/solvers/flattening/boolbv_byte_extract.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ Author: Daniel Kroening, [email protected]
1313
#include <util/arith_tools.h>
1414
#include <util/std_expr.h>
1515
#include <util/byte_operators.h>
16-
#include <util/endianness_map.h>
1716

17+
#include "bv_endianness_map.h"
1818
#include "flatten_byte_operators.h"
1919

20-
bvt map_bv(const endianness_mapt &map, const bvt &src)
20+
bvt map_bv(const bv_endianness_mapt &map, const bvt &src)
2121
{
2222
assert(map.number_of_bits()==src.size());
2323

@@ -84,11 +84,11 @@ bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr)
8484

8585
// first do op0
8686

87-
endianness_mapt op_map(op.type(), little_endian, ns);
87+
bv_endianness_mapt op_map(op.type(), little_endian, ns, boolbv_width);
8888
const bvt op_bv=map_bv(op_map, convert_bv(op));
8989

9090
// do result
91-
endianness_mapt result_map(expr.type(), little_endian, ns);
91+
bv_endianness_mapt result_map(expr.type(), little_endian, ns, boolbv_width);
9292
bvt bv;
9393
bv.resize(width);
9494

src/solvers/flattening/boolbv_byte_update.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ Author: Daniel Kroening, [email protected]
1313

1414
#include <util/arith_tools.h>
1515
#include <util/byte_operators.h>
16-
#include <util/endianness_map.h>
16+
17+
#include "bv_endianness_map.h"
1718

1819
bvt boolbvt::convert_byte_update(const byte_update_exprt &expr)
1920
{
@@ -63,8 +64,8 @@ bvt boolbvt::convert_byte_update(const byte_update_exprt &expr)
6364
}
6465
else
6566
{
66-
endianness_mapt map_op(op.type(), false, ns);
67-
endianness_mapt map_value(value.type(), false, ns);
67+
bv_endianness_mapt map_op(op.type(), false, ns, boolbv_width);
68+
bv_endianness_mapt map_value(value.type(), false, ns, boolbv_width);
6869

6970
std::size_t offset_i=integer2unsigned(offset);
7071

@@ -93,8 +94,8 @@ bvt boolbvt::convert_byte_update(const byte_update_exprt &expr)
9394
equality.rhs()=from_integer(offset/byte_width, offset_expr.type());
9495
literalt equal=convert(equality);
9596

96-
endianness_mapt map_op(op.type(), little_endian, ns);
97-
endianness_mapt map_value(value.type(), little_endian, ns);
97+
bv_endianness_mapt map_op(op.type(), little_endian, ns, boolbv_width);
98+
bv_endianness_mapt map_value(value.type(), little_endian, ns, boolbv_width);
9899

99100
for(std::size_t bit=0; bit<update_width; bit++)
100101
if(offset+bit<bv.size())

src/solvers/flattening/boolbv_union.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/arith_tools.h>
1212
#include <util/config.h>
13-
#include <util/endianness_map.h>
13+
14+
#include "bv_endianness_map.h"
1415

1516
bvt boolbvt::convert_union(const union_exprt &expr)
1617
{
@@ -41,8 +42,8 @@ bvt boolbvt::convert_union(const union_exprt &expr)
4142
assert(
4243
config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_BIG_ENDIAN);
4344

44-
endianness_mapt map_u(expr.type(), false, ns);
45-
endianness_mapt map_op(expr.op0().type(), false, ns);
45+
bv_endianness_mapt map_u(expr.type(), false, ns, boolbv_width);
46+
bv_endianness_mapt map_op(expr.op0().type(), false, ns, boolbv_width);
4647

4748
for(std::size_t i=0; i<op_bv.size(); i++)
4849
bv[map_u.map_bit(i)]=op_bv[map_op.map_bit(i)];

src/solvers/flattening/boolbv_with.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ Author: Daniel Kroening, [email protected]
1212
#include <util/std_expr.h>
1313
#include <util/arith_tools.h>
1414
#include <util/base_type.h>
15-
#include <util/endianness_map.h>
1615
#include <util/config.h>
1716

17+
#include "bv_endianness_map.h"
18+
1819
bvt boolbvt::convert_with(const exprt &expr)
1920
{
2021
if(expr.operands().size()<3)
@@ -286,8 +287,8 @@ void boolbvt::convert_with_union(
286287
assert(
287288
config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_BIG_ENDIAN);
288289

289-
endianness_mapt map_u(type, false, ns);
290-
endianness_mapt map_op2(op2.type(), false, ns);
290+
bv_endianness_mapt map_u(type, false, ns, boolbv_width);
291+
bv_endianness_mapt map_op2(op2.type(), false, ns, boolbv_width);
291292

292293
for(std::size_t i=0; i<op2_bv.size(); i++)
293294
next_bv[map_u.map_bit(i)]=op2_bv[map_op2.map_bit(i)];
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#include "bv_endianness_map.h"
10+
11+
#include <util/arith_tools.h>
12+
#include <util/c_types.h>
13+
14+
#include "boolbv_width.h"
15+
16+
void bv_endianness_mapt::build_little_endian(const typet &src)
17+
{
18+
const std::size_t width = boolbv_width(src);
19+
20+
if(width == 0)
21+
return;
22+
23+
const std::size_t new_size = map.size() + width;
24+
map.reserve(new_size);
25+
26+
for(std::size_t i = map.size(); i < new_size; ++i)
27+
map.push_back(i);
28+
}
29+
30+
void bv_endianness_mapt::build_big_endian(const typet &src)
31+
{
32+
if(src.id() == ID_pointer)
33+
build_little_endian(type);
34+
else
35+
endianness_mapt::build_big_endian(src);
36+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_SOLVERS_FLATTENING_BV_ENDIANNESS_MAP_H
10+
#define CPROVER_SOLVERS_FLATTENING_BV_ENDIANNESS_MAP_H
11+
12+
#include <util/endianness_map.h>
13+
14+
class boolbv_widtht;
15+
16+
/// Map bytes according to the configured endianness. The key difference to
17+
/// endianness_mapt is that bv_endianness_mapt is aware of the bit-level
18+
/// encoding of types, which need not co-incide with the bit layout at
19+
/// source-code level.
20+
class bv_endianness_mapt : public endianness_mapt
21+
{
22+
public:
23+
bv_endianness_mapt(
24+
const typet &type,
25+
bool little_endian,
26+
const namespacet &_ns,
27+
boolbv_widtht &_boolbv_width)
28+
: endianness_mapt(_ns), boolbv_width(_boolbv_width)
29+
{
30+
build(type, little_endian);
31+
}
32+
33+
protected:
34+
boolbv_widtht &boolbv_width;
35+
36+
virtual void build_little_endian(const typet &type) override;
37+
virtual void build_big_endian(const typet &type) override;
38+
};
39+
40+
#endif // CPROVER_SOLVERS_FLATTENING_BV_ENDIANNESS_MAP_H

src/util/endianness_map.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class endianness_mapt
3737
build(type, little_endian);
3838
}
3939

40+
explicit endianness_mapt(const namespacet &_ns) : ns(_ns)
41+
{
42+
}
43+
4044
size_t map_bit(size_t bit) const
4145
{
4246
assert(bit<map.size());
@@ -58,8 +62,8 @@ class endianness_mapt
5862
const namespacet &ns;
5963
std::vector<size_t> map; // bit-nr to bit-nr
6064

61-
void build_little_endian(const typet &type);
62-
void build_big_endian(const typet &type);
65+
virtual void build_little_endian(const typet &type);
66+
virtual void build_big_endian(const typet &type);
6367
};
6468

6569
inline std::ostream &operator<<(

0 commit comments

Comments
 (0)