Skip to content

Commit 8889905

Browse files
committed
Prevent intrinsic mis-use before the linker
1 parent c04fe52 commit 8889905

File tree

4 files changed

+22
-15
lines changed

4 files changed

+22
-15
lines changed

compiler/rustc_codegen_cranelift/src/abi/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,10 @@ pub(crate) fn codegen_terminator_call<'tcx>(
398398
Ok(()) => return,
399399
// Unimplemented intrinsics must have a fallback body. The fallback body is obtained
400400
// by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`.
401-
Err(()) => Some(Instance::new(instance.def_id(), instance.args)),
401+
Err(()) => {
402+
assert!(!fcx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden);
403+
Some(Instance::new(instance.def_id(), instance.args))
404+
}
402405
}
403406
}
404407
InstanceDef::DropGlue(_, None) => {

compiler/rustc_codegen_ssa/src/mir/block.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1717
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
1818
use rustc_middle::ty::{self, Instance, Ty};
1919
use rustc_session::config::OptLevel;
20-
use rustc_span::{source_map::Spanned, sym, Span, Symbol};
20+
use rustc_span::{source_map::Spanned, sym, Span};
2121
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
2222
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
2323
use rustc_target::spec::abi::Abi;
@@ -672,7 +672,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
672672
&mut self,
673673
helper: &TerminatorCodegenHelper<'tcx>,
674674
bx: &mut Bx,
675-
intrinsic: Option<Symbol>,
675+
intrinsic: Option<ty::IntrinsicDef>,
676676
instance: Option<Instance<'tcx>>,
677677
source_info: mir::SourceInfo,
678678
target: Option<mir::BasicBlock>,
@@ -682,7 +682,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
682682
// Emit a panic or a no-op for `assert_*` intrinsics.
683683
// These are intrinsics that compile to panics so that we can get a message
684684
// which mentions the offending type, even from a const context.
685-
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
685+
let panic_intrinsic = intrinsic.and_then(|i| ValidityRequirement::from_intrinsic(i.name));
686686
if let Some(requirement) = panic_intrinsic {
687687
let ty = instance.unwrap().args.type_at(0);
688688

@@ -787,9 +787,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
787787

788788
// Handle intrinsics old codegen wants Expr's for, ourselves.
789789
let intrinsic = match def {
790-
Some(ty::InstanceDef::Intrinsic(def_id)) => {
791-
Some(bx.tcx().intrinsic(def_id).unwrap().name)
792-
}
790+
Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()),
793791
_ => None,
794792
};
795793

@@ -820,7 +818,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
820818
// The arguments we'll be passing. Plus one to account for outptr, if used.
821819
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
822820

823-
if intrinsic == Some(sym::caller_location) {
821+
if matches!(intrinsic, Some(ty::IntrinsicDef { name: sym::caller_location, .. })) {
824822
return if let Some(target) = target {
825823
let location =
826824
self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
@@ -840,7 +838,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
840838
}
841839

842840
let instance = match intrinsic {
843-
None | Some(sym::drop_in_place) => instance,
841+
None | Some(ty::IntrinsicDef { name: sym::drop_in_place, .. }) => instance,
844842
Some(intrinsic) => {
845843
let mut llargs = Vec::with_capacity(1);
846844
let ret_dest = self.make_return_dest(
@@ -868,7 +866,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
868866
// third argument must be constant. This is
869867
// checked by const-qualification, which also
870868
// promotes any complex rvalues to constants.
871-
if i == 2 && intrinsic == sym::simd_shuffle {
869+
if i == 2 && intrinsic.name == sym::simd_shuffle {
872870
if let mir::Operand::Constant(constant) = &arg.node {
873871
let (llval, ty) = self.simd_shuffle_indices(bx, constant);
874872
return OperandRef {
@@ -899,7 +897,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
899897
};
900898
}
901899
// Call the fallback body instead of generating the intrinsic code
902-
Err(()) => Some(Instance::new(instance.def_id(), instance.args)),
900+
Err(()) => {
901+
assert!(!intrinsic.must_be_overridden);
902+
Some(Instance::new(instance.def_id(), instance.args))
903+
}
903904
}
904905
}
905906
};

tests/ui/intrinsics/not-overridden.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
//! cause an error instead of silently invoking the body.
33
#![feature(rustc_attrs, effects)]
44
// build-fail
5-
// normalize-stderr-test: " .*\n" -> ""
5+
// failure-status:101
6+
// normalize-stderr-test ".*note: .*\n\n" -> ""
7+
// normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> ""
8+
// rustc-env:RUST_BACKTRACE=0
69

710
#[rustc_intrinsic]
811
#[rustc_intrinsic_must_be_overridden]
+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: linking with `cc` failed: exit status: 1
2-
3-
error: aborting due to 1 previous error
1+
error: the compiler unexpectedly panicked. this is a bug.
42

3+
query stack during panic:
4+
end of query stack

0 commit comments

Comments
 (0)