From d000e9699bdbef6d70ebf5604daa99a01ebb9994 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 29 Nov 2022 19:23:06 +0200 Subject: [PATCH] Use `Span`s to detect "system crate"s, for error deferral (zombie) purposes. --- .../src/builder/builder_methods.rs | 2 +- .../rustc_codegen_spirv/src/builder_spirv.rs | 11 +++--- .../rustc_codegen_spirv/src/codegen_cx/mod.rs | 36 +++++++++++++------ tests/ui/dis/ptr_copy.normal.stderr | 6 ++++ 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index c0e26daff5..f290878cce 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -1469,7 +1469,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { .with_type(dest_ty); if val_is_ptr || dest_is_ptr { - if self.is_system_crate() { + if self.is_system_crate(self.span()) { self.zombie( result.def(self), &format!( diff --git a/crates/rustc_codegen_spirv/src/builder_spirv.rs b/crates/rustc_codegen_spirv/src/builder_spirv.rs index 25746cbe13..a3d6a44512 100644 --- a/crates/rustc_codegen_spirv/src/builder_spirv.rs +++ b/crates/rustc_codegen_spirv/src/builder_spirv.rs @@ -149,7 +149,7 @@ impl SpirvValue { } SpirvValueKind::FnAddr { .. } => { - if cx.is_system_crate() { + if cx.is_system_crate(span) { cx.builder .const_to_id .borrow() @@ -160,9 +160,10 @@ impl SpirvValue { .expect("FnAddr didn't go through proper undef registration") .val } else { - cx.tcx - .sess - .err("Cannot use this function pointer for anything other than calls"); + cx.tcx.sess.span_err( + span, + "Cannot use this function pointer for anything other than calls", + ); // Because we never get beyond compilation (into e.g. linking), // emitting an invalid ID reference here is OK. 0 @@ -174,7 +175,7 @@ impl SpirvValue { original_pointee_ty, zombie_target_undef, } => { - if cx.is_system_crate() { + if cx.is_system_crate(span) { cx.zombie_with_span( zombie_target_undef, span, diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs index 56230c1c1f..d9b25db267 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs @@ -24,7 +24,7 @@ use rustc_middle::mir::Body; use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt}; use rustc_middle::ty::{Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; -use rustc_span::def_id::{DefId, LOCAL_CRATE}; +use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{SourceFile, Span, DUMMY_SP}; use rustc_target::abi::call::{FnAbi, PassMode}; @@ -166,7 +166,7 @@ impl<'tcx> CodegenCx<'tcx> { /// Finally, if *user* code is marked as zombie, then this means that the user tried to do /// something that isn't supported, and should be an error. pub fn zombie_with_span(&self, word: Word, span: Span, reason: &str) { - if self.is_system_crate() { + if self.is_system_crate(span) { self.zombie_even_in_user_code(word, span, reason); } else { self.tcx.sess.span_err(span, reason); @@ -185,14 +185,30 @@ impl<'tcx> CodegenCx<'tcx> { ); } - pub fn is_system_crate(&self) -> bool { - self.tcx + /// Returns `true` if the originating crate of `span` (which could very well + /// be a different crate, e.g. a generic/`#[inline]` function, or a macro), + /// is a "system crate", and therefore allowed to have some errors deferred + /// as "zombies" (see `zombie_with_span`'s docs above for more details). + pub fn is_system_crate(&self, span: Span) -> bool { + // HACK(eddyb) this ignores `.lo` vs `.hi` potentially resulting in + // different `SourceFile`s (which is likely a bug anyway). + let cnum = self + .tcx .sess - .contains_name(self.tcx.hir().krate_attrs(), sym::compiler_builtins) - || self.tcx.crate_name(LOCAL_CRATE) == sym::core - || self.tcx.crate_name(LOCAL_CRATE) == self.sym.spirv_std - || self.tcx.crate_name(LOCAL_CRATE) == self.sym.libm - || self.tcx.crate_name(LOCAL_CRATE) == self.sym.num_traits + .source_map() + .lookup_source_file(span.data().lo) + .cnum; + + self.tcx + .get_attr(cnum.as_def_id(), sym::compiler_builtins) + .is_some() + || [ + sym::core, + self.sym.spirv_std, + self.sym.libm, + self.sym.num_traits, + ] + .contains(&self.tcx.crate_name(cnum)) } pub fn finalize_module(self) -> Module { @@ -532,7 +548,7 @@ impl<'tcx> MiscMethods<'tcx> for CodegenCx<'tcx> { } .def(span, self); - if self.is_system_crate() { + if self.is_system_crate(span) { // Create these undefs up front instead of on demand in SpirvValue::def because // SpirvValue::def can't use cx.emit() self.def_constant(ty, SpirvConst::ZombieUndefForFnAddr); diff --git a/tests/ui/dis/ptr_copy.normal.stderr b/tests/ui/dis/ptr_copy.normal.stderr index 803dc19178..b6969fcc93 100644 --- a/tests/ui/dis/ptr_copy.normal.stderr +++ b/tests/ui/dis/ptr_copy.normal.stderr @@ -3,6 +3,12 @@ error: Cannot memcpy dynamically sized data | 2431 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: Stack: + core::intrinsics::copy:: + ptr_copy::copy_via_raw_ptr + ptr_copy::main + main error: aborting due to previous error