-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CONTRATCS: force success for unit pointer predicates
Force success for pointer predicates that appear as top level units in requires or ensures clauses. For example `__CPROVER_ensures(__CPROVER_is_fresh(p,size))` is a unit. This ensures that the value set of `p` after assuming the clause contains a unique valid target. It solves a performance issue with z3. All predicates in the `cprover_contracts.c` library now have an extra input `may_fail` controlling the failure behaviour, instrumentation detects units in contracts and sets the `may_fail` parameter accordingly.
- Loading branch information
Remi Delmas
committed
Jan 23, 2025
1 parent
d4757e2
commit 9e8e5c2
Showing
9 changed files
with
106 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ Author: Remi Delmas, [email protected] | |
|
||
#include "dfcc_contract_functions.h" | ||
#include "dfcc_instrument.h" | ||
#include "dfcc_is_cprover_symbol.h" | ||
#include "dfcc_library.h" | ||
#include "dfcc_lift_memory_predicates.h" | ||
#include "dfcc_pointer_equals.h" | ||
|
@@ -535,6 +536,37 @@ void dfcc_wrapper_programt::encode_is_fresh_set() | |
postamble.add(goto_programt::make_dead(is_fresh_set, wrapper_sl)); | ||
} | ||
|
||
#include <iostream> | ||
|
||
/// If the expression is a function call to one of the pointer predicates, | ||
/// adds a "_no_fail" prefix to the function name. This is later picked up | ||
/// by fix_calls to synthesize the value of the `may_fail` parameter for | ||
/// pointer predicates. | ||
bool disable_may_fail(exprt &expr) | ||
{ | ||
if(expr.id() != ID_side_effect) | ||
return false; | ||
|
||
side_effect_exprt &side_effect = to_side_effect_expr(expr); | ||
if(side_effect.get_statement() != ID_function_call) | ||
return false; | ||
|
||
exprt &function = side_effect.operands()[0]; | ||
if(function.id() != ID_symbol) | ||
return false; | ||
|
||
const irep_idt &func_name = to_symbol_expr(function).get_identifier(); | ||
|
||
if(dfcc_is_cprover_pointer_predicate(func_name)) | ||
{ | ||
// tag call as no_fail | ||
function.add_source_location().set("no_fail", true); | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
void dfcc_wrapper_programt::encode_requires_clauses() | ||
{ | ||
// we use this empty requires write set to check for the absence of side | ||
|
@@ -556,6 +588,9 @@ void dfcc_wrapper_programt::encode_requires_clauses() | |
{ | ||
exprt requires_lmbd = | ||
to_lambda_expr(r).application(contract_lambda_parameters); | ||
|
||
// add "no_fail" suffix to predicates required as units | ||
disable_may_fail(requires_lmbd); | ||
source_locationt sl(r.source_location()); | ||
if(statement_type == ID_assert) | ||
{ | ||
|
@@ -605,6 +640,9 @@ void dfcc_wrapper_programt::encode_ensures_clauses() | |
.application(contract_lambda_parameters) | ||
.with_source_location(e); | ||
|
||
// add "no_fail" suffix to unit pointer predicates | ||
disable_may_fail(ensures); | ||
|
||
// this also rewrites ID_old expressions to fresh variables | ||
generate_history_variables_initialization( | ||
goto_model.symbol_table, ensures, language_mode, history); | ||
|