@@ -131,44 +131,41 @@ void local_value_set_analysist::transform_function_stub(
131
131
const symbolt &function_symbol=ns.lookup (fname);
132
132
const code_function_callt &fcall=to_code_function_call (l_call->code );
133
133
134
- std::shared_ptr<lvsaa_single_external_set_summaryt> call_summary =
135
- summarydb.at (fname);
134
+ const auto &assignments=summarydb.at (fname)->field_assignments ;
136
135
137
136
// The summary gives a list of inclusions, in the form symbol1 <- symbol2,
138
137
// indicating that values reachable before the call from symbol2
139
- // may now be reachable from symbol1. The assignments are simeltaneous .
138
+ // may now be reachable from symbol1. The assignments are simultaneous .
140
139
// Thus start by reading all RHS values, before any changes are made:
141
140
142
141
auto &valuesets=static_cast <domaint&>(state).value_set ;
143
142
std::map<exprt, local_value_sett::object_mapt> pre_call_rhs_value_sets;
144
- const std::string external_objects_basename_prefix =" external_objects" ;
143
+ const std::string per_field_evs_prefix =" external_objects" ;
145
144
146
145
std::set<std::pair<std::string, std::string> > lhs_written;
147
146
148
- for (const auto &assignment : call_summary-> field_assignments )
147
+ for (const auto &assignment : assignments )
149
148
{
150
149
++nstub_assignments;
150
+ const auto &lhs_fieldname=assignment.first ;
151
151
const auto &rhs_expr=assignment.second ;
152
152
if (pre_call_rhs_value_sets.count (rhs_expr))
153
153
continue ;
154
154
auto &rhs_map=pre_call_rhs_value_sets[rhs_expr];
155
- if (assignment. second .id ()==ID_external_value_set)
155
+ if (rhs_expr .id ()==ID_external_value_set)
156
156
{
157
- auto &evse=to_external_value_set (assignment.second );
157
+ const auto &evse=to_external_value_set (rhs_expr);
158
+ const std::string &evse_label=
159
+ id2string (to_constant_expr (evse.label ()).get_value ());
160
+
158
161
// Differentiate external-set entries that only contain
159
162
// their initialiser from ones that have been written:
160
163
if (!evse.is_initializer ())
161
- {
162
- lhs_written.insert ({
163
- assignment.first .base_name ,
164
- assignment.first .field_name });
165
- }
166
- if (has_prefix (
167
- id2string (to_constant_expr (evse.label ()).get_value ()),
168
- " external_objects" ))
164
+ lhs_written.insert ({lhs_fieldname.base_name , lhs_fieldname.field_name });
165
+
166
+ if (has_prefix (evse_label, per_field_evs_prefix))
169
167
{
170
168
std::vector<local_value_sett::entryt*> rhs_entries;
171
- const auto &evse=to_external_value_set (assignment.second );
172
169
PRECONDITION (!evse.access_path_entries ().empty ());
173
170
const auto &apback=evse.access_path_entries ().back ();
174
171
if (!evse.is_initializer ())
@@ -181,20 +178,21 @@ void local_value_set_analysist::transform_function_stub(
181
178
}
182
179
183
180
for (const auto &rhs_entry : rhs_entries)
181
+ {
184
182
valuesets.make_union_adjusting_evs_types (
185
183
rhs_map,
186
184
rhs_entry->object_map ,
187
185
evse.type ());
186
+ }
188
187
// Also add the external set itself,
189
188
// representing the possibility that the read
190
189
// comes from outside *this* function as well:
191
190
valuesets.insert (rhs_map, evse);
192
191
}
193
192
else
194
193
{
195
- // This should be an external value set assigned
196
- // to initialise some global or parameter.
197
- assert (evse.access_path_entries ().empty ());
194
+ // This should be an external value set of type ROOT_OBJECT.
195
+ PRECONDITION (evse.access_path_entries ().empty ());
198
196
const symbolt &inflow_symbol=
199
197
ns.lookup (to_constant_expr (evse.label ()).get_value ());
200
198
exprt inflow_expr;
@@ -224,7 +222,7 @@ void local_value_set_analysist::transform_function_stub(
224
222
<< to_constant_expr (evse.label ()).get_value ()
225
223
<< eom;
226
224
}
227
- assert (paramidx!=(size_t )-1 && " Unknown parameter symbol?" );
225
+ INVARIANT (paramidx!=(size_t )-1 , " Unknown parameter symbol?" );
228
226
inflow_expr=fcall.arguments ()[paramidx];
229
227
}
230
228
pointer_typet expect_type=pointer_type (evse.type ());
@@ -236,49 +234,48 @@ void local_value_set_analysist::transform_function_stub(
236
234
else
237
235
{
238
236
// Ordinary value set member; just add to the RHS map.
239
- valuesets.insert (rhs_map, assignment.second );
240
- lhs_written.insert ({
241
- assignment.first .base_name ,
242
- assignment.first .field_name });
237
+ valuesets.insert (rhs_map, rhs_expr);
238
+ lhs_written.insert ({lhs_fieldname.base_name , lhs_fieldname.field_name });
243
239
}
244
240
}
245
241
246
242
// OK, read all the RHS sets, now assign to the LHS symbols:
247
243
248
- for (const auto &assignment : call_summary-> field_assignments )
244
+ for (const auto &assignment : assignments )
249
245
{
246
+ const auto &lhs_fieldname=assignment.first ;
250
247
const auto &rhs_values=pre_call_rhs_value_sets.at (assignment.second );
251
248
252
- if (has_prefix (assignment. first . base_name , external_objects_basename_prefix ))
249
+ if (has_prefix (lhs_fieldname. base_name , per_field_evs_prefix ))
253
250
{
254
251
std::vector<local_value_sett::entryt*> lhs_entries;
255
252
const auto find_pair=std::make_pair (
256
- assignment. first .base_name ,
257
- assignment. first .field_name );
253
+ lhs_fieldname .base_name ,
254
+ lhs_fieldname .field_name );
258
255
if (lhs_written.count (find_pair))
259
256
get_all_field_value_sets (
260
- assignment. first .field_name ,
261
- assignment. first .declared_on_type ,
257
+ lhs_fieldname .field_name ,
258
+ lhs_fieldname .declared_on_type ,
262
259
valuesets,
263
260
lhs_entries);
264
261
// Also write to the external value set itself:
265
262
local_value_sett::entryt evse_entry (
266
- assignment. first .base_name ,
267
- assignment. first .field_name ,
268
- assignment. first .declared_on_type );
269
- std::string objkey=assignment. first . base_name +assignment. first .field_name ;
263
+ lhs_fieldname .base_name ,
264
+ lhs_fieldname .field_name ,
265
+ lhs_fieldname .declared_on_type );
266
+ std::string objkey=lhs_fieldname. base_name +lhs_fieldname .field_name ;
270
267
auto insertit=valuesets.values .insert (std::make_pair (objkey, evse_entry));
271
268
lhs_entries.push_back (&insertit.first ->second );
272
269
for (auto lhs_entry : lhs_entries)
273
270
valuesets.make_union (lhs_entry->object_map , rhs_values);
274
271
}
275
- else if (has_prefix (assignment. first .base_name , prefix_dynamic_object))
272
+ else if (has_prefix (lhs_fieldname .base_name , prefix_dynamic_object))
276
273
{
277
- std::string objkey=assignment. first . base_name +assignment. first .field_name ;
274
+ std::string objkey=lhs_fieldname. base_name +lhs_fieldname .field_name ;
278
275
local_value_sett::entryt dynobj_entry_name (
279
- assignment. first .base_name ,
280
- assignment. first .field_name ,
281
- assignment. first .declared_on_type );
276
+ lhs_fieldname .base_name ,
277
+ lhs_fieldname .field_name ,
278
+ lhs_fieldname .declared_on_type );
282
279
auto insertit=
283
280
valuesets.values .insert (std::make_pair (objkey, dynobj_entry_name));
284
281
valuesets.make_union (insertit.first ->second .object_map , rhs_values);
@@ -287,12 +284,14 @@ void local_value_set_analysist::transform_function_stub(
287
284
{
288
285
// The only other kind of symbols mentioned
289
286
// in summary LHS are global variables.
290
- assert (assignment.first .field_name ==" " );
291
- const auto &global_sym=ns.lookup (assignment.first .base_name );
287
+ INVARIANT (
288
+ lhs_fieldname.field_name ==" " ,
289
+ " unexpected lhs entry in call summary assignments" );
290
+ const auto &global_sym=ns.lookup (lhs_fieldname.base_name );
292
291
local_value_sett::entryt global_entry_name (
293
- assignment. first .base_name ,
292
+ lhs_fieldname .base_name ,
294
293
" " ,
295
- assignment. first .declared_on_type );
294
+ lhs_fieldname .declared_on_type );
296
295
auto &global_entry=
297
296
valuesets.get_entry (global_entry_name, global_sym.type , ns);
298
297
valuesets.make_union (global_entry.object_map , rhs_values);
0 commit comments