Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,18 +497,23 @@ impl<'tcx> GotocCtx<'tcx> {
let instance = Instance::mono(self.tcx, def_id);

let sym = self.ensure(&self.symbol_name(instance), |ctx, name| {
// check if this static is extern
let rlinkage = ctx.tcx.codegen_fn_attrs(def_id).linkage;

// we believe rlinkage being `Some` means the static not extern
// based on compiler/rustc_codegen_cranelift/src/linkage.rs#L21
// see https://github.com/model-checking/kani/issues/388
//
// Update: The assertion below may fail in similar environments.
// We are disabling it until we find out the root cause, see
// https://github.com/model-checking/kani/issues/400
//
// assert!(rlinkage.is_none());
// Rust has a notion of "extern static" variables. These are in an "extern" block,
// and so aren't initialized in the current codegen unit. For example (from std):
// extern "C" {
// #[linkage = "extern_weak"]
// static __dso_handle: *mut u8;
// #[linkage = "extern_weak"]
// static __cxa_thread_atexit_impl: *const libc::c_void;
// }
// CBMC shares C's notion of "extern" global variables. However, CBMC mostly does
// not use this information except when doing C typechecking.
// The one exception is handling static variables with no initializer in
// CBMC's `static_lifetime_init`:
// 1. If they are `is_extern` they are nondet-initialized.
// 2. If they are `!is_extern`, they are zero-initialized.
// Replacing `is_extern` with a constant `true` or `false` both pass the Kani regressions.
// Nevertheless, we can correctly recognize a Rust "extern" declaration and pass that along.
let is_extern = ctx.tcx.is_foreign_item(def_id);

let span = ctx.tcx.def_span(def_id);
Symbol::static_variable(
Expand All @@ -517,7 +522,7 @@ impl<'tcx> GotocCtx<'tcx> {
ctx.codegen_ty(instance.ty(ctx.tcx, ty::ParamEnv::reveal_all())),
ctx.codegen_span(&span),
)
.with_is_extern(rlinkage.is_none())
.with_is_extern(is_extern)
.with_is_thread_local(is_thread_local)
});
sym.clone().to_expr().address_of()
Expand Down