Skip to content

Commit

Permalink
Fix missing function declaration issue
Browse files Browse the repository at this point in the history
In cases where a function pointer is created, but its value is never
used, Kani crashes due to missing function declaration.

For now, collect any instance that has its address taken even if its
never used.

Fixes #3799
  • Loading branch information
celinval committed Jan 29, 2025
1 parent bc134ce commit ac1f63a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
16 changes: 16 additions & 0 deletions kani-compiler/src/kani_middle/reachability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,22 @@ impl MirVisitor for MonoItemsFnCollector<'_, '_> {

self.super_terminator(terminator, location);
}

/// Collect any function definition that may occur as a type.
///
/// The codegen stage will require the definition to be available.
/// This is a conservative approach, since there are cases where the function is never
/// actually used, so we don't need the body.
///
/// Another alternative would be to lazily declare functions, but it would require a bigger
/// change to codegen.
fn visit_ty(&mut self, ty: &Ty, _: Location) {
if let TyKind::RigidTy(RigidTy::FnDef(def, args)) = ty.kind() {
let instance = Instance::resolve(def, &args).unwrap();
self.collect_instance(instance, true);
}
self.super_ty(ty);
}
}

fn extract_unsize_coercion(tcx: TyCtxt, orig_ty: Ty, dst_trait: Ty) -> (Ty, Ty) {
Expand Down
27 changes: 27 additions & 0 deletions tests/kani/CodegenMisc/missing_mut_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Ensure Kani can codegen code with a pointer to a function that is never used
//! See <https://github.com/model-checking/kani/issues/3799> for more details.
fn foo<F: Fn()>(_func: &mut F) {}
fn foo_dyn(_func: &mut dyn Fn()) {}

#[kani::proof]
fn check_foo() {
fn f() {}

foo(&mut f);
}

#[kani::proof]
fn check_foo_dyn() {
fn f() {}

foo_dyn(&mut f);
}

#[kani::proof]
fn check_foo_unused() {
fn f() {}

let ptr = &mut f;
}

0 comments on commit ac1f63a

Please sign in to comment.