Skip to content

Commit ef2719f

Browse files
authored
Rollup merge of rust-lang#93850 - asquared31415:extern-static-size-ice, r=jackh726
Don't ICE when an extern static is too big for the current architecture Fixes rust-lang#93760 Emit an error instead of ICEing when an `extern` static's size overflows the allowed maximum for the target. Changes the error message in the existing `delay_span_bug` call to the true layout error, first for debugging purposes, but opted to leave in to potentially assist future developers as it was being reached in unexpected ways already.
2 parents 6cbc6c3 + 75b15c6 commit ef2719f

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

compiler/rustc_typeck/src/check/check.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
1414
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1515
use rustc_middle::hir::nested_filter;
1616
use rustc_middle::ty::fold::TypeFoldable;
17-
use rustc_middle::ty::layout::MAX_SIMD_LANES;
17+
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
1818
use rustc_middle::ty::subst::GenericArgKind;
1919
use rustc_middle::ty::util::{Discr, IntTypeExt};
2020
use rustc_middle::ty::{self, OpaqueTypeKey, ParamEnv, Ty, TyCtxt};
@@ -417,10 +417,31 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Spa
417417
// have UB during initialization if they are uninhabited, but there also seems to be no good
418418
// reason to allow any statics to be uninhabited.
419419
let ty = tcx.type_of(def_id);
420-
let Ok(layout) = tcx.layout_of(ParamEnv::reveal_all().and(ty)) else {
420+
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
421+
Ok(l) => l,
422+
// Foreign statics that overflow their allowed size should emit an error
423+
Err(LayoutError::SizeOverflow(_))
424+
if {
425+
let node = tcx.hir().get_by_def_id(def_id);
426+
matches!(
427+
node,
428+
hir::Node::ForeignItem(hir::ForeignItem {
429+
kind: hir::ForeignItemKind::Static(..),
430+
..
431+
})
432+
)
433+
} =>
434+
{
435+
tcx.sess
436+
.struct_span_err(span, "extern static is too large for the current architecture")
437+
.emit();
438+
return;
439+
}
421440
// Generic statics are rejected, but we still reach this case.
422-
tcx.sess.delay_span_bug(span, "generic static must be rejected");
423-
return;
441+
Err(e) => {
442+
tcx.sess.delay_span_bug(span, &e.to_string());
443+
return;
444+
}
424445
};
425446
if layout.abi.is_uninhabited() {
426447
tcx.struct_span_lint_hir(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#[repr(C)]
2+
struct ReallyBig {
3+
_a: [u8; usize::MAX],
4+
}
5+
6+
// The limit for "too big for the current architecture" is dependent on the target pointer size
7+
// however it's artifically limited on 64 bits
8+
// logic copied from rustc_target::abi::TargetDataLayout::obj_size_bound()
9+
const fn max_size() -> usize {
10+
#[cfg(target_pointer_width = "16")]
11+
{
12+
1 << 15
13+
}
14+
15+
#[cfg(target_pointer_width = "32")]
16+
{
17+
1 << 31
18+
}
19+
20+
#[cfg(target_pointer_width = "64")]
21+
{
22+
1 << 47
23+
}
24+
25+
#[cfg(not(any(
26+
target_pointer_width = "16",
27+
target_pointer_width = "32",
28+
target_pointer_width = "64"
29+
)))]
30+
{
31+
isize::MAX as usize
32+
}
33+
}
34+
35+
extern "C" {
36+
static FOO: [u8; 1];
37+
static BAR: [u8; max_size() - 1];
38+
static BAZ: [u8; max_size()]; //~ ERROR extern static is too large
39+
static UWU: [usize; usize::MAX]; //~ ERROR extern static is too large
40+
static A: ReallyBig; //~ ERROR extern static is too large
41+
}
42+
43+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: extern static is too large for the current architecture
2+
--> $DIR/extern-static-size-overflow.rs:38:5
3+
|
4+
LL | static BAZ: [u8; max_size()];
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: extern static is too large for the current architecture
8+
--> $DIR/extern-static-size-overflow.rs:39:5
9+
|
10+
LL | static UWU: [usize; usize::MAX];
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: extern static is too large for the current architecture
14+
--> $DIR/extern-static-size-overflow.rs:40:5
15+
|
16+
LL | static A: ReallyBig;
17+
| ^^^^^^^^^^^^^^^^^^^^
18+
19+
error: aborting due to 3 previous errors
20+

0 commit comments

Comments
 (0)