Skip to content

Commit 32ed640

Browse files
committed
Add loop-contract symbols into symbol table during typecheck
1 parent 582aa69 commit 32ed640

File tree

3 files changed

+103
-44
lines changed

3 files changed

+103
-44
lines changed

src/linking/remove_internal_symbols.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ static void get_symbols(
4343

4444
find_symbols_sett new_symbols;
4545

46-
find_type_and_expr_symbols(symbol.type, new_symbols);
47-
find_type_and_expr_symbols(symbol.value, new_symbols);
46+
// ID of named subs of loop contracts
47+
std::vector<irep_idt> loop_contracts_subs{
48+
ID_C_spec_loop_invariant, ID_C_spec_decreases};
49+
50+
find_type_and_expr_symbols(symbol.type, new_symbols, loop_contracts_subs);
51+
find_type_and_expr_symbols(symbol.value, new_symbols, loop_contracts_subs);
4852

4953
for(const auto &s : new_symbols)
5054
working_set.push_back(&ns.lookup(s));

src/util/find_symbols.cpp

+87-36
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,22 @@ enum class symbol_kindt
2727
F_ALL
2828
};
2929

30+
/// Find identifiers with id ID_symbol of the sub expressions and the subs with
31+
/// ID in \p subs_to_find
32+
/// considering both free and bound variables, as well as any type tags.
3033
static bool find_symbols(
3134
symbol_kindt,
3235
const typet &,
3336
std::function<bool(const symbol_exprt &)>,
34-
std::unordered_set<irep_idt> &bindings);
37+
std::unordered_set<irep_idt> &bindings,
38+
const std::vector<irep_idt> &subs_to_find);
3539

3640
static bool find_symbols(
3741
symbol_kindt kind,
3842
const exprt &src,
3943
std::function<bool(const symbol_exprt &)> op,
40-
std::unordered_set<irep_idt> &bindings)
44+
std::unordered_set<irep_idt> &bindings,
45+
const std::vector<irep_idt> &subs_to_find)
4146
{
4247
if(kind == symbol_kindt::F_EXPR_FREE)
4348
{
@@ -48,10 +53,12 @@ static bool find_symbols(
4853
for(const auto &v : binding_expr.variables())
4954
new_bindings.insert(v.get_identifier());
5055

51-
if(!find_symbols(kind, binding_expr.where(), op, new_bindings))
56+
if(!find_symbols(
57+
kind, binding_expr.where(), op, new_bindings, subs_to_find))
5258
return false;
5359

54-
return find_symbols(kind, binding_expr.type(), op, bindings);
60+
return find_symbols(
61+
kind, binding_expr.type(), op, bindings, subs_to_find);
5562
}
5663
else if(src.id() == ID_let)
5764
{
@@ -60,23 +67,38 @@ static bool find_symbols(
6067
for(const auto &v : let_expr.variables())
6168
new_bindings.insert(v.get_identifier());
6269

63-
if(!find_symbols(kind, let_expr.where(), op, new_bindings))
70+
if(!find_symbols(kind, let_expr.where(), op, new_bindings, subs_to_find))
6471
return false;
6572

66-
if(!find_symbols(kind, let_expr.op1(), op, new_bindings))
73+
if(!find_symbols(kind, let_expr.op1(), op, new_bindings, subs_to_find))
6774
return false;
6875

69-
return find_symbols(kind, let_expr.type(), op, bindings);
76+
return find_symbols(kind, let_expr.type(), op, bindings, subs_to_find);
7077
}
7178
}
7279

7380
for(const auto &src_op : src.operands())
7481
{
75-
if(!find_symbols(kind, src_op, op, bindings))
82+
if(!find_symbols(kind, src_op, op, bindings, subs_to_find))
7683
return false;
7784
}
7885

79-
if(!find_symbols(kind, src.type(), op, bindings))
86+
// Go over all named subs with id in subs_to_find
87+
// and find symbols recursively.
88+
for(const auto &sub_to_find : subs_to_find)
89+
{
90+
auto sub_expr = static_cast<const exprt &>(src.find(sub_to_find));
91+
if(sub_expr.is_not_nil())
92+
{
93+
for(const auto &sub_op : sub_expr.operands())
94+
{
95+
if(!find_symbols(kind, sub_op, op, bindings, subs_to_find))
96+
return false;
97+
}
98+
}
99+
}
100+
101+
if(!find_symbols(kind, src.type(), op, bindings, subs_to_find))
80102
return false;
81103

82104
if(src.id() == ID_symbol)
@@ -95,46 +117,58 @@ static bool find_symbols(
95117
}
96118
}
97119

98-
const irept &c_sizeof_type=src.find(ID_C_c_sizeof_type);
120+
const irept &c_sizeof_type = src.find(ID_C_c_sizeof_type);
99121

100122
if(
101-
c_sizeof_type.is_not_nil() &&
102-
!find_symbols(
103-
kind, static_cast<const typet &>(c_sizeof_type), op, bindings))
123+
c_sizeof_type.is_not_nil() && !find_symbols(
124+
kind,
125+
static_cast<const typet &>(c_sizeof_type),
126+
op,
127+
bindings,
128+
subs_to_find))
104129
{
105130
return false;
106131
}
107132

108133
const irept &va_arg_type=src.find(ID_C_va_arg_type);
109134

110135
if(
111-
va_arg_type.is_not_nil() &&
112-
!find_symbols(kind, static_cast<const typet &>(va_arg_type), op, bindings))
136+
va_arg_type.is_not_nil() && !find_symbols(
137+
kind,
138+
static_cast<const typet &>(va_arg_type),
139+
op,
140+
bindings,
141+
subs_to_find))
113142
{
114143
return false;
115144
}
116145

117146
return true;
118147
}
119148

149+
/// Find identifiers with id ID_symbol of the sub expressions and the subs with
150+
/// ID in \p subs_to_find
151+
/// considering both free and bound variables, as well as any type tags.
120152
static bool find_symbols(
121153
symbol_kindt kind,
122154
const typet &src,
123155
std::function<bool(const symbol_exprt &)> op,
124-
std::unordered_set<irep_idt> &bindings)
156+
std::unordered_set<irep_idt> &bindings,
157+
const std::vector<irep_idt> &subs_to_find)
125158
{
126159
if(kind != symbol_kindt::F_TYPE_NON_PTR || src.id() != ID_pointer)
127160
{
128161
if(
129162
src.has_subtype() &&
130-
!find_symbols(kind, to_type_with_subtype(src).subtype(), op, bindings))
163+
!find_symbols(
164+
kind, to_type_with_subtype(src).subtype(), op, bindings, subs_to_find))
131165
{
132166
return false;
133167
}
134168

135169
for(const typet &subtype : to_type_with_subtypes(src).subtypes())
136170
{
137-
if(!find_symbols(kind, subtype, op, bindings))
171+
if(!find_symbols(kind, subtype, op, bindings, subs_to_find))
138172
return false;
139173
}
140174

@@ -155,26 +189,27 @@ static bool find_symbols(
155189

156190
for(const auto &c : struct_union_type.components())
157191
{
158-
if(!find_symbols(kind, c, op, bindings))
192+
if(!find_symbols(kind, c, op, bindings, subs_to_find))
159193
return false;
160194
}
161195
}
162196
else if(src.id()==ID_code)
163197
{
164198
const code_typet &code_type=to_code_type(src);
165-
if(!find_symbols(kind, code_type.return_type(), op, bindings))
199+
if(!find_symbols(kind, code_type.return_type(), op, bindings, subs_to_find))
166200
return false;
167201

168202
for(const auto &p : code_type.parameters())
169203
{
170-
if(!find_symbols(kind, p, op, bindings))
204+
if(!find_symbols(kind, p, op, bindings, subs_to_find))
171205
return false;
172206
}
173207
}
174208
else if(src.id()==ID_array)
175209
{
176210
// do the size -- the subtype is already done
177-
if(!find_symbols(kind, to_array_type(src).size(), op, bindings))
211+
if(!find_symbols(
212+
kind, to_array_type(src).size(), op, bindings, subs_to_find))
178213
return false;
179214
}
180215
else if(
@@ -204,19 +239,21 @@ static bool find_symbols(
204239
static bool find_symbols(
205240
symbol_kindt kind,
206241
const typet &type,
207-
std::function<bool(const symbol_exprt &)> op)
242+
std::function<bool(const symbol_exprt &)> op,
243+
const std::vector<irep_idt> &subs_to_find = {})
208244
{
209245
std::unordered_set<irep_idt> bindings;
210-
return find_symbols(kind, type, op, bindings);
246+
return find_symbols(kind, type, op, bindings, subs_to_find);
211247
}
212248

213249
static bool find_symbols(
214250
symbol_kindt kind,
215251
const exprt &src,
216-
std::function<bool(const symbol_exprt &)> op)
252+
std::function<bool(const symbol_exprt &)> op,
253+
const std::vector<irep_idt> &subs_to_find = {})
217254
{
218255
std::unordered_set<irep_idt> bindings;
219-
return find_symbols(kind, src, op, bindings);
256+
return find_symbols(kind, src, op, bindings, subs_to_find);
220257
}
221258

222259
void find_symbols(const exprt &src, std::set<symbol_exprt> &dest)
@@ -278,20 +315,34 @@ void find_non_pointer_type_symbols(
278315
});
279316
}
280317

281-
void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest)
318+
void find_type_and_expr_symbols(
319+
const exprt &src,
320+
find_symbols_sett &dest,
321+
const std::vector<irep_idt> &subs_to_find)
282322
{
283-
find_symbols(symbol_kindt::F_ALL, src, [&dest](const symbol_exprt &e) {
284-
dest.insert(e.get_identifier());
285-
return true;
286-
});
323+
find_symbols(
324+
symbol_kindt::F_ALL,
325+
src,
326+
[&dest](const symbol_exprt &e) {
327+
dest.insert(e.get_identifier());
328+
return true;
329+
},
330+
subs_to_find);
287331
}
288332

289-
void find_type_and_expr_symbols(const typet &src, find_symbols_sett &dest)
333+
void find_type_and_expr_symbols(
334+
const typet &src,
335+
find_symbols_sett &dest,
336+
const std::vector<irep_idt> &subs_to_find)
290337
{
291-
find_symbols(symbol_kindt::F_ALL, src, [&dest](const symbol_exprt &e) {
292-
dest.insert(e.get_identifier());
293-
return true;
294-
});
338+
find_symbols(
339+
symbol_kindt::F_ALL,
340+
src,
341+
[&dest](const symbol_exprt &e) {
342+
dest.insert(e.get_identifier());
343+
return true;
344+
},
345+
subs_to_find);
295346
}
296347

297348
void find_symbols(const exprt &src, find_symbols_sett &dest)

src/util/find_symbols.h

+10-6
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,20 @@ void find_non_pointer_type_symbols(
7979
const exprt &src,
8080
find_symbols_sett &dest);
8181

82-
/// Find identifiers of the sub expressions with id ID_symbol, considering both
83-
/// free and bound variables, as well as any type tags.
82+
/// Find identifiers with id ID_symbol of the sub expressions and the subs with
83+
/// ID in \p subs_to_find
84+
/// considering both free and bound variables, as well as any type tags.
8485
void find_type_and_expr_symbols(
8586
const typet &src,
86-
find_symbols_sett &dest);
87+
find_symbols_sett &dest,
88+
const std::vector<irep_idt> &subs_to_find = {});
8789

88-
/// Find identifiers of the sub expressions with id ID_symbol, considering both
89-
/// free and bound variables, as well as any type tags.
90+
/// Find identifiers with id ID_symbol of the sub expressions and the subs with
91+
/// ID in \p subs_to_find
92+
/// considering both free and bound variables, as well as any type tags.
9093
void find_type_and_expr_symbols(
9194
const exprt &src,
92-
find_symbols_sett &dest);
95+
find_symbols_sett &dest,
96+
const std::vector<irep_idt> &subs_to_find = {});
9397

9498
#endif // CPROVER_UTIL_FIND_SYMBOLS_H

0 commit comments

Comments
 (0)