Skip to content

Commit 427c548

Browse files
committed
Auto merge of rust-lang#50378 - varkor:repr-align-max-29, r=eddyb
Reduce maximum repr(align(N)) to 2^29 The current maximum `repr(align(N))` alignment is larger than the maximum alignment accepted by LLVM, which can cause issues for huge values of `N`, as seen in rust-lang#49492. Fixes rust-lang#49492. r? @rkruppe
2 parents 9e3cbbb + cd2f5f7 commit 427c548

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

src/librustc_target/abi/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl AddAssign for Size {
326326
}
327327

328328
/// Alignment of a type in bytes, both ABI-mandated and preferred.
329-
/// Each field is a power of two, giving the alignment a maximum value of
330-
/// 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a i32,
331-
/// with a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
329+
/// Each field is a power of two, giving the alignment a maximum value
330+
/// of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a
331+
/// maximum capacity of 2<sup>29</sup> or 536870912.
332332
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
333333
pub struct Align {
334334
abi_pow2: u8,
@@ -356,7 +356,7 @@ impl Align {
356356
}
357357
if bytes != 1 {
358358
Err(format!("`{}` is not a power of 2", align))
359-
} else if pow > 30 {
359+
} else if pow > 29 {
360360
Err(format!("`{}` is too large", align))
361361
} else {
362362
Ok(pow)

src/libsyntax/attr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1012,11 +1012,11 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
10121012
let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
10131013
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
10141014
if literal.is_power_of_two() {
1015-
// rustc::ty::layout::Align restricts align to <= 2147483647
1016-
if *literal <= 2147483647 {
1015+
// rustc::ty::layout::Align restricts align to <= 2^29
1016+
if *literal <= 1 << 29 {
10171017
Ok(*literal as u32)
10181018
} else {
1019-
Err("larger than 2147483647")
1019+
Err("larger than 2^29")
10201020
}
10211021
} else {
10221022
Err("not a power of two")

src/libsyntax/diagnostic_list.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@ fn main() {
244244
```
245245
"##,
246246

247+
E0589: r##"
248+
The value of `N` that was specified for `repr(align(N))` was not a power
249+
of two, or was greater than 2^29.
250+
251+
```compile_fail,E0589
252+
#[repr(align(15))] // error: invalid `repr(align)` attribute: not a power of two
253+
enum Foo {
254+
Bar(u64),
255+
}
256+
```
257+
"##,
258+
247259
E0658: r##"
248260
An unstable feature was used.
249261
@@ -321,7 +333,6 @@ register_diagnostics! {
321333
E0555, // malformed feature attribute, expected #![feature(...)]
322334
E0556, // malformed feature, expected just one word
323335
E0584, // file for module `..` found at both .. and ..
324-
E0589, // invalid `repr(align)` attribute
325336
E0629, // missing 'feature' (rustc_const_unstable)
326337
E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
327338
E0693, // incorrect `repr(align)` attribute format

src/test/compile-fail/repr-align.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ struct A(i32);
1515
#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
1616
struct B(i32);
1717

18-
#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2147483647
18+
#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29
1919
struct C(i32);
2020

21+
#[repr(align(536870912))] // ok: this is the largest accepted alignment
22+
struct D(i32);
23+
2124
fn main() {}

0 commit comments

Comments
 (0)