@@ -396,149 +396,148 @@ impl<'ll> CodegenCx<'ll, '_> {
396396 }
397397
398398 fn codegen_static_item ( & mut self , def_id : DefId ) {
399- unsafe {
400- assert ! (
401- llvm:: LLVMGetInitializer (
402- self . instances. borrow( ) . get( & Instance :: mono( self . tcx, def_id) ) . unwrap( )
403- )
404- . is_none( )
405- ) ;
406- let attrs = self . tcx . codegen_fn_attrs ( def_id) ;
399+ assert ! (
400+ llvm:: LLVMGetInitializer (
401+ self . instances. borrow( ) . get( & Instance :: mono( self . tcx, def_id) ) . unwrap( )
402+ )
403+ . is_none( )
404+ ) ;
405+ let attrs = self . tcx . codegen_fn_attrs ( def_id) ;
407406
408- let Ok ( ( v, alloc) ) = codegen_static_initializer ( self , def_id) else {
409- // Error has already been reported
410- return ;
411- } ;
412- let alloc = alloc. inner ( ) ;
407+ let Ok ( ( v, alloc) ) = codegen_static_initializer ( self , def_id) else {
408+ // Error has already been reported
409+ return ;
410+ } ;
411+ let alloc = alloc. inner ( ) ;
413412
414- let val_llty = self . val_ty ( v) ;
413+ let val_llty = self . val_ty ( v) ;
415414
416- let g = self . get_static_inner ( def_id, val_llty) ;
417- let llty = self . get_type_of_global ( g) ;
415+ let g = self . get_static_inner ( def_id, val_llty) ;
416+ let llty = self . get_type_of_global ( g) ;
418417
419- let g = if val_llty == llty {
420- g
421- } else {
422- // codegen_static_initializer creates the global value just from the
423- // `Allocation` data by generating one big struct value that is just
424- // all the bytes and pointers after each other. This will almost never
425- // match the type that the static was declared with. Unfortunately
426- // we can't just LLVMConstBitCast our way out of it because that has very
427- // specific rules on what can be cast. So instead of adding a new way to
428- // generate static initializers that match the static's type, we picked
429- // the easier option and retroactively change the type of the static item itself.
430- let name = llvm:: get_value_name ( g) ;
431- llvm:: set_value_name ( g, b"" ) ;
432-
433- let linkage = llvm:: get_linkage ( g) ;
434- let visibility = llvm:: get_visibility ( g) ;
435-
436- let new_g = llvm:: LLVMRustGetOrInsertGlobal (
437- self . llmod ,
438- name. as_c_char_ptr ( ) ,
439- name. len ( ) ,
440- val_llty,
441- ) ;
442-
443- llvm:: set_linkage ( new_g, linkage) ;
444- llvm:: set_visibility ( new_g, visibility) ;
445-
446- // The old global has had its name removed but is returned by
447- // get_static since it is in the instance cache. Provide an
448- // alternative lookup that points to the new global so that
449- // global_asm! can compute the correct mangled symbol name
450- // for the global.
451- self . renamed_statics . borrow_mut ( ) . insert ( def_id, new_g) ;
452-
453- // To avoid breaking any invariants, we leave around the old
454- // global for the moment; we'll replace all references to it
455- // with the new global later. (See base::codegen_backend.)
456- self . statics_to_rauw . borrow_mut ( ) . push ( ( g, new_g) ) ;
457- new_g
458- } ;
459- set_global_alignment ( self , g, alloc. align ) ;
460- llvm:: set_initializer ( g, v) ;
461-
462- self . assume_dso_local ( g, true ) ;
463-
464- // Forward the allocation's mutability (picked by the const interner) to LLVM.
465- if alloc. mutability . is_not ( ) {
466- llvm:: set_global_constant ( g, true ) ;
467- }
418+ let g = if val_llty == llty {
419+ g
420+ } else {
421+ // codegen_static_initializer creates the global value just from the
422+ // `Allocation` data by generating one big struct value that is just
423+ // all the bytes and pointers after each other. This will almost never
424+ // match the type that the static was declared with. Unfortunately
425+ // we can't just LLVMConstBitCast our way out of it because that has very
426+ // specific rules on what can be cast. So instead of adding a new way to
427+ // generate static initializers that match the static's type, we picked
428+ // the easier option and retroactively change the type of the static item itself.
429+ let name = String :: from_utf8 ( llvm:: get_value_name ( g) )
430+ . expect ( "we declare our statics with a utf8-valid name" ) ;
431+ llvm:: set_value_name ( g, b"" ) ;
432+
433+ let linkage = llvm:: get_linkage ( g) ;
434+ let visibility = llvm:: get_visibility ( g) ;
435+
436+ let new_g = self . declare_global ( & name, val_llty) ;
437+
438+ llvm:: set_linkage ( new_g, linkage) ;
439+ llvm:: set_visibility ( new_g, visibility) ;
440+
441+ // The old global has had its name removed but is returned by
442+ // get_static since it is in the instance cache. Provide an
443+ // alternative lookup that points to the new global so that
444+ // global_asm! can compute the correct mangled symbol name
445+ // for the global.
446+ self . renamed_statics . borrow_mut ( ) . insert ( def_id, new_g) ;
447+
448+ // To avoid breaking any invariants, we leave around the old
449+ // global for the moment; we'll replace all references to it
450+ // with the new global later. (See base::codegen_backend.)
451+ self . statics_to_rauw . borrow_mut ( ) . push ( ( g, new_g) ) ;
452+ new_g
453+ } ;
454+ set_global_alignment ( self , g, alloc. align ) ;
455+ llvm:: set_initializer ( g, v) ;
468456
469- debuginfo :: build_global_var_di_node ( self , def_id , g ) ;
457+ self . assume_dso_local ( g , true ) ;
470458
471- if attrs. flags . contains ( CodegenFnAttrFlags :: THREAD_LOCAL ) {
472- llvm:: set_thread_local_mode ( g, self . tls_model ) ;
473- }
459+ // Forward the allocation's mutability (picked by the const interner) to LLVM.
460+ if alloc. mutability . is_not ( ) {
461+ llvm:: set_global_constant ( g, true ) ;
462+ }
474463
475- // Wasm statics with custom link sections get special treatment as they
476- // go into custom sections of the wasm executable. The exception to this
477- // is the `.init_array` section which are treated specially by the wasm linker.
478- if self . tcx . sess . target . is_like_wasm
479- && attrs
480- . link_section
481- . map ( |link_section| !link_section. as_str ( ) . starts_with ( ".init_array" ) )
482- . unwrap_or ( true )
483- {
484- if let Some ( section) = attrs. link_section {
485- let section = llvm:: LLVMMDStringInContext2 (
464+ debuginfo:: build_global_var_di_node ( self , def_id, g) ;
465+
466+ if attrs. flags . contains ( CodegenFnAttrFlags :: THREAD_LOCAL ) {
467+ llvm:: set_thread_local_mode ( g, self . tls_model ) ;
468+ }
469+
470+ // Wasm statics with custom link sections get special treatment as they
471+ // go into custom sections of the wasm executable. The exception to this
472+ // is the `.init_array` section which are treated specially by the wasm linker.
473+ if self . tcx . sess . target . is_like_wasm
474+ && attrs
475+ . link_section
476+ . map ( |link_section| !link_section. as_str ( ) . starts_with ( ".init_array" ) )
477+ . unwrap_or ( true )
478+ {
479+ if let Some ( section) = attrs. link_section {
480+ let section = unsafe {
481+ llvm:: LLVMMDStringInContext2 (
486482 self . llcx ,
487483 section. as_str ( ) . as_c_char_ptr ( ) ,
488484 section. as_str ( ) . len ( ) ,
489- ) ;
490- assert ! ( alloc. provenance( ) . ptrs( ) . is_empty( ) ) ;
491-
492- // The `inspect` method is okay here because we checked for provenance, and
493- // because we are doing this access to inspect the final interpreter state (not
494- // as part of the interpreter execution).
495- let bytes =
496- alloc. inspect_with_uninit_and_ptr_outside_interpreter ( 0 ..alloc. len ( ) ) ;
497- let alloc =
498- llvm:: LLVMMDStringInContext2 ( self . llcx , bytes. as_c_char_ptr ( ) , bytes. len ( ) ) ;
499- let data = [ section, alloc] ;
500- let meta = llvm:: LLVMMDNodeInContext2 ( self . llcx , data. as_ptr ( ) , data. len ( ) ) ;
501- let val = self . get_metadata_value ( meta) ;
485+ )
486+ } ;
487+ assert ! ( alloc. provenance( ) . ptrs( ) . is_empty( ) ) ;
488+
489+ // The `inspect` method is okay here because we checked for provenance, and
490+ // because we are doing this access to inspect the final interpreter state (not
491+ // as part of the interpreter execution).
492+ let bytes = alloc. inspect_with_uninit_and_ptr_outside_interpreter ( 0 ..alloc. len ( ) ) ;
493+ let alloc = unsafe {
494+ llvm:: LLVMMDStringInContext2 ( self . llcx , bytes. as_c_char_ptr ( ) , bytes. len ( ) )
495+ } ;
496+ let data = [ section, alloc] ;
497+ let meta =
498+ unsafe { llvm:: LLVMMDNodeInContext2 ( self . llcx , data. as_ptr ( ) , data. len ( ) ) } ;
499+ let val = self . get_metadata_value ( meta) ;
500+ unsafe {
502501 llvm:: LLVMAddNamedMetadataOperand (
503502 self . llmod ,
504503 c"wasm.custom_sections" . as_ptr ( ) ,
505504 val,
506- ) ;
507- }
508- } else {
509- base:: set_link_section ( g, attrs) ;
505+ )
506+ } ;
510507 }
508+ } else {
509+ base:: set_link_section ( g, attrs) ;
510+ }
511511
512- base:: set_variable_sanitizer_attrs ( g, attrs) ;
513-
514- if attrs. flags . contains ( CodegenFnAttrFlags :: USED_COMPILER ) {
515- // `USED` and `USED_LINKER` can't be used together.
516- assert ! ( !attrs. flags. contains( CodegenFnAttrFlags :: USED_LINKER ) ) ;
517-
518- // The semantics of #[used] in Rust only require the symbol to make it into the
519- // object file. It is explicitly allowed for the linker to strip the symbol if it
520- // is dead, which means we are allowed to use `llvm.compiler.used` instead of
521- // `llvm.used` here.
522- //
523- // Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
524- // sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs
525- // in the handling of `.init_array` (the static constructor list) in versions of
526- // the gold linker (prior to the one released with binutils 2.36).
527- //
528- // That said, we only ever emit these when `#[used(compiler)]` is explicitly
529- // requested. This is to avoid similar breakage on other targets, in particular
530- // MachO targets have *their* static constructor lists broken if `llvm.compiler.used`
531- // is emitted rather than `llvm.used`. However, that check happens when assigning
532- // the `CodegenFnAttrFlags` in the `codegen_fn_attrs` query, so we don't need to
533- // take care of it here.
534- self . add_compiler_used_global ( g) ;
535- }
536- if attrs. flags . contains ( CodegenFnAttrFlags :: USED_LINKER ) {
537- // `USED` and `USED_LINKER` can't be used together.
538- assert ! ( !attrs. flags. contains( CodegenFnAttrFlags :: USED_COMPILER ) ) ;
512+ base:: set_variable_sanitizer_attrs ( g, attrs) ;
513+
514+ if attrs. flags . contains ( CodegenFnAttrFlags :: USED_COMPILER ) {
515+ // `USED` and `USED_LINKER` can't be used together.
516+ assert ! ( !attrs. flags. contains( CodegenFnAttrFlags :: USED_LINKER ) ) ;
517+
518+ // The semantics of #[used] in Rust only require the symbol to make it into the
519+ // object file. It is explicitly allowed for the linker to strip the symbol if it
520+ // is dead, which means we are allowed to use `llvm.compiler.used` instead of
521+ // `llvm.used` here.
522+ //
523+ // Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
524+ // sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs
525+ // in the handling of `.init_array` (the static constructor list) in versions of
526+ // the gold linker (prior to the one released with binutils 2.36).
527+ //
528+ // That said, we only ever emit these when `#[used(compiler)]` is explicitly
529+ // requested. This is to avoid similar breakage on other targets, in particular
530+ // MachO targets have *their* static constructor lists broken if `llvm.compiler.used`
531+ // is emitted rather than `llvm.used`. However, that check happens when assigning
532+ // the `CodegenFnAttrFlags` in the `codegen_fn_attrs` query, so we don't need to
533+ // take care of it here.
534+ self . add_compiler_used_global ( g) ;
535+ }
536+ if attrs. flags . contains ( CodegenFnAttrFlags :: USED_LINKER ) {
537+ // `USED` and `USED_LINKER` can't be used together.
538+ assert ! ( !attrs. flags. contains( CodegenFnAttrFlags :: USED_COMPILER ) ) ;
539539
540- self . add_used_global ( g) ;
541- }
540+ self . add_used_global ( g) ;
542541 }
543542 }
544543
0 commit comments