Skip to content

Commit ef9e076

Browse files
committed
Refactor and cleanup
We do not need to do quantifier replacement within ASSIGNS annotation. The replacement maps for ENSURES and REQUIRES clauses should also be maintained independently.
1 parent 60abd1e commit ef9e076

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

src/goto-instrument/code_contracts.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ bool code_contractst::has_contract(const irep_idt fun_name)
172172
}
173173

174174
void code_contractst::add_quantified_variable(
175-
exprt expression,
175+
const exprt &expression,
176176
replace_symbolt &replace,
177-
irep_idt mode)
177+
const irep_idt &mode)
178178
{
179179
if(expression.id() == ID_not || expression.id() == ID_typecast)
180180
{
@@ -213,12 +213,10 @@ void code_contractst::add_quantified_variable(
213213
else if(expression.id() == ID_exists || expression.id() == ID_forall)
214214
{
215215
// When a quantifier expression is found,
216-
// 1. get quantified variables
216+
// for each quantified variable ...
217217
const auto &quantifier_expression = to_quantifier_expr(expression);
218-
const auto &quantified_variables = quantifier_expression.variables();
219-
for(const auto &quantified_variable : quantified_variables)
218+
for(const auto &quantified_variable : quantifier_expression.variables())
220219
{
221-
// for each quantified variable...
222220
const auto &quantified_symbol = to_symbol_expr(quantified_variable);
223221

224222
// 1.1 create fresh symbol
@@ -356,7 +354,8 @@ bool code_contractst::apply_function_contract(
356354

357355
// Create a replace_symbolt object, for replacing expressions in the callee
358356
// with expressions from the call site (e.g. the return value).
359-
replace_symbolt replace;
357+
// This object tracks replacements that are common to both ENSURES and REQUIRES.
358+
replace_symbolt common_replace;
360359
if(type.return_type() != empty_typet())
361360
{
362361
// Check whether the function's return value is not disregarded.
@@ -367,7 +366,7 @@ bool code_contractst::apply_function_contract(
367366
// rewrite calls to foo as follows:
368367
// x = foo() -> assume(__CPROVER_return_value > 5) -> assume(x > 5)
369368
symbol_exprt ret_val(CPROVER_PREFIX "return_value", call.lhs().type());
370-
replace.insert(ret_val, call.lhs());
369+
common_replace.insert(ret_val, call.lhs());
371370
}
372371
else
373372
{
@@ -388,7 +387,7 @@ bool code_contractst::apply_function_contract(
388387
ns,
389388
symbol_table);
390389
symbol_exprt ret_val(CPROVER_PREFIX "return_value", type.return_type());
391-
replace.insert(ret_val, fresh.symbol_expr());
390+
common_replace.insert(ret_val, fresh.symbol_expr());
392391
}
393392
}
394393
}
@@ -403,19 +402,25 @@ bool code_contractst::apply_function_contract(
403402
if(!p_it->get_identifier().empty())
404403
{
405404
symbol_exprt p(p_it->get_identifier(), p_it->type());
406-
replace.insert(p, *a_it);
405+
common_replace.insert(p, *a_it);
407406
}
408407
}
409408

410-
// Add quantified variables in contracts to the symbol map
411409
irep_idt mode = symbol_table.lookup_ref(function).mode;
412-
code_contractst::add_quantified_variable(ensures, replace, mode);
413-
code_contractst::add_quantified_variable(requires, replace, mode);
414410

415-
// Replace expressions in the contract components.
416-
replace(assigns);
417-
replace(requires);
418-
replace(ensures);
411+
// Add quantified variables in contracts to the symbol map
412+
// and create replacement maps for ENSURES and REQUIRES,
413+
// which independently extend common_replace.
414+
{
415+
replace_symbolt replace(common_replace);
416+
code_contractst::add_quantified_variable(ensures, replace, mode);
417+
replace(requires);
418+
}
419+
{
420+
replace_symbolt replace(common_replace);
421+
code_contractst::add_quantified_variable(requires, replace, mode);
422+
replace(ensures);
423+
}
419424

420425
// Insert assertion of the precondition immediately before the call site.
421426
if(requires.is_not_nil())

src/goto-instrument/code_contracts.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,9 @@ class code_contractst
185185
/// the quantified variable is added to the symbol table
186186
/// and to the expression map.
187187
void add_quantified_variable(
188-
exprt expression,
188+
const exprt &expression,
189189
replace_symbolt &replace,
190-
irep_idt mode);
190+
const irep_idt &mode);
191191

192192
/// This function recursively identifies the "old" expressions within expr
193193
/// and replaces them with correspoding history variables.

0 commit comments

Comments
 (0)