about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-03 05:38:11 +0000
committerbors <bors@rust-lang.org>2018-05-03 05:38:11 +0000
commit427c5487493fbd5e96e81b7d3ba54784e0805df7 (patch)
tree6183280d82aae03bb9f5129ff3c4774ce3b7de60
parent9e3cbbb60a2a00a5fcce8c150c3e8fe5f3209e26 (diff)
parentcd2f5f7d977936c409f4bec28075c8918e239f4c (diff)
downloadrust-427c5487493fbd5e96e81b7d3ba54784e0805df7.tar.gz
rust-427c5487493fbd5e96e81b7d3ba54784e0805df7.zip
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
-rw-r--r--src/librustc_target/abi/mod.rs8
-rw-r--r--src/libsyntax/attr.rs6
-rw-r--r--src/libsyntax/diagnostic_list.rs13
-rw-r--r--src/test/compile-fail/repr-align.rs5
4 files changed, 23 insertions, 9 deletions
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index f73085196f4..fd1f779f9ec 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -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)
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index f0557277267..13f8bb9a318 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -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")
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index c9cac1b1142..d1f123f6f6c 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -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
diff --git a/src/test/compile-fail/repr-align.rs b/src/test/compile-fail/repr-align.rs
index 7c8eb6a2de9..9b0408de2a4 100644
--- a/src/test/compile-fail/repr-align.rs
+++ b/src/test/compile-fail/repr-align.rs
@@ -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() {}