@@ -126,7 +126,7 @@ void goto_symext::rewrite_quantifiers(exprt &expr, statet &state)
126
126
127
127
void goto_symext::initialize_entry_point (
128
128
statet &state,
129
- const goto_functionst &goto_functions ,
129
+ const get_goto_functiont &get_goto_function ,
130
130
const goto_programt::const_targett pc,
131
131
const goto_programt::const_targett limit)
132
132
{
@@ -137,23 +137,19 @@ void goto_symext::initialize_entry_point(
137
137
state.top ().calling_location .pc =state.top ().end_of_function ;
138
138
state.symex_target =⌖
139
139
state.dirty =util_make_unique<incremental_dirtyt>();
140
- if (!pc->function .empty ())
141
- {
142
- state.dirty ->populate_dirty_for_function (
143
- pc->function , goto_functions.function_map .at (pc->function ));
144
- }
145
- else
146
- {
147
- log .warning () << " Unable to analyse address-taken locals, as start "
148
- " instruction does not state its function" << messaget::eom;
149
- }
140
+
141
+ INVARIANT (
142
+ !pc->function .empty (), " all symexed instructions should have a function" );
143
+ state.dirty ->populate_dirty_for_function (
144
+ pc->function , get_goto_function (pc->function ));
145
+
150
146
symex_transition (state, state.source .pc );
151
147
}
152
148
153
149
void goto_symext::symex_threaded_step (
154
- statet &state, const goto_functionst &goto_functions )
150
+ statet &state, const get_goto_functiont &get_goto_function )
155
151
{
156
- symex_step (goto_functions , state);
152
+ symex_step (get_goto_function , state);
157
153
158
154
// is there another thread to execute?
159
155
if (state.call_stack ().empty () &&
@@ -168,21 +164,39 @@ void goto_symext::symex_threaded_step(
168
164
}
169
165
}
170
166
167
+ static goto_symext::get_goto_functiont get_function_from_goto_functions (
168
+ const goto_functionst &goto_functions)
169
+ {
170
+ return [&goto_functions](const irep_idt &key) ->
171
+ const goto_functionst::goto_functiont & { // NOLINT(*)
172
+ return goto_functions.function_map .at (key);
173
+ };
174
+ }
175
+
171
176
void goto_symext::symex_with_state (
172
177
statet &state,
173
178
const goto_functionst &goto_functions,
174
179
const goto_programt &goto_program)
180
+ {
181
+ symex_with_state (
182
+ state, get_function_from_goto_functions (goto_functions), goto_program);
183
+ }
184
+
185
+ void goto_symext::symex_with_state (
186
+ statet &state,
187
+ const get_goto_functiont &get_goto_function,
188
+ const goto_programt &goto_program)
175
189
{
176
190
PRECONDITION (!goto_program.instructions .empty ());
177
191
initialize_entry_point (
178
192
state,
179
- goto_functions ,
193
+ get_goto_function ,
180
194
goto_program.instructions .begin (),
181
195
prev (goto_program.instructions .end ()));
182
196
PRECONDITION (state.top ().end_of_function ->is_end_function ());
183
197
184
198
while (!state.call_stack ().empty ())
185
- symex_threaded_step (state, goto_functions );
199
+ symex_threaded_step (state, get_goto_function );
186
200
187
201
state.dirty =nullptr ;
188
202
}
@@ -193,30 +207,48 @@ void goto_symext::symex_instruction_range(
193
207
const goto_programt::const_targett first,
194
208
const goto_programt::const_targett limit)
195
209
{
196
- initialize_entry_point (state, goto_functions, first, limit);
210
+ symex_instruction_range (
211
+ state, get_function_from_goto_functions (goto_functions), first, limit);
212
+ }
213
+
214
+ void goto_symext::symex_instruction_range (
215
+ statet &state,
216
+ const get_goto_functiont &get_goto_function,
217
+ const goto_programt::const_targett first,
218
+ const goto_programt::const_targett limit)
219
+ {
220
+ initialize_entry_point (state, get_goto_function, first, limit);
197
221
while (state.source .pc ->function !=limit->function || state.source .pc !=limit)
198
- symex_threaded_step (state, goto_functions );
222
+ symex_threaded_step (state, get_goto_function );
199
223
}
200
224
201
- // / symex from entry point
202
225
void goto_symext::symex_from_entry_point_of (
203
- const goto_functionst &goto_functions)
226
+ const goto_functionst &goto_functions)
204
227
{
205
- goto_functionst::function_mapt::const_iterator it=
206
- goto_functions. function_map . find ( goto_functionst::entry_point ());
228
+ symex_from_entry_point_of ( get_function_from_goto_functions (goto_functions));
229
+ }
207
230
208
- if (it==goto_functions.function_map .end ())
231
+ // / symex from entry point
232
+ void goto_symext::symex_from_entry_point_of (
233
+ const get_goto_functiont &get_goto_function)
234
+ {
235
+ const goto_functionst::goto_functiont *start_function;
236
+ try
237
+ {
238
+ start_function = &get_goto_function (goto_functionst::entry_point ());
239
+ }
240
+ catch (const std::out_of_range &error)
241
+ {
209
242
throw " the program has no entry point" ;
210
-
211
- const goto_programt &body=it->second .body ;
243
+ }
212
244
213
245
statet state;
214
- symex_with_state (state, goto_functions, body);
246
+ symex_with_state (state, get_goto_function, start_function-> body );
215
247
}
216
248
217
249
// / do just one step
218
250
void goto_symext::symex_step (
219
- const goto_functionst &goto_functions ,
251
+ const get_goto_functiont &get_goto_function ,
220
252
statet &state)
221
253
{
222
254
#if 0
@@ -321,15 +353,15 @@ void goto_symext::symex_step(
321
353
Forall_expr (it, deref_code.arguments ())
322
354
clean_expr (*it, state, false );
323
355
324
- symex_function_call (goto_functions , state, deref_code);
356
+ symex_function_call (get_goto_function , state, deref_code);
325
357
}
326
358
else
327
359
symex_transition (state);
328
360
break ;
329
361
330
362
case OTHER:
331
363
if (!state.guard .is_false ())
332
- symex_other (goto_functions, state);
364
+ symex_other (state);
333
365
334
366
symex_transition (state);
335
367
break ;
0 commit comments