@@ -497,18 +497,22 @@ impl<'tcx> GotocCtx<'tcx> {
497497 let instance = Instance :: mono ( self . tcx , def_id) ;
498498
499499 let sym = self . ensure ( & self . symbol_name ( instance) , |ctx, name| {
500- // check if this static is extern
501- let rlinkage = ctx. tcx . codegen_fn_attrs ( def_id) . linkage ;
502-
503- // we believe rlinkage being `Some` means the static not extern
504- // based on compiler/rustc_codegen_cranelift/src/linkage.rs#L21
505- // see https://github.com/model-checking/kani/issues/388
506- //
507- // Update: The assertion below may fail in similar environments.
508- // We are disabling it until we find out the root cause, see
509- // https://github.com/model-checking/kani/issues/400
510- //
511- // assert!(rlinkage.is_none());
500+ // Rust has a notion of "extern static" variables. These are in an "extern" block,
501+ // and so aren't initialized in the current codegen unit. For example (from std):
502+ // extern "C" {
503+ // #[linkage = "extern_weak"]
504+ // static __dso_handle: *mut u8;
505+ // #[linkage = "extern_weak"]
506+ // static __cxa_thread_atexit_impl: *const libc::c_void;
507+ // }
508+ // CBMC shares C's notion of "extern" global variables. However, CBMC mostly does
509+ // not use this information except when doing C typechecking.
510+ // The one exception is handling static variables with no initializer (see
511+ // CBMC's `static_lifetime_init`):
512+ // 1. If they are `is_extern` they are nondet-initialized.
513+ // 2. If they are `!is_extern`, they are zero-initialized.
514+ // So we recognize a Rust "extern" declaration and pass that information along.
515+ let is_extern = ctx. tcx . is_foreign_item ( def_id) ;
512516
513517 let span = ctx. tcx . def_span ( def_id) ;
514518 Symbol :: static_variable (
@@ -517,7 +521,7 @@ impl<'tcx> GotocCtx<'tcx> {
517521 ctx. codegen_ty ( instance. ty ( ctx. tcx , ty:: ParamEnv :: reveal_all ( ) ) ) ,
518522 ctx. codegen_span ( & span) ,
519523 )
520- . with_is_extern ( rlinkage . is_none ( ) )
524+ . with_is_extern ( is_extern )
521525 . with_is_thread_local ( is_thread_local)
522526 } ) ;
523527 sym. clone ( ) . to_expr ( ) . address_of ( )
0 commit comments