Skip to content

Commit d875666

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 d951013 commit d875666

File tree

1 file changed

+49
-58
lines changed

1 file changed

+49
-58
lines changed

src/goto-instrument/contracts/utils.cpp

+49-58
Original file line numberDiff line numberDiff line change
@@ -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 &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-
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

530521
replace_history_parametert replace_history_old(

0 commit comments

Comments
 (0)