Skip to content

Commit b143c5d

Browse files
authored
Unrolled build for rust-lang#122879
Rollup merge of rust-lang#122879 - maurer:callsite-instances, r=workingjubilee CFI: Strip auto traits off Virtual calls We already use `Instance` at declaration sites when available to glean additional information about possible abstractions of the type in use. This does the same when possible at callsites as well. The primary purpose of this change is to allow CFI to alter how it generates type information for indirect calls through `Virtual` instances. This is needed for the "separate machinery" version of my approach to the vtable issues (rust-lang#122573), because we need to respond differently to a `Virtual` call to the same type as a non-virtual call, specifically [stripping auto traits off the receiver's `Self`](rust-lang@54b15b0) because there isn't a separate vtable for `Foo` vs `Foo + Send`. This would also make a more general underlying mechanism that could be used by rcvalle's [proposed drop detection / encoding](rust-lang@edcd1e2) if we end up using his approach, as we could condition out on the `def_id` in the CFI code rather than requiring the generating code to explicitly note whether it was calling drop.
2 parents 548e14b + f434c27 commit b143c5d

File tree

14 files changed

+155
-58
lines changed

14 files changed

+155
-58
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
541541
let builtin_unreachable: RValue<'gcc> = unsafe {
542542
std::mem::transmute(builtin_unreachable)
543543
};
544-
self.call(self.type_void(), None, None, builtin_unreachable, &[], None);
544+
self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None);
545545
}
546546

547547
// Write results to outputs.

compiler/rustc_codegen_gcc/src/builder.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{
2525
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
2626
TyAndLayout,
2727
};
28-
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
28+
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance};
2929
use rustc_span::def_id::DefId;
3030
use rustc_span::Span;
3131
use rustc_target::abi::{
@@ -592,12 +592,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
592592
then: Block<'gcc>,
593593
catch: Block<'gcc>,
594594
_funclet: Option<&Funclet>,
595+
instance: Option<Instance<'tcx>>,
595596
) -> RValue<'gcc> {
596597
let try_block = self.current_func().new_block("try");
597598

598599
let current_block = self.block.clone();
599600
self.block = try_block;
600-
let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here?
601+
let call = self.call(typ, fn_attrs, None, func, args, None, instance); // TODO(antoyo): use funclet here?
601602
self.block = current_block;
602603

603604
let return_value =
@@ -1667,6 +1668,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16671668
func: RValue<'gcc>,
16681669
args: &[RValue<'gcc>],
16691670
funclet: Option<&Funclet>,
1671+
_instance: Option<Instance<'tcx>>,
16701672
) -> RValue<'gcc> {
16711673
// FIXME(antoyo): remove when having a proper API.
16721674
let gcc_func = unsafe { std::mem::transmute(func) };

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
133133
func,
134134
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
135135
None,
136+
None,
136137
)
137138
}
138139
sym::likely => self.expect(args[0].immediate(), true),
@@ -401,7 +402,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
401402
fn abort(&mut self) {
402403
let func = self.context.get_builtin_function("abort");
403404
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
404-
self.call(self.type_void(), None, None, func, &[], None);
405+
self.call(self.type_void(), None, None, func, &[], None, None);
405406
}
406407

407408
fn assume(&mut self, value: Self::Value) {
@@ -1103,7 +1104,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
11031104
dest: RValue<'gcc>,
11041105
) {
11051106
if bx.sess().panic_strategy() == PanicStrategy::Abort {
1106-
bx.call(bx.type_void(), None, None, try_func, &[data], None);
1107+
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
11071108
// Return 0 unconditionally from the intrinsic call;
11081109
// we can never unwind.
11091110
let ret_align = bx.tcx.data_layout.i32_align.abi;
@@ -1177,21 +1178,21 @@ fn codegen_gnu_try<'gcc>(
11771178
let zero = bx.cx.context.new_rvalue_zero(bx.int_type);
11781179
let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]);
11791180
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
1180-
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None);
1181+
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
11811182
bx.ret(bx.const_i32(1));
11821183

11831184
// NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
11841185
// generate a try/catch.
11851186
// FIXME(antoyo): add a check in the libgccjit API to prevent this.
11861187
bx.switch_to_block(current_block);
1187-
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
1188+
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
11881189
});
11891190

11901191
let func = unsafe { std::mem::transmute(func) };
11911192

11921193
// Note that no invoke is used here because by definition this function
11931194
// can't panic (that's what it's catching).
1194-
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None);
1195+
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None);
11951196
let i32_align = bx.tcx().data_layout.i32_align.abi;
11961197
bx.store(ret, dest, i32_align);
11971198
}

compiler/rustc_codegen_llvm/src/asm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,11 @@ pub(crate) fn inline_asm_call<'ll>(
466466

467467
let call = if !labels.is_empty() {
468468
assert!(catch_funclet.is_none());
469-
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None)
469+
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
470470
} else if let Some((catch, funclet)) = catch_funclet {
471-
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet)
471+
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
472472
} else {
473-
bx.call(fty, None, None, v, inputs, None)
473+
bx.call(fty, None, None, v, inputs, None, None)
474474
};
475475

476476
// Store mark in a metadata node so we can map LLVM errors

compiler/rustc_codegen_llvm/src/builder.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
1919
use rustc_middle::ty::layout::{
2020
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
2121
};
22-
use rustc_middle::ty::{self, Ty, TyCtxt};
22+
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
2323
use rustc_span::Span;
24-
use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions};
24+
use rustc_symbol_mangling::typeid::{
25+
kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance,
26+
TypeIdOptions,
27+
};
2528
use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
2629
use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
2730
use smallvec::SmallVec;
@@ -221,6 +224,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
221224
then: &'ll BasicBlock,
222225
catch: &'ll BasicBlock,
223226
funclet: Option<&Funclet<'ll>>,
227+
instance: Option<Instance<'tcx>>,
224228
) -> &'ll Value {
225229
debug!("invoke {:?} with args ({:?})", llfn, args);
226230

@@ -233,10 +237,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
233237
}
234238

235239
// Emit CFI pointer type membership test
236-
self.cfi_type_test(fn_attrs, fn_abi, llfn);
240+
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
237241

238242
// Emit KCFI operand bundle
239-
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
243+
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
240244
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
241245
if let Some(kcfi_bundle) = kcfi_bundle {
242246
bundles.push(kcfi_bundle);
@@ -1231,6 +1235,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
12311235
llfn: &'ll Value,
12321236
args: &[&'ll Value],
12331237
funclet: Option<&Funclet<'ll>>,
1238+
instance: Option<Instance<'tcx>>,
12341239
) -> &'ll Value {
12351240
debug!("call {:?} with args ({:?})", llfn, args);
12361241

@@ -1243,10 +1248,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
12431248
}
12441249

12451250
// Emit CFI pointer type membership test
1246-
self.cfi_type_test(fn_attrs, fn_abi, llfn);
1251+
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
12471252

12481253
// Emit KCFI operand bundle
1249-
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
1254+
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
12501255
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
12511256
if let Some(kcfi_bundle) = kcfi_bundle {
12521257
bundles.push(kcfi_bundle);
@@ -1468,7 +1473,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14681473

14691474
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
14701475
let (ty, f) = self.cx.get_intrinsic(intrinsic);
1471-
self.call(ty, None, None, f, args, None)
1476+
self.call(ty, None, None, f, args, None, None)
14721477
}
14731478

14741479
fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
@@ -1526,7 +1531,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15261531
format!("llvm.{instr}.sat.i{int_width}.f{float_width}")
15271532
};
15281533
let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
1529-
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None)
1534+
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None, None)
15301535
}
15311536

15321537
pub(crate) fn landing_pad(
@@ -1554,6 +1559,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15541559
default_dest: &'ll BasicBlock,
15551560
indirect_dest: &[&'ll BasicBlock],
15561561
funclet: Option<&Funclet<'ll>>,
1562+
instance: Option<Instance<'tcx>>,
15571563
) -> &'ll Value {
15581564
debug!("invoke {:?} with args ({:?})", llfn, args);
15591565

@@ -1566,10 +1572,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15661572
}
15671573

15681574
// Emit CFI pointer type membership test
1569-
self.cfi_type_test(fn_attrs, fn_abi, llfn);
1575+
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
15701576

15711577
// Emit KCFI operand bundle
1572-
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
1578+
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
15731579
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
15741580
if let Some(kcfi_bundle) = kcfi_bundle {
15751581
bundles.push(kcfi_bundle);
@@ -1601,6 +1607,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16011607
&mut self,
16021608
fn_attrs: Option<&CodegenFnAttrs>,
16031609
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
1610+
instance: Option<Instance<'tcx>>,
16041611
llfn: &'ll Value,
16051612
) {
16061613
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
@@ -1622,7 +1629,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16221629
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
16231630
}
16241631

1625-
let typeid = typeid_for_fnabi(self.tcx, fn_abi, options);
1632+
let typeid = if let Some(instance) = instance {
1633+
typeid_for_instance(self.tcx, &instance, options)
1634+
} else {
1635+
typeid_for_fnabi(self.tcx, fn_abi, options)
1636+
};
16261637
let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
16271638

16281639
// Test whether the function pointer is associated with the type identifier.
@@ -1644,6 +1655,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16441655
&mut self,
16451656
fn_attrs: Option<&CodegenFnAttrs>,
16461657
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
1658+
instance: Option<Instance<'tcx>>,
16471659
llfn: &'ll Value,
16481660
) -> Option<llvm::OperandBundleDef<'ll>> {
16491661
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
@@ -1665,7 +1677,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16651677
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
16661678
}
16671679

1668-
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
1680+
let kcfi_typeid = if let Some(instance) = instance {
1681+
kcfi_typeid_for_instance(self.tcx, &instance, options)
1682+
} else {
1683+
kcfi_typeid_for_fnabi(self.tcx, fn_abi, options)
1684+
};
1685+
16691686
Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
16701687
} else {
16711688
None

0 commit comments

Comments
 (0)