Skip to content

Commit 6f45e45

Browse files
committed
Detect repeated contract enforcement in goto-instrument
goto-instrument must detect when it is being invoked again when contract enforcement has already been run as only one contract can be enforced at a time. Fixes: #7830
1 parent 4fe3ade commit 6f45e45

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

src/goto-instrument/contracts/contracts.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Date: February 2016
1414
#include "contracts.h"
1515

1616
#include <util/c_types.h>
17+
#include <util/exception_utils.h>
1718
#include <util/format_expr.h>
1819
#include <util/fresh_symbol.h>
1920
#include <util/mathematical_expr.h>
@@ -1199,16 +1200,25 @@ void code_contractst::check_frame_conditions_function(const irep_idt &function)
11991200

12001201
void code_contractst::enforce_contract(const irep_idt &function)
12011202
{
1202-
// Add statements to the source function
1203-
// to ensure assigns clause is respected.
1204-
check_frame_conditions_function(function);
1205-
12061203
// Rename source function
12071204
std::stringstream ss;
12081205
ss << CPROVER_PREFIX << "contracts_original_" << function;
12091206
const irep_idt mangled(ss.str());
12101207
const irep_idt original(function);
12111208

1209+
// Check if contract enforcement has already been applied to this function
1210+
if(symbol_table.has_symbol(mangled))
1211+
{
1212+
throw invalid_input_exceptiont(
1213+
"Contract enforcement has already been applied to function '" +
1214+
id2string(function) +
1215+
"'.\nOnly one contract may be enforced at a time per function.");
1216+
}
1217+
1218+
// Add statements to the source function
1219+
// to ensure assigns clause is respected.
1220+
check_frame_conditions_function(function);
1221+
12121222
auto old_function = goto_functions.function_map.find(original);
12131223
INVARIANT(
12141224
old_function != goto_functions.function_map.end(),

src/goto-instrument/contracts/dynamic-frames/dfcc.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ dfcct::dfcct(
171171

172172
void dfcct::check_transform_goto_model_preconditions()
173173
{
174+
// Check if contract enforcement has already been applied
175+
const irep_idt dfcc_map_name = "__dfcc_instrumented_functions";
176+
PRECONDITION_WITH_DIAGNOSTICS(
177+
!goto_model.symbol_table.has_symbol(dfcc_map_name),
178+
"Contract enforcement has already been applied to this binary.\n"
179+
"Only one contract may be enforced at a time.");
180+
174181
// check that harness function exists
175182
PRECONDITION_WITH_DIAGNOSTICS(
176183
dfcc_utilst::function_symbol_with_body_exists(goto_model, harness_id),

0 commit comments

Comments
 (0)