Skip to content

Commit a7e4c18

Browse files
committed
Implement the new pointer encoding for SMT1/2 back ends
1 parent b1adf88 commit a7e4c18

File tree

2 files changed

+96
-99
lines changed

2 files changed

+96
-99
lines changed

src/solvers/smt1/smt1_conv.cpp

+51-45
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,22 @@ exprt smt1_convt::ce_value(
145145
else if(type.id()==ID_pointer)
146146
{
147147
assert(value.size()==boolbv_width(type));
148+
std::size_t object_bits=pointer_logic.get_object_width();
149+
std::size_t offset_bits=pointer_logic.get_offset_width();
148150

149151
constant_exprt result(type);
150-
result.set_value(value);
152+
result.set_value(value.substr(0, object_bits+offset_bits));
151153

152154
// add the elaborated expression as operand
153155

154156
pointer_logict::pointert p;
155-
p.object=integer2unsigned(
156-
binary2integer(
157-
value.substr(0, config.bv_encoding.object_bits), false));
157+
p.object=
158+
integer2size_t(
159+
binary2integer(value.substr(0, object_bits), false));
158160

159161
p.offset=
160162
binary2integer(
161-
value.substr(config.bv_encoding.object_bits, std::string::npos), true);
163+
value.substr(object_bits, offset_bits), true);
162164

163165
result.copy_to_operands(
164166
pointer_logic.pointer_expr(p, to_pointer_type(type)));
@@ -261,13 +263,18 @@ void smt1_convt::convert_address_of_rec(
261263
expr.id()==ID_string_constant ||
262264
expr.id()==ID_label)
263265
{
266+
std::string addr=
267+
expr.id()==ID_symbol?
268+
expr.get_string(ID_identifier)+"$address":
269+
"bv0["+std::to_string(pointer_logic.get_address_width())+"]";
270+
264271
out
272+
<< "(concat "
265273
<< "(concat"
266-
<< " bv" << pointer_logic.add_object(expr) << "["
267-
<< config.bv_encoding.object_bits << "]"
268-
<< " bv0["
269-
<< boolbv_width(result_type)-config.bv_encoding.object_bits << "]"
270-
<< ")";
274+
<< " bv" << pointer_logic.add_object(expr)
275+
<< "[" << pointer_logic.get_object_width() << "]"
276+
<< " bv0[" << pointer_logic.get_offset_width() << "]"
277+
<< ") " << addr << ")";
271278
}
272279
else if(expr.id()==ID_index)
273280
{
@@ -893,33 +900,26 @@ void smt1_convt::convert_expr(const exprt &expr, bool bool_as_bv)
893900
{
894901
assert(expr.operands().size()==1);
895902
assert(expr.op0().type().id()==ID_pointer);
896-
std::size_t op_width=boolbv_width(expr.op0().type());
897-
out << "(zero_extend[" << config.bv_encoding.object_bits << "] (extract["
898-
<< (op_width-1-config.bv_encoding.object_bits)
899-
<< ":0] ";
903+
std::size_t object_bits=pointer_logic.get_object_width();
904+
std::size_t offset_bits=pointer_logic.get_offset_width();
905+
out << "(extract["
906+
<< object_bits+offset_bits-1 << ":"
907+
<< object_bits << "] ";
900908
convert_expr(expr.op0(), true);
901-
out << "))";
902-
assert(boolbv_width(expr.type())==op_width);
909+
out << ")";
910+
DATA_INVARIANT(
911+
boolbv_width(expr.type()) == offset_bits, "offset encoding mismatch");
903912
}
904913
else if(expr.id()==ID_pointer_object)
905914
{
906915
assert(expr.operands().size()==1);
907916
assert(expr.op0().type().id()==ID_pointer);
908-
std::size_t op_width=boolbv_width(expr.op0().type());
909-
signed int ext=boolbv_width(expr.type())-config.bv_encoding.object_bits;
910-
911-
if(ext>0)
912-
out << "(zero_extend[" << ext << "] ";
913-
914-
out << "(extract["
915-
<< (op_width-1)
916-
<< ":"
917-
<< op_width-1-config.bv_encoding.object_bits << "] ";
917+
std::size_t object_bits=pointer_logic.get_object_width();
918+
out << "(extract[" << object_bits-1 << ":0] ";
918919
convert_expr(expr.op0(), true);
919920
out << ")";
920-
921-
if(ext>0)
922-
out << ")";
921+
DATA_INVARIANT(
922+
boolbv_width(expr.type()) == object_bits, "object encoding mismatch");
923923
}
924924
else if(expr.id()=="is_dynamic_object")
925925
{
@@ -931,17 +931,15 @@ void smt1_convt::convert_expr(const exprt &expr, bool bool_as_bv)
931931

932932
assert(expr.operands().size()==1);
933933
assert(expr.op0().type().id()==ID_pointer);
934-
std::size_t op_width=boolbv_width(expr.op0().type());
934+
std::size_t object_bits=pointer_logic.get_object_width();
935935

936936
// this may have to be converted
937937
from_bool_begin(type, bool_as_bv);
938938

939-
out << "(= (extract["
940-
<< (op_width-1)
941-
<< ":" << op_width-config.bv_encoding.object_bits << "] ";
939+
out << "(= (extract[" << object_bits-1 << ":0] ";
942940
convert_expr(expr.op0(), true);
943941
out << ") bv" << pointer_logic.get_invalid_object()
944-
<< "[" << config.bv_encoding.object_bits << "])";
942+
<< "[" << object_bits << "])";
945943

946944
// this may have to be converted
947945
from_bool_end(type, bool_as_bv);
@@ -1856,12 +1854,14 @@ void smt1_convt::convert_constant(
18561854
if(value==ID_NULL)
18571855
{
18581856
assert(boolbv_width(expr.type())!=0);
1859-
out << "(concat"
1857+
out << "(concat "
1858+
<< "(concat"
18601859
<< " bv" << pointer_logic.get_null_object()
1861-
<< "[" << config.bv_encoding.object_bits << "]"
1862-
<< " bv0[" << boolbv_width(expr.type())-config.bv_encoding.object_bits
1863-
<< "]"
1864-
<< ")"; // concat
1860+
<< "[" << pointer_logic.get_object_width() << "]"
1861+
<< " bv0[" << pointer_logic.get_offset_width() << "]"
1862+
<< ") "
1863+
<< "bv0[" << pointer_logic.get_address_width() << "]"
1864+
<< ")";
18651865
}
18661866
else
18671867
throw "unknown pointer constant: "+id2string(value);
@@ -1937,7 +1937,7 @@ void smt1_convt::convert_is_dynamic_object(
19371937

19381938
assert(expr.operands().size()==1);
19391939
assert(expr.op0().type().id()==ID_pointer);
1940-
std::size_t op_width=boolbv_width(expr.op0().type());
1940+
std::size_t object_bits=pointer_logic.get_object_width();
19411941

19421942
// this may have to be converted
19431943
from_bool_begin(expr.type(), bool_as_bv);
@@ -1948,24 +1948,22 @@ void smt1_convt::convert_is_dynamic_object(
19481948
{
19491949
// let is only allowed in formulas
19501950

1951-
out << "(let (?obj (extract["
1952-
<< (op_width-1)
1953-
<< ":" << op_width-config.bv_encoding.object_bits << "] ";
1951+
out << "(let (?obj (extract[" << object_bits-1 << ":0] ";
19541952
convert_expr(expr.op0(), true);
19551953
out << ")) ";
19561954

19571955
if(dynamic_objects.size()==1)
19581956
{
19591957
out << "(= bv" << dynamic_objects.front()
1960-
<< "[" << config.bv_encoding.object_bits << "] ?obj)";
1958+
<< "[" << object_bits << "] ?obj)";
19611959
}
19621960
else
19631961
{
19641962
out << "(or";
19651963

19661964
for(const auto &obj : dynamic_objects)
19671965
out << " (= bv" << obj
1968-
<< "[" << config.bv_encoding.object_bits << "] ?obj)";
1966+
<< "[" << object_bits << "] ?obj)";
19691967

19701968
out << ")"; // or
19711969
}
@@ -2847,6 +2845,14 @@ void smt1_convt::find_symbols(const exprt &expr)
28472845
convert_type(type);
28482846
out << "))" << "\n";
28492847
}
2848+
2849+
std::string address_id=id2string(identifier)+"$address";
2850+
2851+
out << ":extrafuns(("
2852+
<< convert_identifier(address_id)
2853+
<< " ";
2854+
convert_type(size_type());
2855+
out << "))\n";
28502856
}
28512857
}
28522858
else if(expr.id()==ID_array_of)

src/solvers/smt2/smt2_conv.cpp

+45-54
Original file line numberDiff line numberDiff line change
@@ -138,34 +138,28 @@ void smt2_convt::define_object_size(
138138
const exprt &expr)
139139
{
140140
assert(expr.id()==ID_object_size);
141-
const exprt &ptr = expr.op0();
142-
std::size_t size_width = boolbv_width(expr.type());
143-
std::size_t pointer_width = boolbv_width(ptr.type());
144-
std::size_t number = 0;
145-
std::size_t h=pointer_width-1;
146-
std::size_t l=pointer_width-config.bv_encoding.object_bits;
141+
const exprt &ptr=expr.op0();
142+
std::size_t size_width=boolbv_width(expr.type());
143+
std::size_t number=0;
144+
std::size_t object_bits=pointer_logic.get_object_width();
147145

148146
for(const auto &o : pointer_logic.objects)
149147
{
150-
const typet &type = ns.follow(o.type());
151-
exprt size_expr = size_of_expr(type, ns);
152-
mp_integer object_size;
148+
const typet &type=ns.follow(o.type());
149+
mp_integer object_size=pointer_offset_size(type, ns);
153150

154-
if(o.id()!=ID_symbol ||
155-
size_expr.is_nil() ||
156-
to_integer(size_expr, object_size))
151+
if(o.id()!=ID_symbol || object_size<=0)
157152
{
158153
++number;
159154
continue;
160155
}
161156

162157
out << "(assert (implies (= " <<
163-
"((_ extract " << h << " " << l << ") ";
158+
"((_ extract " << object_bits-1 << " 0) ";
164159
convert_expr(ptr);
165-
out << ") (_ bv" << number << " "
166-
<< config.bv_encoding.object_bits << "))"
167-
<< "(= " << id << " (_ bv" << object_size.to_ulong() << " "
168-
<< size_width << "))))\n";
160+
out << ") (_ bv" << number << " " << object_bits << "))" <<
161+
"(= " << id << " (_ bv" << object_size.to_ulong() << " " <<
162+
size_width << "))))\n";
169163

170164
++number;
171165
}
@@ -456,10 +450,12 @@ exprt smt2_convt::parse_rec(const irept &src, const typet &_type)
456450
to_integer(bv_expr, v);
457451

458452
// split into object and offset
459-
mp_integer pow=power(2, width-config.bv_encoding.object_bits);
453+
std::size_t object_bits=pointer_logic.get_object_width();
454+
std::size_t offset_bits=pointer_logic.get_offset_width();
455+
mp_integer pow=power(2, object_bits);
460456
pointer_logict::pointert ptr;
461-
ptr.object=integer2size_t(v/pow);
462-
ptr.offset=v%pow;
457+
ptr.object=integer2size_t(v%pow);
458+
ptr.offset=(v%power(2, object_bits+offset_bits))/pow;
463459
return pointer_logic.pointer_expr(ptr, to_pointer_type(type));
464460
}
465461
else if(type.id()==ID_struct)
@@ -487,12 +483,18 @@ void smt2_convt::convert_address_of_rec(
487483
expr.id()==ID_string_constant ||
488484
expr.id()==ID_label)
489485
{
486+
std::string addr=
487+
expr.id()==ID_symbol?
488+
expr.get_string(ID_identifier)+"$address":
489+
"(_ bv0 "+std::to_string(pointer_logic.get_address_width())+")";
490+
490491
out
491-
<< "(concat (_ bv"
492-
<< pointer_logic.add_object(expr) << " "
493-
<< config.bv_encoding.object_bits << ")"
494-
<< " (_ bv0 "
495-
<< boolbv_width(result_type)-config.bv_encoding.object_bits << "))";
492+
<< "(concat "
493+
<< "(concat "
494+
<< "(_ bv" << pointer_logic.add_object(expr)
495+
<< " " << pointer_logic.get_object_width() << ") "
496+
<< "(_ bv0 " << pointer_logic.get_offset_width() << ")) "
497+
<< addr << ")";
496498
}
497499
else if(expr.id()==ID_index)
498500
{
@@ -1312,38 +1314,32 @@ void smt2_convt::convert_expr(const exprt &expr)
13121314
{
13131315
assert(expr.operands().size()==1);
13141316
assert(expr.op0().type().id()==ID_pointer);
1315-
std::size_t offset_bits=
1316-
boolbv_width(expr.op0().type())-config.bv_encoding.object_bits;
1317-
std::size_t result_width=boolbv_width(expr.type());
1317+
std::size_t object_bits=pointer_logic.get_object_width();
1318+
std::size_t offset_bits=pointer_logic.get_offset_width();
1319+
std::size_t ext=boolbv_width(expr.type())-offset_bits;
13181320

1319-
// max extract width
1320-
if(offset_bits>result_width)
1321-
offset_bits=result_width;
1322-
1323-
// too few bits?
1324-
if(result_width>offset_bits)
1325-
out << "((_ zero_extend " << result_width-offset_bits << ") ";
1321+
if(ext>0)
1322+
out << "((_ zero_extend " << ext << ") ";
13261323

1327-
out << "((_ extract " << offset_bits-1 << " 0) ";
1324+
out << "((_ extract " << object_bits+offset_bits-1
1325+
<< " " << object_bits << ") ";
13281326
convert_expr(expr.op0());
13291327
out << ")";
13301328

1331-
if(result_width>offset_bits)
1329+
if(ext>0)
13321330
out << ")"; // zero_extend
13331331
}
13341332
else if(expr.id()==ID_pointer_object)
13351333
{
13361334
assert(expr.operands().size()==1);
13371335
assert(expr.op0().type().id()==ID_pointer);
1338-
std::size_t ext=boolbv_width(expr.type())-config.bv_encoding.object_bits;
1339-
std::size_t pointer_width=boolbv_width(expr.op0().type());
1336+
std::size_t object_bits=pointer_logic.get_object_width();
1337+
std::size_t ext=boolbv_width(expr.type())-object_bits;
13401338

13411339
if(ext>0)
13421340
out << "((_ zero_extend " << ext << ") ";
13431341

1344-
out << "((_ extract "
1345-
<< pointer_width-1 << " "
1346-
<< pointer_width-config.bv_encoding.object_bits << ") ";
1342+
out << "((_ extract " << object_bits-1 << " 0) ";
13471343
convert_expr(expr.op0());
13481344
out << ")";
13491345

@@ -1357,14 +1353,12 @@ void smt2_convt::convert_expr(const exprt &expr)
13571353
else if(expr.id()==ID_invalid_pointer)
13581354
{
13591355
assert(expr.operands().size()==1);
1356+
std::size_t object_bits=pointer_logic.get_object_width();
13601357

1361-
std::size_t pointer_width=boolbv_width(expr.op0().type());
1362-
out << "(= ((_ extract "
1363-
<< pointer_width-1 << " "
1364-
<< pointer_width-config.bv_encoding.object_bits << ") ";
1358+
out << "(= ((_ extract " << object_bits-1 << " 0) ";
13651359
convert_expr(expr.op0());
13661360
out << ") (_ bv" << pointer_logic.get_invalid_object()
1367-
<< " " << config.bv_encoding.object_bits << "))";
1361+
<< " " << object_bits << "))";
13681362
}
13691363
else if(expr.id()=="pointer_object_has_type")
13701364
{
@@ -2721,31 +2715,28 @@ void smt2_convt::convert_is_dynamic_object(const exprt &expr)
27212715
pointer_logic.get_dynamic_objects(dynamic_objects);
27222716

27232717
assert(expr.operands().size()==1);
2718+
std::size_t object_bits=pointer_logic.get_object_width();
27242719

27252720
if(dynamic_objects.empty())
27262721
out << "false";
27272722
else
27282723
{
2729-
std::size_t pointer_width=boolbv_width(expr.op0().type());
2730-
2731-
out << "(let ((?obj ((_ extract "
2732-
<< pointer_width-1 << " "
2733-
<< pointer_width-config.bv_encoding.object_bits << ") ";
2724+
out << "(let ((?obj ((_ extract " << object_bits << " 0) ";
27342725
convert_expr(expr.op0());
27352726
out << "))) ";
27362727

27372728
if(dynamic_objects.size()==1)
27382729
{
27392730
out << "(= (_ bv" << dynamic_objects.front()
2740-
<< " " << config.bv_encoding.object_bits << ") ?obj)";
2731+
<< " " << object_bits << ") ?obj)";
27412732
}
27422733
else
27432734
{
27442735
out << "(or";
27452736

27462737
for(const auto &object : dynamic_objects)
27472738
out << " (= (_ bv" << object
2748-
<< " " << config.bv_encoding.object_bits << ") ?obj)";
2739+
<< " " << object_bits << ") ?obj)";
27492740

27502741
out << ")"; // or
27512742
}

0 commit comments

Comments
 (0)