Auto merge of #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 #49492. Fixes #49492. r? @rkruppe
This commit is contained in:
commit
427c548749
@ -326,9 +326,9 @@ impl AddAssign for Size {
|
||||
}
|
||||
|
||||
/// Alignment of a type in bytes, both ABI-mandated and preferred.
|
||||
/// Each field is a power of two, giving the alignment a maximum value of
|
||||
/// 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a i32,
|
||||
/// with a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
|
||||
/// Each field is a power of two, giving the alignment a maximum value
|
||||
/// of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a
|
||||
/// maximum capacity of 2<sup>29</sup> or 536870912.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct Align {
|
||||
abi_pow2: u8,
|
||||
@ -356,7 +356,7 @@ impl Align {
|
||||
}
|
||||
if bytes != 1 {
|
||||
Err(format!("`{}` is not a power of 2", align))
|
||||
} else if pow > 30 {
|
||||
} else if pow > 29 {
|
||||
Err(format!("`{}` is too large", align))
|
||||
} else {
|
||||
Ok(pow)
|
||||
|
@ -1012,11 +1012,11 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
|
||||
let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
|
||||
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
|
||||
if literal.is_power_of_two() {
|
||||
// rustc::ty::layout::Align restricts align to <= 2147483647
|
||||
if *literal <= 2147483647 {
|
||||
// rustc::ty::layout::Align restricts align to <= 2^29
|
||||
if *literal <= 1 << 29 {
|
||||
Ok(*literal as u32)
|
||||
} else {
|
||||
Err("larger than 2147483647")
|
||||
Err("larger than 2^29")
|
||||
}
|
||||
} else {
|
||||
Err("not a power of two")
|
||||
|
@ -244,6 +244,18 @@ fn main() {
|
||||
```
|
||||
"##,
|
||||
|
||||
E0589: r##"
|
||||
The value of `N` that was specified for `repr(align(N))` was not a power
|
||||
of two, or was greater than 2^29.
|
||||
|
||||
```compile_fail,E0589
|
||||
#[repr(align(15))] // error: invalid `repr(align)` attribute: not a power of two
|
||||
enum Foo {
|
||||
Bar(u64),
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0658: r##"
|
||||
An unstable feature was used.
|
||||
|
||||
@ -321,7 +333,6 @@ register_diagnostics! {
|
||||
E0555, // malformed feature attribute, expected #![feature(...)]
|
||||
E0556, // malformed feature, expected just one word
|
||||
E0584, // file for module `..` found at both .. and ..
|
||||
E0589, // invalid `repr(align)` attribute
|
||||
E0629, // missing 'feature' (rustc_const_unstable)
|
||||
E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
|
||||
E0693, // incorrect `repr(align)` attribute format
|
||||
|
@ -15,7 +15,10 @@ struct A(i32);
|
||||
#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
|
||||
struct B(i32);
|
||||
|
||||
#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2147483647
|
||||
#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29
|
||||
struct C(i32);
|
||||
|
||||
#[repr(align(536870912))] // ok: this is the largest accepted alignment
|
||||
struct D(i32);
|
||||
|
||||
fn main() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user