22
33use rustc_hir:: LangItem ;
44use rustc_hir:: attrs:: PeImportNameType ;
5+ use rustc_middle:: bug;
6+ use rustc_middle:: mir:: interpret:: { GlobalAlloc , PointerArithmetic , Scalar } ;
57use rustc_middle:: ty:: layout:: TyAndLayout ;
68use rustc_middle:: ty:: { self , Instance , ScalarInt , TyCtxt } ;
7- use rustc_middle:: { bug, span_bug} ;
89use rustc_session:: cstore:: { DllCallingConvention , DllImport } ;
910use rustc_span:: Span ;
1011use rustc_target:: spec:: { Abi , Env , Os , Target } ;
@@ -148,7 +149,6 @@ pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
148149
149150pub fn asm_const_to_str < ' tcx > (
150151 tcx : TyCtxt < ' tcx > ,
151- sp : Span ,
152152 scalar : ScalarInt ,
153153 ty_and_layout : TyAndLayout < ' tcx > ,
154154) -> String {
@@ -163,7 +163,34 @@ pub fn asm_const_to_str<'tcx>(
163163 ty:: IntTy :: I128 => ( value as i128 ) . to_string ( ) ,
164164 ty:: IntTy :: Isize => unreachable ! ( ) ,
165165 } ,
166- _ => span_bug ! ( sp, "asm const has bad type {}" , ty_and_layout. ty) ,
166+ // For unsigned integers or pointers without provenance, just print the unsigned value
167+ _ => value. to_string ( ) ,
168+ }
169+ }
170+
171+ /// "Clean" a const pointer by removing values where the resulting ASM will not be
172+ /// `<symbol> + <offset>`.
173+ ///
174+ /// These values are converted to `ScalarInt`.
175+ pub fn asm_const_ptr_clean < ' tcx > ( tcx : TyCtxt < ' tcx > , scalar : Scalar ) -> Scalar {
176+ let Scalar :: Ptr ( ptr, _) = scalar else {
177+ return scalar;
178+ } ;
179+ let ( prov, offset) = ptr. prov_and_relative_offset ( ) ;
180+ let global_alloc = tcx. global_alloc ( prov. alloc_id ( ) ) ;
181+ match global_alloc {
182+ GlobalAlloc :: TypeId { .. } => {
183+ // `TypeId` provenances are not a thing in codegen. Just erase and replace with scalar offset.
184+ Scalar :: from_u64 ( offset. bytes ( ) )
185+ }
186+ GlobalAlloc :: Memory ( alloc) if alloc. inner ( ) . len ( ) == 0 => {
187+ // ZST const allocations don't actually get global defined when lowered.
188+ // Turn them into integer without provenances now.
189+ let val = alloc. inner ( ) . align . bytes ( ) . wrapping_add ( offset. bytes ( ) ) ;
190+ Scalar :: from_target_usize ( tcx. truncate_to_target_usize ( val) , & tcx)
191+ }
192+ // Other types of `GlobalAlloc` are fine.
193+ _ => scalar,
167194 }
168195}
169196
0 commit comments