@@ -208,16 +208,22 @@ exprt smt2_parsert::let_expression()
208208 if (next_token () != smt2_tokenizert::CLOSE)
209209 throw error (" expected ')' at end of bindings" );
210210
211- // save the renaming map
212- renaming_mapt old_renaming_map=renaming_map ;
211+ // we may hide identifiers in outer scopes
212+ std::vector<std::pair<irep_idt, idt>> saved_ids ;
213213
214- // go forwards, add to id_map, renaming if need be
214+ // add the bindings to the id_map
215215 for (auto &b : bindings)
216216 {
217- // get a fresh id for it
218- b.first = add_fresh_id (b.first , idt::BINDING, b.second );
217+ auto insert_result = id_map.insert ({b.first , idt{idt::BINDING, b.second }});
218+ if (!insert_result.second ) // already there
219+ {
220+ auto &id_entry = *insert_result.first ;
221+ saved_ids.emplace_back (id_entry.first , std::move (id_entry.second ));
222+ id_entry.second = idt{idt::BINDING, b.second };
223+ }
219224 }
220225
226+ // now parse, with bindings in place
221227 exprt where = expression ();
222228
223229 if (next_token () != smt2_tokenizert::CLOSE)
@@ -232,11 +238,13 @@ exprt smt2_parsert::let_expression()
232238 values.push_back (b.second );
233239 }
234240
235- // we keep these in the id_map in order to retain globally
236- // unique identifiers
241+ // delete the bindings from the id_map
242+ for (const auto &binding : bindings)
243+ id_map.erase (binding.first );
237244
238- // restore renamings
239- renaming_map=old_renaming_map;
245+ // restore any previous ids
246+ for (auto &saved_id : saved_ids)
247+ id_map.insert (std::move (saved_id));
240248
241249 return let_exprt (variables, values, where);
242250}
0 commit comments