Skip to content

Commit ab2cb50

Browse files
authored
Call goto-instrument with DFCC only once (#3642)
DFCC should be called only once. This PR combined the two DCFF calls into one. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent a8a28ee commit ab2cb50

File tree

1 file changed

+40
-40
lines changed

1 file changed

+40
-40
lines changed

kani-driver/src/call_goto_instrument.rs

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,12 @@ impl KaniSession {
3737
self.goto_sanity_check(output)?;
3838
}
3939

40-
self.instrument_contracts(harness, output)?;
41-
42-
if self
40+
let is_loop_contracts_enabled = self
4341
.args
4442
.common_args
4543
.unstable_features
46-
.contains(kani_metadata::UnstableFeature::LoopContracts)
47-
{
48-
self.instrument_loop_contracts(harness, output)?;
49-
}
44+
.contains(kani_metadata::UnstableFeature::LoopContracts);
45+
self.instrument_contracts(harness, is_loop_contracts_enabled, output)?;
5046

5147
if self.args.checks.undefined_function_on() {
5248
self.add_library(output)?;
@@ -172,42 +168,46 @@ impl KaniSession {
172168
self.call_goto_instrument(args)
173169
}
174170

175-
/// Make CBMC enforce a function contract.
176-
pub fn instrument_contracts(&self, harness: &HarnessMetadata, file: &Path) -> Result<()> {
177-
let Some(assigns) = harness.contract.as_ref() else { return Ok(()) };
171+
/// Apply annotated function contracts and loop contracts with goto-instrument.
172+
pub fn instrument_contracts(
173+
&self,
174+
harness: &HarnessMetadata,
175+
is_loop_contracts_enabled: bool,
176+
file: &Path,
177+
) -> Result<()> {
178+
// Do nothing if neither loop contracts nor function contracts is enabled.
179+
if !is_loop_contracts_enabled && harness.contract.is_none() {
180+
return Ok(());
181+
}
178182

179-
let mut args: Vec<OsString> = vec![
180-
"--dfcc".into(),
181-
(&harness.mangled_name).into(),
182-
"--enforce-contract".into(),
183-
assigns.contracted_function_name.as_str().into(),
184-
"--no-malloc-may-fail".into(),
185-
file.into(),
186-
file.into(),
187-
];
188-
if let Some(tracker) = &assigns.recursion_tracker {
189-
args.push("--nondet-static-exclude".into());
190-
args.push(tracker.as_str().into());
183+
let mut args: Vec<OsString> =
184+
vec!["--dfcc".into(), (&harness.mangled_name).into(), "--no-malloc-may-fail".into()];
185+
186+
if is_loop_contracts_enabled {
187+
args.append(&mut vec![
188+
"--apply-loop-contracts".into(),
189+
"--loop-contracts-no-unwind".into(),
190+
// Because loop contracts now are wrapped in a closure which will be a side-effect expression in CBMC even they
191+
// may not contain side-effect. So we disable the side-effect check for now and will implement a better check
192+
// instead of simply rejecting function calls and statement expressions.
193+
// See issue: diffblue/cbmc#8393
194+
"--disable-loop-contracts-side-effect-check".into(),
195+
]);
191196
}
192-
self.call_goto_instrument(&args)
193-
}
194197

195-
/// Apply annotated loop contracts.
196-
pub fn instrument_loop_contracts(&self, harness: &HarnessMetadata, file: &Path) -> Result<()> {
197-
let args: Vec<OsString> = vec![
198-
"--dfcc".into(),
199-
(&harness.mangled_name).into(),
200-
"--apply-loop-contracts".into(),
201-
"--loop-contracts-no-unwind".into(),
202-
"--no-malloc-may-fail".into(),
203-
// Because loop contracts now are wrapped in a closure which will be a side-effect expression in CBMC even they
204-
// may not contain side-effect. So we disable the side-effect check for now and will implement a better check
205-
// instead of simply rejecting function calls and statement expressions.
206-
// See issue: diffblue/cbmc#8393
207-
"--disable-loop-contracts-side-effect-check".into(),
208-
file.into(),
209-
file.into(),
210-
];
198+
if let Some(assigns) = harness.contract.as_ref() {
199+
args.push("--enforce-contract".into());
200+
args.push(assigns.contracted_function_name.as_str().into());
201+
202+
if let Some(tracker) = &assigns.recursion_tracker {
203+
args.push("--nondet-static-exclude".into());
204+
args.push(tracker.as_str().into());
205+
}
206+
}
207+
208+
args.push(file.into());
209+
args.push(file.into());
210+
211211
self.call_goto_instrument(&args)
212212
}
213213

0 commit comments

Comments
 (0)