Skip to content

Commit 3247fdd

Browse files
committed
replace_symbolt: Check type consistency
1 parent 5a1518b commit 3247fdd

File tree

6 files changed

+104
-29
lines changed

6 files changed

+104
-29
lines changed

src/goto-instrument/concurrency.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ void concurrency_instrumentationt::instrument(exprt &expr)
8080

8181
find_symbols(expr, symbols);
8282

83-
replace_symbolt replace_symbol;
83+
const namespacet ns(symbol_table);
84+
replace_symbolt replace_symbol(ns);
8485

8586
for(std::set<exprt>::const_iterator
8687
s_it=symbols.begin();

src/goto-programs/instrument_preconditions.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ replace_symbolt actuals_replace_map(
7171
const auto &parameters=code_type.parameters();
7272
const auto &arguments=call.arguments();
7373

74-
replace_symbolt result;
74+
replace_symbolt result(ns);
7575
std::size_t count=0;
7676
for(const auto &p : parameters)
7777
{

src/solvers/flattening/flatten_byte_operators.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Author: Daniel Kroening, [email protected]
1515
#include <util/pointer_offset_size.h>
1616
#include <util/replace_symbol.h>
1717
#include <util/simplify_expr.h>
18+
#include <util/symbol.h>
19+
#include <util/symbol_table.h>
1820

1921
#include "flatten_byte_extract_exceptions.h"
2022

@@ -72,13 +74,20 @@ static exprt unpack_rec(
7274
// all array members will have the same structure; do this just
7375
// once and then replace the dummy symbol by a suitable index
7476
// expression in the loop below
75-
symbol_exprt dummy(ID_C_incomplete, subtype);
77+
symbolt dummy_sym;
78+
dummy_sym.name = ID_C_incomplete;
79+
dummy_sym.type = subtype;
80+
const symbol_exprt dummy = dummy_sym.symbol_expr();
81+
symbol_tablet st;
82+
st.add(dummy_sym);
83+
namespacet dummy_ns(st);
84+
7685
exprt sub=unpack_rec(dummy, little_endian, max_bytes, ns, true);
7786

7887
for(mp_integer i=0; i<num_elements; ++i)
7988
{
8089
index_exprt index(src, from_integer(i, index_type()));
81-
replace_symbolt replace;
90+
replace_symbolt replace(dummy_ns);
8291
replace.insert(ID_C_incomplete, index);
8392

8493
for(const auto &op : sub.operands())

src/util/replace_symbol.cpp

+50-4
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,54 @@ Author: Daniel Kroening, [email protected]
88

99
#include "replace_symbol.h"
1010

11+
#include "base_type.h"
12+
#include "invariant.h"
13+
#include "namespace.h"
1114
#include "std_types.h"
1215
#include "std_expr.h"
16+
#include "symbol.h"
1317

14-
replace_symbolt::replace_symbolt()
18+
replace_symbolt::~replace_symbolt()
1519
{
1620
}
1721

18-
replace_symbolt::~replace_symbolt()
22+
replace_symbolt &replace_symbolt::operator=(const replace_symbolt &other)
23+
{
24+
PRECONDITION(&ns.get_symbol_table() == &other.ns.get_symbol_table());
25+
26+
expr_map = other.expr_map;
27+
type_map = other.type_map;
28+
29+
return *this;
30+
}
31+
32+
void replace_symbolt::insert(
33+
const irep_idt &identifier,
34+
const exprt &new_expr)
1935
{
36+
const symbolt &symbol = ns.lookup(identifier);
37+
PRECONDITION(!symbol.is_type);
38+
PRECONDITION(base_type_eq(ns.lookup(identifier).type, new_expr.type(), ns));
39+
40+
expr_map.emplace(identifier, new_expr);
2041
}
2142

2243
void replace_symbolt::insert(
2344
const symbol_exprt &old_expr,
2445
const exprt &new_expr)
2546
{
26-
expr_map.insert(std::pair<irep_idt, exprt>(
27-
old_expr.get_identifier(), new_expr));
47+
insert(old_expr.get_identifier(), new_expr);
48+
}
49+
50+
void replace_symbolt::insert(
51+
const irep_idt &identifier,
52+
const typet &new_type)
53+
{
54+
const symbolt &symbol = ns.lookup(identifier);
55+
PRECONDITION(symbol.is_type);
56+
PRECONDITION(base_type_eq(ns.lookup(identifier).type, new_type, ns));
57+
58+
type_map.emplace(identifier, new_type);
2859
}
2960

3061
bool replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
@@ -34,6 +65,9 @@ bool replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
3465
if(it == expr_map.end())
3566
return true;
3667

68+
DATA_INVARIANT(
69+
base_type_eq(s.type(), it->second.type(), ns),
70+
"type of symbol to be replaced should match");
3771
static_cast<exprt &>(s) = it->second;
3872

3973
return false;
@@ -288,6 +322,18 @@ void unchecked_replace_symbolt::insert(
288322
type_map.emplace(identifier, new_type);
289323
}
290324

325+
bool unchecked_replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
326+
{
327+
expr_mapt::const_iterator it = expr_map.find(s.get_identifier());
328+
329+
if(it == expr_map.end())
330+
return true;
331+
332+
static_cast<exprt &>(s) = it->second;
333+
334+
return false;
335+
}
336+
291337
bool address_of_aware_replace_symbolt::replace(exprt &dest) const
292338
{
293339
const exprt &const_dest(dest);

src/util/replace_symbol.h

+24-17
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,25 @@ Author: Daniel Kroening, [email protected]
1515
// false: replaced something
1616
//
1717

18+
#include <unordered_map>
19+
1820
#include "expr.h"
21+
#include "namespace.h"
22+
#include "symbol_table.h"
1923

20-
#include <unordered_map>
24+
class symbol_exprt;
2125

2226
/// Replace expression or type symbols by an expression or type, respectively.
27+
/// The resolved type of the symbol must match the type of the replacement.
2328
class replace_symbolt
2429
{
2530
public:
2631
typedef std::unordered_map<irep_idt, exprt> expr_mapt;
2732
typedef std::unordered_map<irep_idt, typet> type_mapt;
2833

29-
void insert(const irep_idt &identifier,
30-
const exprt &expr)
31-
{
32-
expr_map.insert(std::pair<irep_idt, exprt>(identifier, expr));
33-
}
34-
35-
void insert(const class symbol_exprt &old_expr,
36-
const exprt &new_expr);
37-
38-
void insert(const irep_idt &identifier,
39-
const typet &type)
40-
{
41-
type_map.insert(std::pair<irep_idt, typet>(identifier, type));
42-
}
43-
34+
void insert(const irep_idt &identifier, const exprt &new_expr);
35+
void insert(const symbol_exprt &old_expr, const exprt &new_expr);
36+
void insert(const irep_idt &identifier, const typet &new_type);
4437

4538
virtual bool replace(exprt &dest) const;
4639
virtual bool replace(typet &dest) const;
@@ -77,7 +70,11 @@ class replace_symbolt
7770
type_map.find(id) != type_map.end();
7871
}
7972

80-
replace_symbolt();
73+
explicit replace_symbolt(const namespacet &ns)
74+
: ns(ns)
75+
{
76+
}
77+
8178
virtual ~replace_symbolt();
8279

8380
const expr_mapt &get_expr_map() const
@@ -90,7 +87,10 @@ class replace_symbolt
9087
return expr_map;
9188
}
9289

90+
replace_symbolt &operator=(const replace_symbolt &other);
91+
9392
protected:
93+
const namespacet &ns;
9494
expr_mapt expr_map;
9595
type_mapt type_map;
9696

@@ -104,6 +104,7 @@ class unchecked_replace_symbolt : public replace_symbolt
104104
{
105105
public:
106106
unchecked_replace_symbolt()
107+
: replace_symbolt(dummy_ns), dummy_ns(symbol_table)
107108
{
108109
}
109110

@@ -112,6 +113,12 @@ class unchecked_replace_symbolt : public replace_symbolt
112113
void insert(const irep_idt &identifier, const exprt &new_expr);
113114
void insert(const symbol_exprt &old_expr, const exprt &new_expr);
114115
void insert(const irep_idt &identifier, const typet &new_type);
116+
117+
private:
118+
const symbol_tablet symbol_table;
119+
const namespacet dummy_ns;
120+
121+
bool replace_symbol_expr(symbol_exprt &dest) const override;
115122
};
116123

117124
/// Replace symbols with constants while maintaining syntactically valid

unit/util/replace_symbol.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,19 @@
1313

1414
TEST_CASE("Replace all symbols in expression", "[core][util][replace_symbol]")
1515
{
16-
symbol_exprt s1("a", typet("some_type"));
17-
symbol_exprt s2("b", typet("some_type"));
16+
symbol_tablet symbol_table;
17+
18+
symbolt sym_a;
19+
sym_a.name = "a";
20+
sym_a.type = typet("some_type");
21+
symbol_exprt s1 = sym_a.symbol_expr();
22+
symbol_table.add(sym_a);
23+
24+
symbolt sym_b;
25+
sym_b.name = "b";
26+
sym_b.type = typet("some_type");
27+
symbol_exprt s2 = sym_b.symbol_expr();
28+
symbol_table.add(sym_b);
1829

1930
exprt binary("binary", typet("some_type"));
2031
binary.copy_to_operands(s1);
@@ -23,9 +34,10 @@ TEST_CASE("Replace all symbols in expression", "[core][util][replace_symbol]")
2334
array_typet array_type(typet("sub-type"), s1);
2435
REQUIRE(array_type.size() == s1);
2536

26-
exprt other_expr("other");
37+
exprt other_expr("other", typet("some_type"));
2738

28-
unchecked_replace_symbolt r;
39+
namespacet ns(symbol_table);
40+
replace_symbolt r(ns);
2941
REQUIRE(r.empty());
3042
r.insert("a", other_expr);
3143
REQUIRE(r.replaces_symbol("a"));

0 commit comments

Comments
 (0)