Skip to content

Commit

Permalink
Auto merge of rust-lang#127546 - workingjubilee:5-level-paging-exists…
Browse files Browse the repository at this point in the history
…, 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
  • Loading branch information
bors committed Sep 20, 2024
2 parents 506f22b + 8431855 commit cfa946e
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 82 deletions.
10 changes: 4 additions & 6 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,23 +337,21 @@ impl TargetDataLayout {
Ok(dl)
}

/// Returns exclusive upper bound on object size.
/// Returns **exclusive** upper bound on object size.
///
/// The theoretical maximum object size is defined as the maximum positive `isize` value.
/// This ensures that the `offset` semantics remain well-defined by allowing it to correctly
/// index every address within an object along with one byte past the end, along with allowing
/// `isize` to store the difference between any two pointers into an object.
///
/// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer
/// to represent object size in bits. It would need to be 1 << 61 to account for this, but is
/// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
/// address space on 64-bit ARMv8 and x86_64.
/// LLVM uses a 64-bit integer to represent object size in bits, but we care only for bytes,
/// so we adopt such a more-constrained address space due to its technical limitations.
#[inline]
pub fn obj_size_bound(&self) -> u64 {
match self.pointer_size.bits() {
16 => 1 << 15,
32 => 1 << 31,
64 => 1 << 47,
64 => 1 << 61,
bits => panic!("obj_size_bound: unknown pointer bit size {bits}"),
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,6 @@ ui/const-generics/infer/issue-77092.rs
ui/const-generics/issue-102124.rs
ui/const-generics/issue-105689.rs
ui/const-generics/issue-106419-struct-with-multiple-const-params.rs
ui/const-generics/issue-112505-overflow.rs
ui/const-generics/issue-46511.rs
ui/const-generics/issue-66451.rs
ui/const-generics/issue-70408.rs
Expand Down Expand Up @@ -2718,7 +2717,6 @@ ui/limits/issue-15919-32.rs
ui/limits/issue-15919-64.rs
ui/limits/issue-17913.rs
ui/limits/issue-55878.rs
ui/limits/issue-56762.rs
ui/limits/issue-69485-var-size-diffs-too-large.rs
ui/limits/issue-75158-64.rs
ui/linkage-attr/auxiliary/issue-12133-dylib.rs
Expand Down
2 changes: 1 addition & 1 deletion tests/crashes/125476.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ known-bug: rust-lang/rust#125476
//@ only-x86_64
pub struct Data([u8; usize::MAX >> 16]);
pub struct Data([u8; usize::MAX >> 2]);
const _: &'static [Data] = &[];
7 changes: 0 additions & 7 deletions tests/ui/const-generics/issue-112505-overflow.rs

This file was deleted.

12 changes: 0 additions & 12 deletions tests/ui/const-generics/issue-112505-overflow.stderr

This file was deleted.

10 changes: 10 additions & 0 deletions tests/ui/const-generics/transmute-fail.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// ignore-tidy-linelength
//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"


#![feature(transmute_generic_consts)]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
Expand Down Expand Up @@ -31,6 +36,11 @@ fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 7777
}
}

fn overflow_more(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 239] {
unsafe { std::mem::transmute(v) } //~ ERROR cannot transmute between types of different sizes
}


fn transpose<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
unsafe {
std::mem::transmute(v)
Expand Down
43 changes: 26 additions & 17 deletions tests/ui/const-generics/transmute-fail.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error: the constant `W` is not of type `usize`
--> $DIR/transmute-fail.rs:12:42
--> $DIR/transmute-fail.rs:17:42
|
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
| ^^^^^^^^^^^^^ expected `usize`, found `bool`

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

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

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

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

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/transmute-fail.rs:36:9
--> $DIR/transmute-fail.rs:40:14
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type $REALLY_TOO_BIG are too big for the current architecture)
= note: target type: `[[[u32; 9999999]; 777777777]; 239]` (values of the type $REALLY_TOO_BIG are too big for the current architecture)

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/transmute-fail.rs:46:9
|
LL | std::mem::transmute(v)
| ^^^^^^^^^^^^^^^^^^^
Expand All @@ -47,7 +56,7 @@ LL | std::mem::transmute(v)
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])

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

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

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

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

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

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

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

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

error: aborting due to 14 previous errors
error: aborting due to 15 previous errors

For more information about this error, try `rustc --explain E0512`.
30 changes: 6 additions & 24 deletions tests/ui/extern/extern-static-size-overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,13 @@ struct ReallyBig {
}

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

Expand Down
6 changes: 3 additions & 3 deletions tests/ui/extern/extern-static-size-overflow.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error: extern static is too large for the current architecture
--> $DIR/extern-static-size-overflow.rs:38:5
--> $DIR/extern-static-size-overflow.rs:20: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
--> $DIR/extern-static-size-overflow.rs:21: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
--> $DIR/extern-static-size-overflow.rs:22:5
|
LL | static A: ReallyBig;
| ^^^^^^^^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/limits/huge-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
type BIG = Option<[u32; (1<<29)-1]>;

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

fn main() {
let big: BIG = None;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//@ only-x86_64
//@ only-64bit

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

const HUGE_SIZE: usize = 1 << 61;


pub struct TooBigArray {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error[E0080]: could not evaluate static initializer
--> $DIR/issue-56762.rs:16:1
--> $DIR/huge-static.rs:19:1
|
LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693952]` are too big for the current architecture

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

error: aborting due to 2 previous errors

Expand Down
4 changes: 3 additions & 1 deletion tests/ui/limits/huge-struct.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// ignore-tidy-linelength
//@ build-fail
//@ normalize-stderr-test: "S32" -> "SXX"
//@ normalize-stderr-test: "S1M" -> "SXX"
//@ error-pattern: too big for the current
//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"
//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big"

struct S32<T> {
v0: T,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/limits/huge-struct.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: values of the type `SXX<SXX<SXX<u32>>>` are too big for the current architecture
--> $DIR/huge-struct.rs:46:9
error: values of the type $REALLY_TOO_BIG are too big for the current architecture
--> $DIR/huge-struct.rs:48:9
|
LL | let fat: Option<SXX<SXX<SXX<u32>>>> = None;
| ^^^
Expand Down

0 comments on commit cfa946e

Please sign in to comment.