Skip to content

Commit 0f982de

Browse files
committedOct 13, 2024·
error on alignments greater than isize::MAX
1 parent 18b1161 commit 0f982de

File tree

4 files changed

+67
-1
lines changed

4 files changed

+67
-1
lines changed
 

‎compiler/rustc_passes/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,10 @@ passes_remove_fields =
607607
passes_repr_align_function =
608608
`repr(align)` attributes on functions are unstable
609609
610+
passes_repr_align_greater_than_target_max =
611+
alignment must not be greater than `isize::MAX` bytes
612+
.note = `isize::MAX` is {$size} for the current target
613+
610614
passes_repr_conflicting =
611615
conflicting representation hints
612616

‎compiler/rustc_passes/src/check_attr.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use rustc_session::lint::builtin::{
3434
use rustc_session::parse::feature_err;
3535
use rustc_span::symbol::{Symbol, kw, sym};
3636
use rustc_span::{BytePos, DUMMY_SP, Span};
37+
use rustc_target::abi::Size;
3738
use rustc_target::spec::abi::Abi;
3839
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
3940
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
@@ -1786,7 +1787,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17861787
| Target::Union
17871788
| Target::Enum
17881789
| Target::Fn
1789-
| Target::Method(_) => continue,
1790+
| Target::Method(_) => {}
17901791
_ => {
17911792
self.dcx().emit_err(
17921793
errors::AttrApplication::StructEnumFunctionMethodUnion {
@@ -1796,6 +1797,32 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17961797
);
17971798
}
17981799
}
1800+
1801+
// UNWRAP: parsing the attribute already ensured that it had a name and integer value
1802+
// that is a power of 2 and less than 2^29
1803+
1804+
// if the attribute is malformed, it may return None from this
1805+
// but an error will have already been emitted, so this code should just skip such attributes
1806+
1807+
if let Some((
1808+
_,
1809+
MetaItemLit {
1810+
kind: ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed),
1811+
..
1812+
},
1813+
)) = hint.singleton_lit_list()
1814+
{
1815+
{
1816+
let max = Size::from_bits(self.tcx.sess.target.pointer_width)
1817+
.signed_int_max() as u64;
1818+
if literal.get() as u64 > max {
1819+
self.dcx().emit_err(errors::InvalidReprAlignForTarget {
1820+
span: hint.span(),
1821+
size: max,
1822+
});
1823+
}
1824+
}
1825+
}
17991826
}
18001827
sym::packed => {
18011828
if target != Target::Struct && target != Target::Union {

‎compiler/rustc_passes/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,15 @@ pub(crate) struct ReprConflicting {
532532
pub hint_spans: Vec<Span>,
533533
}
534534

535+
#[derive(Diagnostic)]
536+
#[diag(passes_repr_align_greater_than_target_max, code = E0589)]
537+
#[note]
538+
pub(crate) struct InvalidReprAlignForTarget {
539+
#[primary_span]
540+
pub span: Span,
541+
pub size: u64,
542+
}
543+
535544
#[derive(LintDiagnostic)]
536545
#[diag(passes_repr_conflicting, code = E0566)]
537546
pub(crate) struct ReprConflictingLint;
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ revisions: msp430 aarch32
2+
//@[msp430] build-fail
3+
//@[msp430] needs-llvm-components: msp430
4+
//@[msp430] compile-flags: --target=msp430-none-elf
5+
//@[aarch32] build-pass
6+
//@[aarch32] needs-llvm-components: arm
7+
//@[aarch32] compile-flags: --target=thumbv7m-none-eabi
8+
9+
// We should fail to compute alignment for types aligned higher than usize::MAX.
10+
// We can't handle alignments that require all 32 bits, so this only affects 16-bit.
11+
12+
#![feature(lang_items, no_core)]
13+
#![no_core]
14+
#![crate_type = "lib"]
15+
16+
#[lang = "sized"]
17+
trait Sized {}
18+
19+
#[repr(align(16384))]
20+
struct Kitten;
21+
22+
#[repr(align(32768))]
23+
struct Cat;
24+
25+
#[repr(align(65536))]
26+
struct BigCat;

0 commit comments

Comments
 (0)