@@ -210,6 +210,14 @@ impl<'ll> CodegenCx<'ll, '_> {
210210 unsafe { llvm:: LLVMConstBitCast ( val, ty) }
211211 }
212212
213+ pub ( crate ) fn const_pointercast ( & self , val : & ' ll Value , ty : & ' ll Type ) -> & ' ll Value {
214+ unsafe { llvm:: LLVMConstPointerCast ( val, ty) }
215+ }
216+
217+ /// Create a global variable.
218+ ///
219+ /// The returned global variable is a pointer in the default address space for globals.
220+ /// Fails if a symbol with the given name already exists.
213221 pub ( crate ) fn static_addr_of_mut (
214222 & self ,
215223 cv : & ' ll Value ,
@@ -233,6 +241,34 @@ impl<'ll> CodegenCx<'ll, '_> {
233241 gv
234242 }
235243
244+ /// Create a global constant.
245+ ///
246+ /// The returned global variable is a pointer in the default address space for globals.
247+ pub ( crate ) fn static_addr_of_impl (
248+ & self ,
249+ cv : & ' ll Value ,
250+ align : Align ,
251+ kind : Option < & str > ,
252+ ) -> & ' ll Value {
253+ if let Some ( & gv) = self . const_globals . borrow ( ) . get ( & cv) {
254+ unsafe {
255+ // Upgrade the alignment in cases where the same constant is used with different
256+ // alignment requirements
257+ let llalign = align. bytes ( ) as u32 ;
258+ if llalign > llvm:: LLVMGetAlignment ( gv) {
259+ llvm:: LLVMSetAlignment ( gv, llalign) ;
260+ }
261+ }
262+ return gv;
263+ }
264+ let gv = self . static_addr_of_mut ( cv, align, kind) ;
265+ unsafe {
266+ llvm:: LLVMSetGlobalConstant ( gv, True ) ;
267+ }
268+ self . const_globals . borrow_mut ( ) . insert ( cv, gv) ;
269+ gv
270+ }
271+
236272 #[ instrument( level = "debug" , skip( self ) ) ]
237273 pub ( crate ) fn get_static ( & self , def_id : DefId ) -> & ' ll Value {
238274 let instance = Instance :: mono ( self . tcx , def_id) ;
@@ -505,24 +541,15 @@ impl<'ll> CodegenCx<'ll, '_> {
505541}
506542
507543impl < ' ll > StaticCodegenMethods for CodegenCx < ' ll , ' _ > {
544+ /// Get a pointer to a global variable.
545+ ///
546+ /// The pointer will always be in the default address space. If global variables default to a
547+ /// different address space, an addrspacecast is inserted.
508548 fn static_addr_of ( & self , cv : & ' ll Value , align : Align , kind : Option < & str > ) -> & ' ll Value {
509- if let Some ( & gv) = self . const_globals . borrow ( ) . get ( & cv) {
510- unsafe {
511- // Upgrade the alignment in cases where the same constant is used with different
512- // alignment requirements
513- let llalign = align. bytes ( ) as u32 ;
514- if llalign > llvm:: LLVMGetAlignment ( gv) {
515- llvm:: LLVMSetAlignment ( gv, llalign) ;
516- }
517- }
518- return gv;
519- }
520- let gv = self . static_addr_of_mut ( cv, align, kind) ;
521- unsafe {
522- llvm:: LLVMSetGlobalConstant ( gv, True ) ;
523- }
524- self . const_globals . borrow_mut ( ) . insert ( cv, gv) ;
525- gv
549+ let gv = self . static_addr_of_impl ( cv, align, kind) ;
550+ // static_addr_of_impl returns the bare global variable, which might not be in the default
551+ // address space. Cast to the default address space if necessary.
552+ self . const_pointercast ( gv, self . type_ptr ( ) )
526553 }
527554
528555 fn codegen_static ( & self , def_id : DefId ) {
0 commit comments