@@ -254,7 +254,7 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
254254 if (next_token () != smt2_tokenizert::OPEN)
255255 throw error () << " expected bindings after " << id;
256256
257- std::vector<symbol_exprt> bindings;
257+ binding_exprt::variablest bindings;
258258
259259 while (smt2_tokenizer.peek () == smt2_tokenizert::OPEN)
260260 {
@@ -276,18 +276,23 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
276276 if (next_token () != smt2_tokenizert::CLOSE)
277277 throw error (" expected ')' at end of bindings" );
278278
279- // save the renaming map
280- renaming_mapt old_renaming_map = renaming_map ;
279+ // we may hide identifiers in outer scopes
280+ std::vector<std::pair<irep_idt, idt>> saved_ids ;
281281
282- // go forwards, add to id_map, renaming if need be
282+ // add the bindings to the id_map
283283 for (auto &b : bindings)
284284 {
285- const irep_idt id =
286- add_fresh_id (b.get_identifier (), idt::BINDING, exprt (ID_nil, b.type ()));
287-
288- b.set_identifier (id);
285+ auto insert_result =
286+ id_map.insert ({b.get_identifier (), idt{idt::BINDING, b.type ()}});
287+ if (!insert_result.second ) // already there
288+ {
289+ auto &id_entry = *insert_result.first ;
290+ saved_ids.emplace_back (id_entry.first , std::move (id_entry.second ));
291+ id_entry.second = idt{idt::BINDING, b.type ()};
292+ }
289293 }
290294
295+ // now parse, with bindings in place
291296 exprt expr=expression ();
292297
293298 if (next_token () != smt2_tokenizert::CLOSE)
@@ -299,8 +304,9 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
299304 for (const auto &b : bindings)
300305 id_map.erase (b.get_identifier ());
301306
302- // restore renaming map
303- renaming_map = old_renaming_map;
307+ // restore any previous ids
308+ for (auto &saved_id : saved_ids)
309+ id_map.insert (std::move (saved_id));
304310
305311 // go backwards, build quantified expression
306312 for (auto r_it=bindings.rbegin (); r_it!=bindings.rend (); r_it++)
0 commit comments