@@ -254,12 +254,34 @@ void goto_symext::symex_with_state(
254
254
const get_goto_functiont &get_goto_function,
255
255
symbol_tablet &new_symbol_table)
256
256
{
257
+ // resets the namespace to only wrap a single symbol table, and does so upon
258
+ // destruction of an object of this type; instantiating the type is thus all
259
+ // that's needed to achieve a reset upon exiting this method
260
+ struct reset_namespacet
261
+ {
262
+ explicit reset_namespacet (namespacet &ns) : ns(ns)
263
+ {
264
+ }
265
+
266
+ ~reset_namespacet ()
267
+ {
268
+ const symbol_tablet &st = ns.get_symbol_table ();
269
+ ns = namespacet (st);
270
+ }
271
+
272
+ namespacet &ns;
273
+ };
274
+
257
275
// We'll be using ns during symbolic execution and it needs to know
258
276
// about the names minted in `state`, so make it point both to
259
277
// `state`'s symbol table and the symbol table of the original
260
278
// goto-program.
261
279
ns = namespacet (outer_symbol_table, state.symbol_table );
262
280
281
+ // whichever way we exit this method, reset the namespace back to a sane state
282
+ // as state.symbol_table might go out of scope
283
+ reset_namespacet reset_ns (ns);
284
+
263
285
PRECONDITION (state.top ().end_of_function ->is_end_function ());
264
286
265
287
symex_threaded_step (state, get_goto_function);
@@ -279,9 +301,6 @@ void goto_symext::symex_with_state(
279
301
// execution, so return the names generated through symbolic execution
280
302
// through `new_symbol_table`.
281
303
new_symbol_table = state.symbol_table ;
282
- // reset the namespace back to a sane state as state.symbol_table might go out
283
- // of scope
284
- ns = namespacet (outer_symbol_table);
285
304
}
286
305
287
306
void goto_symext::resume_symex_from_saved_state (
0 commit comments