From 75b15c68f81094ad6f1da6f29bd42a1197585257 Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Thu, 24 Feb 2022 14:10:41 -0500 Subject: [PATCH] don't ice when an extern static is too big --- compiler/rustc_typeck/src/check/check.rs | 29 +++++++++++-- .../ui/extern/extern-static-size-overflow.rs | 43 +++++++++++++++++++ .../extern/extern-static-size-overflow.stderr | 20 +++++++++ 3 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/extern/extern-static-size-overflow.rs create mode 100644 src/test/ui/extern/extern-static-size-overflow.stderr diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 30ae382de4278..158c3e261b8f1 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -14,7 +14,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::layout::MAX_SIMD_LANES; +use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, OpaqueTypeKey, ParamEnv, Ty, TyCtxt}; @@ -415,10 +415,31 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Spa // have UB during initialization if they are uninhabited, but there also seems to be no good // reason to allow any statics to be uninhabited. let ty = tcx.type_of(def_id); - let Ok(layout) = tcx.layout_of(ParamEnv::reveal_all().and(ty)) else { + let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) { + Ok(l) => l, + // Foreign statics that overflow their allowed size should emit an error + Err(LayoutError::SizeOverflow(_)) + if { + let node = tcx.hir().get_by_def_id(def_id); + matches!( + node, + hir::Node::ForeignItem(hir::ForeignItem { + kind: hir::ForeignItemKind::Static(..), + .. + }) + ) + } => + { + tcx.sess + .struct_span_err(span, "extern static is too large for the current architecture") + .emit(); + return; + } // Generic statics are rejected, but we still reach this case. - tcx.sess.delay_span_bug(span, "generic static must be rejected"); - return; + Err(e) => { + tcx.sess.delay_span_bug(span, &e.to_string()); + return; + } }; if layout.abi.is_uninhabited() { tcx.struct_span_lint_hir( diff --git a/src/test/ui/extern/extern-static-size-overflow.rs b/src/test/ui/extern/extern-static-size-overflow.rs new file mode 100644 index 0000000000000..30a0c44546686 --- /dev/null +++ b/src/test/ui/extern/extern-static-size-overflow.rs @@ -0,0 +1,43 @@ +#[repr(C)] +struct ReallyBig { + _a: [u8; usize::MAX], +} + +// The limit for "too big for the current architecture" is dependent on the target pointer size +// however it's artifically limited on 64 bits +// logic copied from rustc_target::abi::TargetDataLayout::obj_size_bound() +const fn max_size() -> usize { + #[cfg(target_pointer_width = "16")] + { + 1 << 15 + } + + #[cfg(target_pointer_width = "32")] + { + 1 << 31 + } + + #[cfg(target_pointer_width = "64")] + { + 1 << 47 + } + + #[cfg(not(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64" + )))] + { + isize::MAX as usize + } +} + +extern "C" { + static FOO: [u8; 1]; + static BAR: [u8; max_size() - 1]; + static BAZ: [u8; max_size()]; //~ ERROR extern static is too large + static UWU: [usize; usize::MAX]; //~ ERROR extern static is too large + static A: ReallyBig; //~ ERROR extern static is too large +} + +fn main() {} diff --git a/src/test/ui/extern/extern-static-size-overflow.stderr b/src/test/ui/extern/extern-static-size-overflow.stderr new file mode 100644 index 0000000000000..f5173feec75d4 --- /dev/null +++ b/src/test/ui/extern/extern-static-size-overflow.stderr @@ -0,0 +1,20 @@ +error: extern static is too large for the current architecture + --> $DIR/extern-static-size-overflow.rs:38:5 + | +LL | static BAZ: [u8; max_size()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: extern static is too large for the current architecture + --> $DIR/extern-static-size-overflow.rs:39:5 + | +LL | static UWU: [usize; usize::MAX]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: extern static is too large for the current architecture + --> $DIR/extern-static-size-overflow.rs:40:5 + | +LL | static A: ReallyBig; + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors +