Skip to content

Commit

Permalink
don't ice when an extern static is too big
Browse files Browse the repository at this point in the history
  • Loading branch information
asquared31415 committed Feb 24, 2022
1 parent 3d127e2 commit 75b15c6
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 4 deletions.
29 changes: 25 additions & 4 deletions compiler/rustc_typeck/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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(
Expand Down
43 changes: 43 additions & 0 deletions src/test/ui/extern/extern-static-size-overflow.rs
Original file line number Diff line number Diff line change
@@ -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() {}
20 changes: 20 additions & 0 deletions src/test/ui/extern/extern-static-size-overflow.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 75b15c6

Please sign in to comment.