Skip to content

Commit f8ad1f1

Browse files
committed
Generate unique symbol names if const pointers refer to promoted static
1 parent 7af11f8 commit f8ad1f1

File tree

10 files changed

+85
-18
lines changed

10 files changed

+85
-18
lines changed

compiler/rustc_codegen_cranelift/src/global_asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ fn codegen_global_asm_inner<'tcx>(
109109
InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s),
110110
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
111111
match operands[operand_idx] {
112-
GlobalAsmOperandRef::Const { value, ty } => {
112+
GlobalAsmOperandRef::Const { value, ty, instance: _ } => {
113113
match value {
114114
ConstScalar::Int(int) => {
115115
let string = rustc_codegen_ssa::common::asm_const_to_str(

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,12 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
404404
// processed in the previous pass
405405
}
406406

407-
InlineAsmOperandRef::Const { value, ty: _ } => match value {
407+
InlineAsmOperandRef::Const { value, ty: _, instance } => match value {
408408
Scalar::Int(_) => (),
409409
Scalar::Ptr(ptr, _) => {
410410
let (prov, _) = ptr.prov_and_relative_offset();
411411
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
412-
let (val, sym) = self.cx.alloc_to_backend(global_alloc).unwrap();
412+
let (val, sym) = self.cx.alloc_to_backend(global_alloc, instance).unwrap();
413413
const_syms.push(sym.unwrap());
414414
inputs.push(AsmInOperand { constraint: "X".into(), rust_idx, val });
415415
}
@@ -495,7 +495,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
495495
push_to_template(modifier, gcc_index);
496496
}
497497

498-
InlineAsmOperandRef::Const { value, ty } => {
498+
InlineAsmOperandRef::Const { value, ty, instance: _ } => {
499499
match value {
500500
Scalar::Int(int) => {
501501
// Const operands get injected directly into the template
@@ -910,7 +910,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
910910
}
911911
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => {
912912
match operands[operand_idx] {
913-
GlobalAsmOperandRef::Const { value, ty } => {
913+
GlobalAsmOperandRef::Const { value, ty, instance } => {
914914
match value {
915915
Scalar::Int(int) => {
916916
// Const operands get injected directly into the
@@ -937,8 +937,9 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
937937
self.tcx.symbol_name(instance)
938938
}
939939
_ => {
940-
let (_, syms) =
941-
self.alloc_to_backend(global_alloc).unwrap();
940+
let (_, syms) = self
941+
.alloc_to_backend(global_alloc, instance)
942+
.unwrap();
942943
// TODO(antoyo): set the global variable as used.
943944
// TODO(@Amanieu): Additional mangling is needed on
944945
// some targets to add a leading underscore (Mach-O).

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use gccjit::{LValue, RValue, ToRValue, Type};
1+
use gccjit::{GlobalKind, LValue, RValue, ToRValue, Type};
22
use rustc_abi::Primitive::Pointer;
33
use rustc_abi::{self as abi, HasDataLayout};
44
use rustc_codegen_ssa::traits::{
@@ -224,6 +224,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
224224
fn alloc_to_backend(
225225
&self,
226226
global_alloc: GlobalAlloc<'tcx>,
227+
name_hint: Option<Instance<'tcx>>,
227228
) -> Result<(RValue<'gcc>, Option<Instance<'tcx>>), u64> {
228229
let alloc = match global_alloc {
229230
GlobalAlloc::Function { instance, .. } => {
@@ -265,6 +266,18 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
265266
}
266267
};
267268

269+
if let Some(name) = name_hint {
270+
let sym = self.tcx.symbol_name(name);
271+
272+
let init = crate::consts::const_alloc_to_gcc_uncached(self, alloc);
273+
let alloc = alloc.inner();
274+
let typ = self.val_ty(init).get_aligned(alloc.align.bytes());
275+
276+
let global = self.declare_global_with_linkage(sym.name, typ, GlobalKind::Exported);
277+
global.global_set_initializer_rvalue(init);
278+
return Ok((global.get_address(None), Some(name)));
279+
}
280+
268281
let init = self.const_data_from_alloc(alloc);
269282
let alloc = alloc.inner();
270283
let value = match alloc.mutability {
@@ -299,7 +312,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
299312
Scalar::Ptr(ptr, _size) => {
300313
let (prov, offset) = ptr.prov_and_relative_offset();
301314
let alloc_id = prov.alloc_id();
302-
let base_addr = match self.alloc_to_backend(self.tcx.global_alloc(alloc_id)) {
315+
let base_addr = match self.alloc_to_backend(self.tcx.global_alloc(alloc_id), None) {
303316
Ok((base_addr, _)) => base_addr,
304317
Err(base_addr) => {
305318
let val = base_addr.wrapping_add(offset.bytes());

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,12 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
159159
constraints.push(format!("{}", op_idx[&idx]));
160160
}
161161
}
162-
InlineAsmOperandRef::Const { value, ty: _ } => match value {
162+
InlineAsmOperandRef::Const { value, ty: _, instance: _ } => match value {
163163
ConstScalar::Int(_) => (),
164164
ConstScalar::Ptr(ptr, _) => {
165165
let (prov, _) = ptr.prov_and_relative_offset();
166166
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
167-
let (value, _) = self.cx.alloc_to_backend(global_alloc).unwrap();
167+
let (value, _) = self.cx.alloc_to_backend(global_alloc, None).unwrap();
168168
inputs.push(value);
169169
op_idx.insert(idx, constraints.len());
170170
constraints.push("s".to_string());
@@ -212,7 +212,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
212212
template_str.push_str(&format!("${{{}}}", op_idx[&operand_idx]));
213213
}
214214
}
215-
InlineAsmOperandRef::Const { value, ty } => {
215+
InlineAsmOperandRef::Const { value, ty, instance: _ } => {
216216
match value {
217217
ConstScalar::Int(int) => {
218218
// Const operands get injected directly into the template
@@ -431,7 +431,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
431431
InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
432432
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => {
433433
match operands[operand_idx] {
434-
GlobalAsmOperandRef::Const { value, ty } => {
434+
GlobalAsmOperandRef::Const { value, ty, instance } => {
435435
match value {
436436
ConstScalar::Int(int) => {
437437
// Const operands get injected directly into the
@@ -448,7 +448,8 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
448448
ConstScalar::Ptr(ptr, _) => {
449449
let (prov, offset) = ptr.prov_and_relative_offset();
450450
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
451-
let (llval, sym) = self.alloc_to_backend(global_alloc).unwrap();
451+
let (llval, sym) =
452+
self.alloc_to_backend(global_alloc, instance).unwrap();
452453
assert!(sym.is_some());
453454

454455
self.add_compiler_used_global(llval);

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
263263
fn alloc_to_backend(
264264
&self,
265265
global_alloc: GlobalAlloc<'tcx>,
266+
name_hint: Option<Instance<'tcx>>,
266267
) -> Result<(Self::Value, Option<Instance<'tcx>>), u64> {
267268
let alloc = match global_alloc {
268269
GlobalAlloc::Function { instance, .. } => {
@@ -312,6 +313,22 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
312313

313314
let init = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
314315
let alloc = alloc.inner();
316+
317+
if let Some(name) = name_hint {
318+
let sym = self.tcx.symbol_name(name);
319+
320+
// If a hint is provided, always use `static_addr_of_mut`, as `static_addr_of_impl` may
321+
// deduplicate and provide one that doesn't have a desired name.
322+
let value = self.static_addr_of_mut(init, alloc.align, None);
323+
if alloc.mutability.is_not() {
324+
llvm::set_global_constant(value, true);
325+
}
326+
327+
llvm::set_value_name(value, sym.name.as_bytes());
328+
llvm::set_linkage(value, llvm::Linkage::InternalLinkage);
329+
return Ok((value, Some(name)));
330+
}
331+
315332
let value = match alloc.mutability {
316333
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
317334
_ => self.static_addr_of_impl(init, alloc.align, None),
@@ -344,7 +361,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
344361
let (prov, offset) = ptr.prov_and_relative_offset();
345362
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
346363
let base_addr_space = global_alloc.address_space(self);
347-
let base_addr = match self.alloc_to_backend(global_alloc) {
364+
let base_addr = match self.alloc_to_backend(global_alloc, None) {
348365
Ok((base_addr, _)) => base_addr,
349366
Err(base_addr) => {
350367
let val = base_addr.wrapping_add(offset.bytes());

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ where
407407
.iter()
408408
.map(|(op, op_sp)| match *op {
409409
rustc_hir::InlineAsmOperand::Const { ref anon_const } => {
410-
match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
410+
let def_id = anon_const.def_id.to_def_id();
411+
match cx.tcx().const_eval_poly(def_id) {
411412
Ok(const_value) => {
412413
let ty =
413414
cx.tcx().typeck_body(anon_const.body).node_type(anon_const.hir_id);
@@ -421,6 +422,10 @@ where
421422
GlobalAsmOperandRef::Const {
422423
value: common::asm_const_ptr_clean(cx.tcx(), scalar),
423424
ty,
425+
instance: Some(Instance::new_raw(
426+
def_id,
427+
ty::GenericArgs::identity_for_item(cx.tcx(), def_id),
428+
)),
424429
}
425430
}
426431
Err(ErrorHandled::Reported { .. }) => {
@@ -430,6 +435,7 @@ where
430435
GlobalAsmOperandRef::Const {
431436
value: Scalar::from_u32(0),
432437
ty: Ty::new_uint(cx.tcx(), UintTy::U32),
438+
instance: None,
433439
}
434440
}
435441
Err(ErrorHandled::TooGeneric(_)) => {
@@ -456,6 +462,7 @@ where
456462
cx,
457463
),
458464
ty: Ty::new_fn_ptr(cx.tcx(), ty.fn_sig(cx.tcx())),
465+
instance: None,
459466
}
460467
}
461468
rustc_hir::InlineAsmOperand::SymStatic { path: _, def_id } => {

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use rustc_data_structures::packed::Pu128;
77
use rustc_hir::lang_items::LangItem;
88
use rustc_lint_defs::builtin::TAIL_CALL_TRACK_CALLER;
99
use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, Scalar};
10-
use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason};
10+
use rustc_middle::mir::{
11+
self, AssertKind, Const, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
12+
};
1113
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1214
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
1315
use rustc_middle::ty::{self, Instance, Ty};
@@ -1268,6 +1270,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12681270
InlineAsmOperandRef::InOut { reg, late, in_value, out_place }
12691271
}
12701272
mir::InlineAsmOperand::Const { ref value } => {
1273+
let Const::Unevaluated(c, _) = &value.const_ else {
1274+
bug!("need unevaluated const to derive symbol name")
1275+
};
1276+
let const_instance = Instance::new_raw(c.def, c.args);
1277+
12711278
let const_value = self.eval_mir_constant(value);
12721279
let mir::ConstValue::Scalar(scalar) = const_value else {
12731280
span_bug!(
@@ -1279,6 +1286,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12791286
InlineAsmOperandRef::Const {
12801287
value: common::asm_const_ptr_clean(bx.tcx(), scalar),
12811288
ty: value.ty(),
1289+
instance: Some(const_instance),
12821290
}
12831291
}
12841292
mir::InlineAsmOperand::SymFn { ref value } => {
@@ -1298,6 +1306,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12981306
bx,
12991307
),
13001308
ty: Ty::new_fn_ptr(bx.tcx(), const_.ty().fn_sig(bx.tcx())),
1309+
instance: None,
13011310
}
13021311
} else {
13031312
span_bug!(span, "invalid type for asm sym (fn)");

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind};
22
use rustc_hir::attrs::{InstructionSetAttr, Linkage};
33
use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, Scalar};
44
use rustc_middle::mir::mono::{MonoItemData, Visibility};
5-
use rustc_middle::mir::{self, InlineAsmOperand, START_BLOCK};
5+
use rustc_middle::mir::{self, Const, InlineAsmOperand, START_BLOCK};
66
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
77
use rustc_middle::ty::{Instance, Ty, TyCtxt, TypeVisitableExt};
88
use rustc_middle::{bug, span_bug, ty};
@@ -63,6 +63,11 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
6363
) -> GlobalAsmOperandRef<'tcx> {
6464
match op {
6565
InlineAsmOperand::Const { value } => {
66+
let Const::Unevaluated(c, _) = &value.const_ else {
67+
bug!("need unevaluated const to derive symbol name")
68+
};
69+
let const_instance = Instance::new_raw(c.def, c.args);
70+
6671
let const_value = instance
6772
.instantiate_mir_and_normalize_erasing_regions(
6873
cx.tcx(),
@@ -88,6 +93,7 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
8893
GlobalAsmOperandRef::Const {
8994
value: common::asm_const_ptr_clean(cx.tcx(), scalar),
9095
ty: mono_type,
96+
instance: Some(const_instance),
9197
}
9298
}
9399
InlineAsmOperand::SymFn { value } => {
@@ -110,6 +116,7 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
110116
cx,
111117
),
112118
ty: Ty::new_fn_ptr(cx.tcx(), mono_type.fn_sig(cx.tcx())),
119+
instance: None,
113120
}
114121
}
115122
InlineAsmOperand::SymStatic { def_id } => {

compiler/rustc_codegen_ssa/src/traits/asm.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
3030
value: Scalar,
3131
/// Type of the constant. This is needed to extract width and signedness.
3232
ty: Ty<'tcx>,
33+
/// Instance to the const that produces this operand.
34+
///
35+
/// This is used to be able to generate unique name for promoted statics.
36+
instance: Option<Instance<'tcx>>,
3337
},
3438
SymStatic {
3539
def_id: DefId,
@@ -45,6 +49,10 @@ pub enum GlobalAsmOperandRef<'tcx> {
4549
value: Scalar,
4650
/// Type of the constant. This is needed to extract width and signedness.
4751
ty: Ty<'tcx>,
52+
/// Instance to the const that produces this operand.
53+
///
54+
/// This is used to be able to generate unique name for promoted statics.
55+
instance: Option<Instance<'tcx>>,
4856
},
4957
SymStatic {
5058
def_id: DefId,

compiler/rustc_codegen_ssa/src/traits/consts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,13 @@ pub trait ConstCodegenMethods<'tcx>: BackendTypes {
4545
///
4646
/// If the `GlobalAlloc` should not be mapped to a global, but absolute address should be used,
4747
/// an integer is returned as `Err` instead.
48+
///
49+
/// If the caller needs to guarantee a symbol name, it can provide a name hint. The name will be
50+
/// used to generate a new symbol if there isn't one already (i.e. the case of fn/static).
4851
fn alloc_to_backend(
4952
&self,
5053
global_alloc: GlobalAlloc<'tcx>,
54+
name_hint: Option<Instance<'tcx>>,
5155
) -> Result<(Self::Value, Option<Instance<'tcx>>), u64>;
5256
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value;
5357

0 commit comments

Comments
 (0)