Skip to content

Commit cfa946e

Browse files
committed
Auto merge of #127546 - workingjubilee:5-level-paging-exists, r=<try>
Correct outdated object size limit The comment here about 48 bit addresses being enough was written in 2016 but was made incorrect in 2019 by 5-level paging, and then persisted for another 5 years before being noticed and corrected. The bolding of the "exclusive" part is merely to call attention to something I missed when reading it and doublechecking the math. try-job: i686-msvc try-job: test-various
2 parents 506f22b + 8431855 commit cfa946e

14 files changed

+65
-82
lines changed

compiler/rustc_abi/src/lib.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -337,23 +337,21 @@ impl TargetDataLayout {
337337
Ok(dl)
338338
}
339339

340-
/// Returns exclusive upper bound on object size.
340+
/// Returns **exclusive** upper bound on object size.
341341
///
342342
/// The theoretical maximum object size is defined as the maximum positive `isize` value.
343343
/// This ensures that the `offset` semantics remain well-defined by allowing it to correctly
344344
/// index every address within an object along with one byte past the end, along with allowing
345345
/// `isize` to store the difference between any two pointers into an object.
346346
///
347-
/// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer
348-
/// to represent object size in bits. It would need to be 1 << 61 to account for this, but is
349-
/// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
350-
/// address space on 64-bit ARMv8 and x86_64.
347+
/// LLVM uses a 64-bit integer to represent object size in bits, but we care only for bytes,
348+
/// so we adopt such a more-constrained address space due to its technical limitations.
351349
#[inline]
352350
pub fn obj_size_bound(&self) -> u64 {
353351
match self.pointer_size.bits() {
354352
16 => 1 << 15,
355353
32 => 1 << 31,
356-
64 => 1 << 47,
354+
64 => 1 << 61,
357355
bits => panic!("obj_size_bound: unknown pointer bit size {bits}"),
358356
}
359357
}

src/tools/tidy/src/issues.txt

-2
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,6 @@ ui/const-generics/infer/issue-77092.rs
552552
ui/const-generics/issue-102124.rs
553553
ui/const-generics/issue-105689.rs
554554
ui/const-generics/issue-106419-struct-with-multiple-const-params.rs
555-
ui/const-generics/issue-112505-overflow.rs
556555
ui/const-generics/issue-46511.rs
557556
ui/const-generics/issue-66451.rs
558557
ui/const-generics/issue-70408.rs
@@ -2718,7 +2717,6 @@ ui/limits/issue-15919-32.rs
27182717
ui/limits/issue-15919-64.rs
27192718
ui/limits/issue-17913.rs
27202719
ui/limits/issue-55878.rs
2721-
ui/limits/issue-56762.rs
27222720
ui/limits/issue-69485-var-size-diffs-too-large.rs
27232721
ui/limits/issue-75158-64.rs
27242722
ui/linkage-attr/auxiliary/issue-12133-dylib.rs

tests/crashes/125476.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
//@ known-bug: rust-lang/rust#125476
22
//@ only-x86_64
3-
pub struct Data([u8; usize::MAX >> 16]);
3+
pub struct Data([u8; usize::MAX >> 2]);
44
const _: &'static [Data] = &[];

tests/ui/const-generics/issue-112505-overflow.rs

-7
This file was deleted.

tests/ui/const-generics/issue-112505-overflow.stderr

-12
This file was deleted.

tests/ui/const-generics/transmute-fail.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
// ignore-tidy-linelength
2+
//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
3+
//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
4+
5+
16
#![feature(transmute_generic_consts)]
27
#![feature(generic_const_exprs)]
38
#![allow(incomplete_features)]
@@ -31,6 +36,11 @@ fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 7777
3136
}
3237
}
3338

39+
fn overflow_more(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 239] {
40+
unsafe { std::mem::transmute(v) } //~ ERROR cannot transmute between types of different sizes
41+
}
42+
43+
3444
fn transpose<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
3545
unsafe {
3646
std::mem::transmute(v)
+26-17
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: the constant `W` is not of type `usize`
2-
--> $DIR/transmute-fail.rs:12:42
2+
--> $DIR/transmute-fail.rs:17:42
33
|
44
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
55
| ^^^^^^^^^^^^^ expected `usize`, found `bool`
66

77
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
8-
--> $DIR/transmute-fail.rs:7:9
8+
--> $DIR/transmute-fail.rs:12:9
99
|
1010
LL | std::mem::transmute(v)
1111
| ^^^^^^^^^^^^^^^^^^^
@@ -14,13 +14,13 @@ LL | std::mem::transmute(v)
1414
= note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1])
1515

1616
error: the constant `W` is not of type `usize`
17-
--> $DIR/transmute-fail.rs:15:9
17+
--> $DIR/transmute-fail.rs:20:9
1818
|
1919
LL | std::mem::transmute(v)
2020
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`
2121

2222
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
23-
--> $DIR/transmute-fail.rs:22:9
23+
--> $DIR/transmute-fail.rs:27:9
2424
|
2525
LL | std::mem::transmute(v)
2626
| ^^^^^^^^^^^^^^^^^^^
@@ -29,16 +29,25 @@ LL | std::mem::transmute(v)
2929
= note: target type: `[u32; W * H * H]` (this type does not have a fixed size)
3030

3131
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
32-
--> $DIR/transmute-fail.rs:29:9
32+
--> $DIR/transmute-fail.rs:34:9
3333
|
3434
LL | std::mem::transmute(v)
3535
| ^^^^^^^^^^^^^^^^^^^
3636
|
37-
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[u32; 8888888]; 9999999]` are too big for the current architecture)
38-
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
37+
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type $REALLY_TOO_BIG are too big for the current architecture)
38+
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type $REALLY_TOO_BIG are too big for the current architecture)
3939

4040
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
41-
--> $DIR/transmute-fail.rs:36:9
41+
--> $DIR/transmute-fail.rs:40:14
42+
|
43+
LL | unsafe { std::mem::transmute(v) }
44+
| ^^^^^^^^^^^^^^^^^^^
45+
|
46+
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type $REALLY_TOO_BIG are too big for the current architecture)
47+
= note: target type: `[[[u32; 9999999]; 777777777]; 239]` (values of the type $REALLY_TOO_BIG are too big for the current architecture)
48+
49+
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
50+
--> $DIR/transmute-fail.rs:46:9
4251
|
4352
LL | std::mem::transmute(v)
4453
| ^^^^^^^^^^^^^^^^^^^
@@ -47,7 +56,7 @@ LL | std::mem::transmute(v)
4756
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
4857

4958
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
50-
--> $DIR/transmute-fail.rs:47:9
59+
--> $DIR/transmute-fail.rs:57:9
5160
|
5261
LL | std::mem::transmute(v)
5362
| ^^^^^^^^^^^^^^^^^^^
@@ -56,7 +65,7 @@ LL | std::mem::transmute(v)
5665
= note: target type: `[u32; W * H]` (this type does not have a fixed size)
5766

5867
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
59-
--> $DIR/transmute-fail.rs:54:9
68+
--> $DIR/transmute-fail.rs:64:9
6069
|
6170
LL | std::mem::transmute(v)
6271
| ^^^^^^^^^^^^^^^^^^^
@@ -65,7 +74,7 @@ LL | std::mem::transmute(v)
6574
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
6675

6776
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
68-
--> $DIR/transmute-fail.rs:63:9
77+
--> $DIR/transmute-fail.rs:73:9
6978
|
7079
LL | std::mem::transmute(v)
7180
| ^^^^^^^^^^^^^^^^^^^
@@ -74,7 +83,7 @@ LL | std::mem::transmute(v)
7483
= note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
7584

7685
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
77-
--> $DIR/transmute-fail.rs:72:9
86+
--> $DIR/transmute-fail.rs:82:9
7887
|
7988
LL | std::mem::transmute(v)
8089
| ^^^^^^^^^^^^^^^^^^^
@@ -83,7 +92,7 @@ LL | std::mem::transmute(v)
8392
= note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W])
8493

8594
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
86-
--> $DIR/transmute-fail.rs:79:9
95+
--> $DIR/transmute-fail.rs:89:9
8796
|
8897
LL | std::mem::transmute(v)
8998
| ^^^^^^^^^^^^^^^^^^^
@@ -92,7 +101,7 @@ LL | std::mem::transmute(v)
92101
= note: target type: `[u8; L * 2]` (this type does not have a fixed size)
93102

94103
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
95-
--> $DIR/transmute-fail.rs:86:9
104+
--> $DIR/transmute-fail.rs:96:9
96105
|
97106
LL | std::mem::transmute(v)
98107
| ^^^^^^^^^^^^^^^^^^^
@@ -101,7 +110,7 @@ LL | std::mem::transmute(v)
101110
= note: target type: `[u16; L]` (this type does not have a fixed size)
102111

103112
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
104-
--> $DIR/transmute-fail.rs:93:9
113+
--> $DIR/transmute-fail.rs:103:9
105114
|
106115
LL | std::mem::transmute(v)
107116
| ^^^^^^^^^^^^^^^^^^^
@@ -110,14 +119,14 @@ LL | std::mem::transmute(v)
110119
= note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
111120

112121
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
113-
--> $DIR/transmute-fail.rs:102:9
122+
--> $DIR/transmute-fail.rs:112:9
114123
|
115124
LL | std::mem::transmute(v)
116125
| ^^^^^^^^^^^^^^^^^^^
117126
|
118127
= note: source type: `[[u32; 2 * H]; W + W]` (size can vary because of [u32; 2 * H])
119128
= note: target type: `[[u32; W + W]; 2 * H]` (size can vary because of [u32; W + W])
120129

121-
error: aborting due to 14 previous errors
130+
error: aborting due to 15 previous errors
122131

123132
For more information about this error, try `rustc --explain E0512`.

tests/ui/extern/extern-static-size-overflow.rs

+6-24
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,13 @@ struct ReallyBig {
44
}
55

66
// The limit for "too big for the current architecture" is dependent on the target pointer size
7-
// however it's artificially limited on 64 bits
8-
// logic copied from rustc_target::abi::TargetDataLayout::obj_size_bound()
7+
// but is artificially limited due to LLVM's internal architecture
8+
// logic based on rustc_target::abi::TargetDataLayout::obj_size_bound()
99
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
10+
if usize::BITS < 61 {
11+
1 << (usize::BITS - 1)
12+
} else {
13+
1 << 61
3214
}
3315
}
3416

tests/ui/extern/extern-static-size-overflow.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error: extern static is too large for the current architecture
2-
--> $DIR/extern-static-size-overflow.rs:38:5
2+
--> $DIR/extern-static-size-overflow.rs:20:5
33
|
44
LL | static BAZ: [u8; max_size()];
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

77
error: extern static is too large for the current architecture
8-
--> $DIR/extern-static-size-overflow.rs:39:5
8+
--> $DIR/extern-static-size-overflow.rs:21:5
99
|
1010
LL | static UWU: [usize; usize::MAX];
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: extern static is too large for the current architecture
14-
--> $DIR/extern-static-size-overflow.rs:40:5
14+
--> $DIR/extern-static-size-overflow.rs:22:5
1515
|
1616
LL | static A: ReallyBig;
1717
| ^^^^^^^^^^^^^^^^^^^

tests/ui/limits/huge-enum.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
type BIG = Option<[u32; (1<<29)-1]>;
77

88
#[cfg(target_pointer_width = "64")]
9-
type BIG = Option<[u32; (1<<45)-1]>;
9+
type BIG = Option<[u32; (1<<59)-1]>;
1010

1111
fn main() {
1212
let big: BIG = None;

tests/ui/limits/issue-56762.rs tests/ui/limits/huge-static.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
//@ only-x86_64
1+
//@ only-64bit
22

3-
const HUGE_SIZE: usize = !0usize / 8;
3+
// This test validates we gracefully fail computing a const or static of absurdly large size.
4+
// The oddly-specific number is because of LLVM measuring object sizes in bits.
5+
6+
const HUGE_SIZE: usize = 1 << 61;
47

58

69
pub struct TooBigArray {

tests/ui/limits/issue-56762.stderr tests/ui/limits/huge-static.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0080]: could not evaluate static initializer
2-
--> $DIR/issue-56762.rs:16:1
2+
--> $DIR/huge-static.rs:19:1
33
|
44
LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693952]` are too big for the current architecture
66

77
error[E0080]: could not evaluate static initializer
8-
--> $DIR/issue-56762.rs:19:1
8+
--> $DIR/huge-static.rs:22:1
99
|
1010
LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693952]` are too big for the current architecture
1212

1313
error: aborting due to 2 previous errors
1414

tests/ui/limits/huge-struct.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
// ignore-tidy-linelength
12
//@ build-fail
23
//@ normalize-stderr-test: "S32" -> "SXX"
34
//@ normalize-stderr-test: "S1M" -> "SXX"
4-
//@ error-pattern: too big for the current
5+
//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
6+
//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
57

68
struct S32<T> {
79
v0: T,

tests/ui/limits/huge-struct.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error: values of the type `SXX<SXX<SXX<u32>>>` are too big for the current architecture
2-
--> $DIR/huge-struct.rs:46:9
1+
error: values of the type $REALLY_TOO_BIG are too big for the current architecture
2+
--> $DIR/huge-struct.rs:48:9
33
|
44
LL | let fat: Option<SXX<SXX<SXX<u32>>>> = None;
55
| ^^^

0 commit comments

Comments
 (0)