Skip to content

Commit 7814587

Browse files
committed
Refactor replace_history_parameter_rec
Reduce the indentation level by doing early returns, and do the map lookup just once instead of three times.
1 parent d2d52c2 commit 7814587

File tree

1 file changed

+53
-58
lines changed

1 file changed

+53
-58
lines changed

src/goto-instrument/contracts/utils.cpp

Lines changed: 53 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -457,74 +457,69 @@ 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 &parameter = 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 &parameter = 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-
parameter2history[parameter] = tmp_symbol;
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 = parameter2history[parameter];
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+
// 0. Create a skip target to jump to, if the parameter is invalid
492+
goto_programt skip_program;
493+
const auto skip_target =
494+
skip_program.add(goto_programt::make_skip(location));
495+
496+
// 1. Create a symbol expression that represents the history variable
497+
entry.first->second =
498+
new_tmp_symbol(parameter.type(), location, mode, symbol_table)
499+
.symbol_expr();
500+
501+
// 3. Add the required instructions to the instructions list
502+
// 3.1. Declare the newly created temporary variable
503+
history.add(goto_programt::make_decl(entry.first->second, location));
504+
505+
// 3.2. Skip storing the history if the expression is invalid
506+
history.add(goto_programt::make_goto(
507+
skip_target,
508+
not_exprt{
509+
all_dereferences_are_valid(parameter, namespacet(symbol_table))},
510+
location));
511+
512+
// 3.3. Add an assignment such that the value pointed to by the new
513+
// temporary variable is equal to the value of the corresponding
514+
// parameter
515+
history.add(
516+
goto_programt::make_assignment(entry.first->second, parameter, location));
517+
518+
// 3.4. Add a skip target
519+
history.destructive_append(skip_program);
527520
}
521+
522+
expr = entry.first->second;
528523
}
529524

530525
replace_history_parametert replace_history_old(

0 commit comments

Comments
 (0)