about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLee Bousfield <ljbousfield@gmail.com>2017-07-08 10:28:20 -0400
committerLee Bousfield <ljbousfield@gmail.com>2017-07-08 10:28:56 -0400
commitafed75a2d9b7e049dc26be7af3cb72297274d343 (patch)
tree2b3e04c0d249821ae26a710621b515297f46a615
parenta10213f297be8e231f55fd6db843674a8f512140 (diff)
downloadrust-afed75a2d9b7e049dc26be7af3cb72297274d343.tar.gz
rust-afed75a2d9b7e049dc26be7af3cb72297274d343.zip
Lower alignment limit down to 2^31 - 1 (from LLVM)
-rw-r--r--src/librustc/ty/layout.rs10
-rw-r--r--src/libsyntax/attr.rs6
-rw-r--r--src/test/compile-fail/repr-align.rs2
3 files changed, 10 insertions, 8 deletions
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 90468d92a50..6fb26f0dd6d 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -285,7 +285,9 @@ impl Size {
 }
 
 /// Alignment of a type in bytes, both ABI-mandated and preferred.
-/// Each field is a power of two.
+/// Each field is a power of two, giving the alignment a maximum
+/// value of 2^(2^8 - 1), which is limited by LLVM to a i32, with
+/// a maximum capacity of 2^31 - 1 or 2147483647.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct Align {
     abi: u8,
@@ -298,7 +300,7 @@ impl Align {
     }
 
     pub fn from_bytes(abi: u64, pref: u64) -> Result<Align, String> {
-        let pack = |align: u64| {
+        let log2 = |align: u64| {
             // Treat an alignment of 0 bytes like 1-byte alignment.
             if align == 0 {
                 return Ok(0);
@@ -318,8 +320,8 @@ impl Align {
         };
 
         Ok(Align {
-            abi: pack(abi)?,
-            pref: pack(pref)?,
+            abi: log2(abi)?,
+            pref: log2(pref)?,
         })
     }
 
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 45c106f2a7f..a247fe7f8a5 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -974,11 +974,11 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
                         let mut align_error = None;
                         if let ast::LitKind::Int(align, ast::LitIntType::Unsuffixed) = value.node {
                             if align.is_power_of_two() {
-                                // rustc::ty::layout::Align restricts align to <= 2147483648
-                                if align <= 2147483648 {
+                                // rustc::ty::layout::Align restricts align to <= 2147483647
+                                if align <= 2147483647 {
                                     acc.push(ReprAlign(align as u32));
                                 } else {
-                                    align_error = Some("larger than 2147483648");
+                                    align_error = Some("larger than 2147483647");
                                 }
                             } else {
                                 align_error = Some("not a power of two");
diff --git a/src/test/compile-fail/repr-align.rs b/src/test/compile-fail/repr-align.rs
index 433abe943f5..bc9cf065e5a 100644
--- a/src/test/compile-fail/repr-align.rs
+++ b/src/test/compile-fail/repr-align.rs
@@ -17,7 +17,7 @@ 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 2147483648
+#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2147483647
 struct C(i32);
 
 fn main() {}