about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-01 03:16:45 +0000
committerbors <bors@rust-lang.org>2024-04-01 03:16:45 +0000
commitdefef8658e8f740cc8d2818b5b96441071e9a7a6 (patch)
treed83fa1b9a04bc318756c11d60243d39ddb487bf2
parent66de6111960571ab7b030c205b6176801c7ecbfc (diff)
parent6e5f1dacf3a670cf03111039a032c765355839aa (diff)
downloadrust-defef8658e8f740cc8d2818b5b96441071e9a7a6.tar.gz
rust-defef8658e8f740cc8d2818b5b96441071e9a7a6.zip
Auto merge of #122972 - beetrees:use-align-type, r=fee1-dead
Use the `Align` type when parsing alignment attributes

Use the `Align` type in `rustc_attr::parse_alignment`, removing the need to call `Align::from_bytes(...).unwrap()` later in the compilation process.
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_abi/src/lib.rs7
-rw-r--r--compiler/rustc_attr/Cargo.toml1
-rw-r--r--compiler/rustc_attr/src/builtin.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs3
-rw-r--r--tests/ui/repr/repr-align.rs8
-rw-r--r--tests/ui/repr/repr-align.stderr42
12 files changed, 74 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6168a0a1747..a10eccb1ce5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3569,6 +3569,7 @@ dependencies = [
 name = "rustc_attr"
 version = "0.0.0"
 dependencies = [
+ "rustc_abi",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 4f2b9d0ef50..7439af7aed3 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -698,6 +698,7 @@ impl fmt::Display for AlignFromBytesError {
 
 impl Align {
     pub const ONE: Align = Align { pow2: 0 };
+    pub const EIGHT: Align = Align { pow2: 3 };
     // LLVM has a maximal supported alignment of 2^29, we inherit that.
     pub const MAX: Align = Align { pow2: 29 };
 
@@ -707,19 +708,19 @@ impl Align {
     }
 
     #[inline]
-    pub fn from_bytes(align: u64) -> Result<Align, AlignFromBytesError> {
+    pub const fn from_bytes(align: u64) -> Result<Align, AlignFromBytesError> {
         // Treat an alignment of 0 bytes like 1-byte alignment.
         if align == 0 {
             return Ok(Align::ONE);
         }
 
         #[cold]
-        fn not_power_of_2(align: u64) -> AlignFromBytesError {
+        const fn not_power_of_2(align: u64) -> AlignFromBytesError {
             AlignFromBytesError::NotPowerOfTwo(align)
         }
 
         #[cold]
-        fn too_large(align: u64) -> AlignFromBytesError {
+        const fn too_large(align: u64) -> AlignFromBytesError {
             AlignFromBytesError::TooLarge(align)
         }
 
diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml
index d33416d2003..3b24452450a 100644
--- a/compiler/rustc_attr/Cargo.toml
+++ b/compiler/rustc_attr/Cargo.toml
@@ -5,6 +5,7 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
+rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 814104ec78c..439f13e7635 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -1,5 +1,6 @@
 //! Parsing and validation of builtin attributes
 
+use rustc_abi::Align;
 use rustc_ast::{self as ast, attr};
 use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
 use rustc_ast_pretty::pprust;
@@ -919,10 +920,10 @@ pub enum ReprAttr {
     ReprInt(IntType),
     ReprRust,
     ReprC,
-    ReprPacked(u32),
+    ReprPacked(Align),
     ReprSimd,
     ReprTransparent,
-    ReprAlign(u32),
+    ReprAlign(Align),
 }
 
 #[derive(Eq, PartialEq, Debug, Copy, Clone)]
@@ -968,7 +969,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
                 let hint = match item.name_or_empty() {
                     sym::Rust => Some(ReprRust),
                     sym::C => Some(ReprC),
-                    sym::packed => Some(ReprPacked(1)),
+                    sym::packed => Some(ReprPacked(Align::ONE)),
                     sym::simd => Some(ReprSimd),
                     sym::transparent => Some(ReprTransparent),
                     sym::align => {
@@ -1209,11 +1210,17 @@ fn allow_unstable<'a>(
     })
 }
 
-pub fn parse_alignment(node: &ast::LitKind) -> Result<u32, &'static str> {
+pub fn parse_alignment(node: &ast::LitKind) -> Result<Align, &'static str> {
     if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
+        // `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first
         if literal.get().is_power_of_two() {
-            // rustc_middle::ty::layout::Align restricts align to <= 2^29
-            if *literal <= 1 << 29 { Ok(literal.get() as u32) } else { Err("larger than 2^29") }
+            // Only possible error is larger than 2^29
+            literal
+                .get()
+                .try_into()
+                .ok()
+                .and_then(|v| Align::from_bytes(v).ok())
+                .ok_or("larger than 2^29")
         } else {
             Err("not a power of two")
         }
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index f9eaa0d94cb..870e5ab3296 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -417,7 +417,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
         to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"));
     }
     if let Some(align) = codegen_fn_attrs.alignment {
-        llvm::set_alignment(llfn, align as usize);
+        llvm::set_alignment(llfn, align);
     }
     to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 85277db6d53..68c1770c1d4 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -16,6 +16,7 @@ use rustc_middle::bug;
 use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::Instance;
+use rustc_target::abi::Align;
 
 use std::cell::RefCell;
 
@@ -23,7 +24,7 @@ pub(crate) mod ffi;
 pub(crate) mod map_data;
 pub mod mapgen;
 
-const VAR_ALIGN_BYTES: usize = 8;
+const VAR_ALIGN: Align = Align::EIGHT;
 
 /// A context object for maintaining all state needed by the coverageinfo module.
 pub struct CrateCoverageContext<'ll, 'tcx> {
@@ -225,7 +226,7 @@ pub(crate) fn save_cov_data_to_mod<'ll, 'tcx>(
     llvm::set_global_constant(llglobal, true);
     llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
     llvm::set_section(llglobal, &covmap_section_name);
-    llvm::set_alignment(llglobal, VAR_ALIGN_BYTES);
+    llvm::set_alignment(llglobal, VAR_ALIGN);
     cx.add_used_global(llglobal);
 }
 
@@ -255,7 +256,7 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
     llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
     llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
     llvm::set_section(llglobal, covfun_section_name);
-    llvm::set_alignment(llglobal, VAR_ALIGN_BYTES);
+    llvm::set_alignment(llglobal, VAR_ALIGN);
     llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
     cx.add_used_global(llglobal);
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index 4f5cc575da6..6ab1eea9597 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -11,6 +11,7 @@ pub use self::RealPredicate::*;
 use libc::c_uint;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_llvm::RustString;
+use rustc_target::abi::Align;
 use std::cell::RefCell;
 use std::ffi::{CStr, CString};
 use std::str::FromStr;
@@ -229,9 +230,9 @@ pub fn set_visibility(llglobal: &Value, visibility: Visibility) {
     }
 }
 
-pub fn set_alignment(llglobal: &Value, bytes: usize) {
+pub fn set_alignment(llglobal: &Value, align: Align) {
     unsafe {
-        ffi::LLVMSetAlignment(llglobal, bytes as c_uint);
+        ffi::LLVMSetAlignment(llglobal, align.bytes() as c_uint);
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 1286a724e95..a880445a27c 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -964,7 +964,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
             for r in attr::parse_repr_attr(tcx.sess, attr) {
                 if let attr::ReprPacked(pack) = r
                     && let Some(repr_pack) = repr.pack
-                    && pack as u64 != repr_pack.bytes()
+                    && pack != repr_pack
                 {
                     struct_span_code_err!(
                         tcx.dcx(),
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 7d6d39a2a8a..ec9697bbd35 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -1,6 +1,7 @@
 use crate::mir::mono::Linkage;
 use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_span::symbol::Symbol;
+use rustc_target::abi::Align;
 use rustc_target::spec::SanitizerSet;
 
 #[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)]
@@ -42,7 +43,7 @@ pub struct CodegenFnAttrs {
     pub instruction_set: Option<InstructionSetAttr>,
     /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be
     /// aligned to.
-    pub alignment: Option<u32>,
+    pub alignment: Option<Align>,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 99da981b9d6..ef7626a054f 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1552,7 +1552,6 @@ impl<'tcx> TyCtxt<'tcx> {
                     attr::ReprRust => ReprFlags::empty(),
                     attr::ReprC => ReprFlags::IS_C,
                     attr::ReprPacked(pack) => {
-                        let pack = Align::from_bytes(pack as u64).unwrap();
                         min_pack = Some(if let Some(min_pack) = min_pack {
                             min_pack.min(pack)
                         } else {
@@ -1584,7 +1583,7 @@ impl<'tcx> TyCtxt<'tcx> {
                         ReprFlags::empty()
                     }
                     attr::ReprAlign(align) => {
-                        max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap()));
+                        max_align = max_align.max(Some(align));
                         ReprFlags::empty()
                     }
                 });
diff --git a/tests/ui/repr/repr-align.rs b/tests/ui/repr/repr-align.rs
index 58ecf9a5183..33aa727d4bd 100644
--- a/tests/ui/repr/repr-align.rs
+++ b/tests/ui/repr/repr-align.rs
@@ -15,6 +15,10 @@ struct S2(i32);
 #[repr(align(536870912))] // ok: this is the largest accepted alignment
 struct S3(i32);
 
+#[repr(align(0))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
+                  //~| ERROR: invalid `repr(align)` attribute: not a power of two
+struct S4(i32);
+
 #[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer
                      //~| ERROR: invalid `repr(align)` attribute: not an unsuffixed integer
 enum E0 { A, B }
@@ -30,4 +34,8 @@ enum E2 { A, B }
 #[repr(align(536870912))] // ok: this is the largest accepted alignment
 enum E3 { A, B }
 
+#[repr(align(0))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
+                  //~| ERROR: invalid `repr(align)` attribute: not a power of two
+enum E4 { A, B }
+
 fn main() {}
diff --git a/tests/ui/repr/repr-align.stderr b/tests/ui/repr/repr-align.stderr
index bb0e17ba395..660247840c4 100644
--- a/tests/ui/repr/repr-align.stderr
+++ b/tests/ui/repr/repr-align.stderr
@@ -16,24 +16,36 @@ error[E0589]: invalid `repr(align)` attribute: larger than 2^29
 LL | #[repr(align(4294967296))]
    |              ^^^^^^^^^^
 
-error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
+error[E0589]: invalid `repr(align)` attribute: not a power of two
   --> $DIR/repr-align.rs:18:14
    |
+LL | #[repr(align(0))]
+   |              ^
+
+error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
+  --> $DIR/repr-align.rs:22:14
+   |
 LL | #[repr(align(16.0))]
    |              ^^^^
 
 error[E0589]: invalid `repr(align)` attribute: not a power of two
-  --> $DIR/repr-align.rs:22:14
+  --> $DIR/repr-align.rs:26:14
    |
 LL | #[repr(align(15))]
    |              ^^
 
 error[E0589]: invalid `repr(align)` attribute: larger than 2^29
-  --> $DIR/repr-align.rs:26:14
+  --> $DIR/repr-align.rs:30:14
    |
 LL | #[repr(align(4294967296))]
    |              ^^^^^^^^^^
 
+error[E0589]: invalid `repr(align)` attribute: not a power of two
+  --> $DIR/repr-align.rs:37:14
+   |
+LL | #[repr(align(0))]
+   |              ^
+
 error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
   --> $DIR/repr-align.rs:3:14
    |
@@ -58,16 +70,24 @@ LL | #[repr(align(4294967296))]
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
+error[E0589]: invalid `repr(align)` attribute: not a power of two
   --> $DIR/repr-align.rs:18:14
    |
+LL | #[repr(align(0))]
+   |              ^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
+  --> $DIR/repr-align.rs:22:14
+   |
 LL | #[repr(align(16.0))]
    |              ^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: not a power of two
-  --> $DIR/repr-align.rs:22:14
+  --> $DIR/repr-align.rs:26:14
    |
 LL | #[repr(align(15))]
    |              ^^
@@ -75,13 +95,21 @@ LL | #[repr(align(15))]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0589]: invalid `repr(align)` attribute: larger than 2^29
-  --> $DIR/repr-align.rs:26:14
+  --> $DIR/repr-align.rs:30:14
    |
 LL | #[repr(align(4294967296))]
    |              ^^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 12 previous errors
+error[E0589]: invalid `repr(align)` attribute: not a power of two
+  --> $DIR/repr-align.rs:37:14
+   |
+LL | #[repr(align(0))]
+   |              ^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 16 previous errors
 
 For more information about this error, try `rustc --explain E0589`.