Skip to content

Commit 62dd13c

Browse files
authored
Support function implementations of known built-ins (#3945)
Kani should produce valid symbol tables in GOTO binaries when Rust code provides an implementation for a built-in known to Kani. Without this fix, goto-cc fails the following invariant: ``` --- begin invariant violation report --- Invariant check failed File: ../src/ansi-c/goto-conversion/goto_convert_functions.cpp:164 function: convert_function Condition: parameter identifier should not be empty Reason: !p.empty() ``` 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 707309b commit 62dd13c

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/function.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,22 @@ impl GotocCtx<'_> {
204204
let body = self.transformer.body(self.tcx, instance);
205205
self.set_current_fn(instance, &body);
206206
debug!(krate=?instance.def.krate(), is_std=self.current_fn().is_std(), "declare_function");
207-
self.ensure(instance.mangled_name(), |ctx, fname| {
208-
Symbol::function(
209-
fname,
210-
ctx.fn_typ(instance, &body),
211-
None,
212-
instance.name(),
213-
ctx.codegen_span_stable(instance.def.span()),
214-
)
215-
});
207+
let fname = instance.mangled_name();
208+
let sym = Symbol::function(
209+
&fname,
210+
self.fn_typ(instance, &body),
211+
None,
212+
instance.name(),
213+
self.codegen_span_stable(instance.def.span()),
214+
);
215+
if !self.symbol_table.contains((&fname).into()) {
216+
self.symbol_table.insert(sym);
217+
} else {
218+
let old_sym = self.symbol_table.lookup(fname).unwrap();
219+
if old_sym.location.is_builtin() {
220+
self.symbol_table.replace(|_| true, sym);
221+
}
222+
}
216223
self.reset_current_fn();
217224
}
218225
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Function with the same name as a known built-in, but we provide an alternative implementation
5+
// instead of using the built-in.
6+
#[no_mangle]
7+
fn copysign(a: f64, _b: f64) -> f64 {
8+
a
9+
}
10+
11+
#[kani::proof]
12+
pub fn harness() {
13+
let a: f64 = kani::any();
14+
let b: f64 = kani::any();
15+
copysign(a, b);
16+
}

0 commit comments

Comments
 (0)