Skip to content

Commit 6e5f1da

Browse files
committed
Use the Align type when parsing alignment attributes
1 parent 2f090c3 commit 6e5f1da

File tree

12 files changed

+74
-26
lines changed

12 files changed

+74
-26
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3560,6 +3560,7 @@ dependencies = [
35603560
name = "rustc_attr"
35613561
version = "0.0.0"
35623562
dependencies = [
3563+
"rustc_abi",
35633564
"rustc_ast",
35643565
"rustc_ast_pretty",
35653566
"rustc_data_structures",

compiler/rustc_abi/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ impl fmt::Display for AlignFromBytesError {
698698

699699
impl Align {
700700
pub const ONE: Align = Align { pow2: 0 };
701+
pub const EIGHT: Align = Align { pow2: 3 };
701702
// LLVM has a maximal supported alignment of 2^29, we inherit that.
702703
pub const MAX: Align = Align { pow2: 29 };
703704

@@ -707,19 +708,19 @@ impl Align {
707708
}
708709

709710
#[inline]
710-
pub fn from_bytes(align: u64) -> Result<Align, AlignFromBytesError> {
711+
pub const fn from_bytes(align: u64) -> Result<Align, AlignFromBytesError> {
711712
// Treat an alignment of 0 bytes like 1-byte alignment.
712713
if align == 0 {
713714
return Ok(Align::ONE);
714715
}
715716

716717
#[cold]
717-
fn not_power_of_2(align: u64) -> AlignFromBytesError {
718+
const fn not_power_of_2(align: u64) -> AlignFromBytesError {
718719
AlignFromBytesError::NotPowerOfTwo(align)
719720
}
720721

721722
#[cold]
722-
fn too_large(align: u64) -> AlignFromBytesError {
723+
const fn too_large(align: u64) -> AlignFromBytesError {
723724
AlignFromBytesError::TooLarge(align)
724725
}
725726

compiler/rustc_attr/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
# tidy-alphabetical-start
8+
rustc_abi = { path = "../rustc_abi" }
89
rustc_ast = { path = "../rustc_ast" }
910
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
1011
rustc_data_structures = { path = "../rustc_data_structures" }

compiler/rustc_attr/src/builtin.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Parsing and validation of builtin attributes
22
3+
use rustc_abi::Align;
34
use rustc_ast::{self as ast, attr};
45
use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
56
use rustc_ast_pretty::pprust;
@@ -919,10 +920,10 @@ pub enum ReprAttr {
919920
ReprInt(IntType),
920921
ReprRust,
921922
ReprC,
922-
ReprPacked(u32),
923+
ReprPacked(Align),
923924
ReprSimd,
924925
ReprTransparent,
925-
ReprAlign(u32),
926+
ReprAlign(Align),
926927
}
927928

928929
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
@@ -968,7 +969,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
968969
let hint = match item.name_or_empty() {
969970
sym::Rust => Some(ReprRust),
970971
sym::C => Some(ReprC),
971-
sym::packed => Some(ReprPacked(1)),
972+
sym::packed => Some(ReprPacked(Align::ONE)),
972973
sym::simd => Some(ReprSimd),
973974
sym::transparent => Some(ReprTransparent),
974975
sym::align => {
@@ -1209,11 +1210,17 @@ fn allow_unstable<'a>(
12091210
})
12101211
}
12111212

1212-
pub fn parse_alignment(node: &ast::LitKind) -> Result<u32, &'static str> {
1213+
pub fn parse_alignment(node: &ast::LitKind) -> Result<Align, &'static str> {
12131214
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
1215+
// `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first
12141216
if literal.get().is_power_of_two() {
1215-
// rustc_middle::ty::layout::Align restricts align to <= 2^29
1216-
if *literal <= 1 << 29 { Ok(literal.get() as u32) } else { Err("larger than 2^29") }
1217+
// Only possible error is larger than 2^29
1218+
literal
1219+
.get()
1220+
.try_into()
1221+
.ok()
1222+
.and_then(|v| Align::from_bytes(v).ok())
1223+
.ok_or("larger than 2^29")
12171224
} else {
12181225
Err("not a power of two")
12191226
}

compiler/rustc_codegen_llvm/src/attributes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
417417
to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"));
418418
}
419419
if let Some(align) = codegen_fn_attrs.alignment {
420-
llvm::set_alignment(llfn, align as usize);
420+
llvm::set_alignment(llfn, align);
421421
}
422422
to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
423423

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ use rustc_middle::mir::coverage::CoverageKind;
1717
use rustc_middle::mir::Coverage;
1818
use rustc_middle::ty::layout::HasTyCtxt;
1919
use rustc_middle::ty::Instance;
20+
use rustc_target::abi::Align;
2021

2122
use std::cell::RefCell;
2223

2324
pub(crate) mod ffi;
2425
pub(crate) mod map_data;
2526
pub mod mapgen;
2627

27-
const VAR_ALIGN_BYTES: usize = 8;
28+
const VAR_ALIGN: Align = Align::EIGHT;
2829

2930
/// A context object for maintaining all state needed by the coverageinfo module.
3031
pub struct CrateCoverageContext<'ll, 'tcx> {
@@ -227,7 +228,7 @@ pub(crate) fn save_cov_data_to_mod<'ll, 'tcx>(
227228
llvm::set_global_constant(llglobal, true);
228229
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
229230
llvm::set_section(llglobal, &covmap_section_name);
230-
llvm::set_alignment(llglobal, VAR_ALIGN_BYTES);
231+
llvm::set_alignment(llglobal, VAR_ALIGN);
231232
cx.add_used_global(llglobal);
232233
}
233234

@@ -257,7 +258,7 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
257258
llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
258259
llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
259260
llvm::set_section(llglobal, covfun_section_name);
260-
llvm::set_alignment(llglobal, VAR_ALIGN_BYTES);
261+
llvm::set_alignment(llglobal, VAR_ALIGN);
261262
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
262263
cx.add_used_global(llglobal);
263264
}

compiler/rustc_codegen_llvm/src/llvm/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub use self::RealPredicate::*;
1111
use libc::c_uint;
1212
use rustc_data_structures::small_c_str::SmallCStr;
1313
use rustc_llvm::RustString;
14+
use rustc_target::abi::Align;
1415
use std::cell::RefCell;
1516
use std::ffi::{CStr, CString};
1617
use std::str::FromStr;
@@ -229,9 +230,9 @@ pub fn set_visibility(llglobal: &Value, visibility: Visibility) {
229230
}
230231
}
231232

232-
pub fn set_alignment(llglobal: &Value, bytes: usize) {
233+
pub fn set_alignment(llglobal: &Value, align: Align) {
233234
unsafe {
234-
ffi::LLVMSetAlignment(llglobal, bytes as c_uint);
235+
ffi::LLVMSetAlignment(llglobal, align.bytes() as c_uint);
235236
}
236237
}
237238

compiler/rustc_hir_analysis/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
964964
for r in attr::parse_repr_attr(tcx.sess, attr) {
965965
if let attr::ReprPacked(pack) = r
966966
&& let Some(repr_pack) = repr.pack
967-
&& pack as u64 != repr_pack.bytes()
967+
&& pack != repr_pack
968968
{
969969
struct_span_code_err!(
970970
tcx.dcx(),

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::mir::mono::Linkage;
22
use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
33
use rustc_span::symbol::Symbol;
4+
use rustc_target::abi::Align;
45
use rustc_target::spec::SanitizerSet;
56

67
#[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)]
@@ -42,7 +43,7 @@ pub struct CodegenFnAttrs {
4243
pub instruction_set: Option<InstructionSetAttr>,
4344
/// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be
4445
/// aligned to.
45-
pub alignment: Option<u32>,
46+
pub alignment: Option<Align>,
4647
}
4748

4849
#[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]

compiler/rustc_middle/src/ty/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,6 @@ impl<'tcx> TyCtxt<'tcx> {
15231523
attr::ReprRust => ReprFlags::empty(),
15241524
attr::ReprC => ReprFlags::IS_C,
15251525
attr::ReprPacked(pack) => {
1526-
let pack = Align::from_bytes(pack as u64).unwrap();
15271526
min_pack = Some(if let Some(min_pack) = min_pack {
15281527
min_pack.min(pack)
15291528
} else {
@@ -1555,7 +1554,7 @@ impl<'tcx> TyCtxt<'tcx> {
15551554
ReprFlags::empty()
15561555
}
15571556
attr::ReprAlign(align) => {
1558-
max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap()));
1557+
max_align = max_align.max(Some(align));
15591558
ReprFlags::empty()
15601559
}
15611560
});

tests/ui/repr/repr-align.rs

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ struct S2(i32);
1515
#[repr(align(536870912))] // ok: this is the largest accepted alignment
1616
struct S3(i32);
1717

18+
#[repr(align(0))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
19+
//~| ERROR: invalid `repr(align)` attribute: not a power of two
20+
struct S4(i32);
21+
1822
#[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer
1923
//~| ERROR: invalid `repr(align)` attribute: not an unsuffixed integer
2024
enum E0 { A, B }
@@ -30,4 +34,8 @@ enum E2 { A, B }
3034
#[repr(align(536870912))] // ok: this is the largest accepted alignment
3135
enum E3 { A, B }
3236

37+
#[repr(align(0))] //~ ERROR: invalid `repr(align)` attribute: not a power of two
38+
//~| ERROR: invalid `repr(align)` attribute: not a power of two
39+
enum E4 { A, B }
40+
3341
fn main() {}

tests/ui/repr/repr-align.stderr

+35-7
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,36 @@ error[E0589]: invalid `repr(align)` attribute: larger than 2^29
1616
LL | #[repr(align(4294967296))]
1717
| ^^^^^^^^^^
1818

19-
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
19+
error[E0589]: invalid `repr(align)` attribute: not a power of two
2020
--> $DIR/repr-align.rs:18:14
2121
|
22+
LL | #[repr(align(0))]
23+
| ^
24+
25+
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
26+
--> $DIR/repr-align.rs:22:14
27+
|
2228
LL | #[repr(align(16.0))]
2329
| ^^^^
2430

2531
error[E0589]: invalid `repr(align)` attribute: not a power of two
26-
--> $DIR/repr-align.rs:22:14
32+
--> $DIR/repr-align.rs:26:14
2733
|
2834
LL | #[repr(align(15))]
2935
| ^^
3036

3137
error[E0589]: invalid `repr(align)` attribute: larger than 2^29
32-
--> $DIR/repr-align.rs:26:14
38+
--> $DIR/repr-align.rs:30:14
3339
|
3440
LL | #[repr(align(4294967296))]
3541
| ^^^^^^^^^^
3642

43+
error[E0589]: invalid `repr(align)` attribute: not a power of two
44+
--> $DIR/repr-align.rs:37:14
45+
|
46+
LL | #[repr(align(0))]
47+
| ^
48+
3749
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
3850
--> $DIR/repr-align.rs:3:14
3951
|
@@ -58,30 +70,46 @@ LL | #[repr(align(4294967296))]
5870
|
5971
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
6072

61-
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
73+
error[E0589]: invalid `repr(align)` attribute: not a power of two
6274
--> $DIR/repr-align.rs:18:14
6375
|
76+
LL | #[repr(align(0))]
77+
| ^
78+
|
79+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
80+
81+
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
82+
--> $DIR/repr-align.rs:22:14
83+
|
6484
LL | #[repr(align(16.0))]
6585
| ^^^^
6686
|
6787
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
6888

6989
error[E0589]: invalid `repr(align)` attribute: not a power of two
70-
--> $DIR/repr-align.rs:22:14
90+
--> $DIR/repr-align.rs:26:14
7191
|
7292
LL | #[repr(align(15))]
7393
| ^^
7494
|
7595
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
7696

7797
error[E0589]: invalid `repr(align)` attribute: larger than 2^29
78-
--> $DIR/repr-align.rs:26:14
98+
--> $DIR/repr-align.rs:30:14
7999
|
80100
LL | #[repr(align(4294967296))]
81101
| ^^^^^^^^^^
82102
|
83103
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
84104

85-
error: aborting due to 12 previous errors
105+
error[E0589]: invalid `repr(align)` attribute: not a power of two
106+
--> $DIR/repr-align.rs:37:14
107+
|
108+
LL | #[repr(align(0))]
109+
| ^
110+
|
111+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
112+
113+
error: aborting due to 16 previous errors
86114

87115
For more information about this error, try `rustc --explain E0589`.

0 commit comments

Comments
 (0)