@@ -457,74 +457,65 @@ static void replace_history_parameter_rec(
457457 const source_locationt &location,
458458 const irep_idt &mode,
459459 goto_programt &history,
460- const irep_idt &id )
460+ const irep_idt &history_id )
461461{
462462 for (auto &op : expr.operands ())
463463 {
464464 replace_history_parameter_rec (
465- symbol_table, op, parameter2history, location, mode, history, id );
465+ symbol_table, op, parameter2history, location, mode, history, history_id );
466466 }
467467
468- if (expr.id () == ID_old || expr.id () == ID_loop_entry)
469- {
470- const auto ¶meter = to_history_expr (expr, id).expression ();
468+ if (expr.id () != ID_old && expr.id () != ID_loop_entry)
469+ return ;
471470
472- const auto &id = parameter.id ();
473- if (
474- id == ID_dereference || id == ID_member || id == ID_symbol ||
475- id == ID_ptrmember || id == ID_constant || id == ID_typecast ||
476- id == ID_index)
477- {
478- auto it = parameter2history.find (parameter);
471+ const auto ¶meter = to_history_expr (expr, history_id).expression ();
472+ const auto &id = parameter.id ();
473+ if (
474+ id != ID_dereference && id != ID_member && id != ID_symbol &&
475+ id != ID_ptrmember && id != ID_constant && id != ID_typecast &&
476+ id != ID_index)
477+ {
478+ throw invalid_source_file_exceptiont (
479+ " Tracking history of " + id2string (parameter.id ()) +
480+ " expressions is not supported yet." ,
481+ expr.source_location ());
482+ }
479483
480- if (it == parameter2history.end ())
481- {
482- // 0. Create a skip target to jump to, if the parameter is invalid
483- goto_programt skip_program;
484- const auto skip_target =
485- skip_program.add (goto_programt::make_skip (location));
486-
487- // 1. Create a temporary symbol expression that represents the
488- // history variable
489- symbol_exprt tmp_symbol =
490- new_tmp_symbol (parameter.type (), location, mode, symbol_table)
491- .symbol_expr ();
492-
493- // 2. Associate the above temporary variable to it's corresponding
494- // expression
495- it = parameter2history.emplace (parameter, tmp_symbol).first ;
496-
497- // 3. Add the required instructions to the instructions list
498- // 3.1. Declare the newly created temporary variable
499- history.add (goto_programt::make_decl (tmp_symbol, location));
500-
501- // 3.2. Skip storing the history if the expression is invalid
502- history.add (goto_programt::make_goto (
503- skip_target,
504- not_exprt{
505- all_dereferences_are_valid (parameter, namespacet (symbol_table))},
506- location));
507-
508- // 3.3. Add an assignment such that the value pointed to by the new
509- // temporary variable is equal to the value of the corresponding
510- // parameter
511- history.add (
512- goto_programt::make_assignment (tmp_symbol, parameter, location));
513-
514- // 3.4. Add a skip target
515- history.destructive_append (skip_program);
516- }
484+ // speculatively insert a dummy, which will be replaced below if the insert
485+ // actually happened
486+ auto entry =
487+ parameter2history.insert ({parameter, symbol_exprt::typeless (ID_nil)});
517488
518- expr = it->second ;
519- }
520- else
521- {
522- throw invalid_source_file_exceptiont (
523- " Tracking history of " + id2string (parameter.id ()) +
524- " expressions is not supported yet." ,
525- expr.source_location ());
526- }
489+ if (entry.second )
490+ {
491+ // 1. Create a temporary symbol expression that represents the
492+ // history variable
493+ entry.first ->second =
494+ new_tmp_symbol (parameter.type (), location, mode, symbol_table)
495+ .symbol_expr ();
496+
497+ // 2. Add the required instructions to the instructions list
498+ // 2.1. Declare the newly created temporary variable
499+ history.add (goto_programt::make_decl (entry.first ->second , location));
500+
501+ // 2.2. Skip storing the history if the expression is invalid
502+ auto goto_instruction = history.add (goto_programt::make_incomplete_goto (
503+ not_exprt{
504+ all_dereferences_are_valid (parameter, namespacet (symbol_table))},
505+ location));
506+
507+ // 2.3. Add an assignment such that the value pointed to by the new
508+ // temporary variable is equal to the value of the corresponding
509+ // parameter
510+ history.add (
511+ goto_programt::make_assignment (entry.first ->second , parameter, location));
512+
513+ // 2.4. Complete conditional jump for invalid-parameter case
514+ auto label_instruction = history.add (goto_programt::make_skip (location));
515+ goto_instruction->complete_goto (label_instruction);
527516 }
517+
518+ expr = entry.first ->second ;
528519}
529520
530521replace_history_parametert replace_history_old (
0 commit comments