Skip to content

Commit

Permalink
error on alignments greater than isize::MAX
Browse files Browse the repository at this point in the history
  • Loading branch information
asquared31415 committed Oct 13, 2024
1 parent 18b1161 commit 0f982de
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
4 changes: 4 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@ passes_remove_fields =
passes_repr_align_function =
`repr(align)` attributes on functions are unstable
passes_repr_align_greater_than_target_max =
alignment must not be greater than `isize::MAX` bytes
.note = `isize::MAX` is {$size} for the current target
passes_repr_conflicting =
conflicting representation hints
Expand Down
29 changes: 28 additions & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use rustc_session::lint::builtin::{
use rustc_session::parse::feature_err;
use rustc_span::symbol::{Symbol, kw, sym};
use rustc_span::{BytePos, DUMMY_SP, Span};
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
Expand Down Expand Up @@ -1786,7 +1787,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| Target::Union
| Target::Enum
| Target::Fn
| Target::Method(_) => continue,
| Target::Method(_) => {}
_ => {
self.dcx().emit_err(
errors::AttrApplication::StructEnumFunctionMethodUnion {
Expand All @@ -1796,6 +1797,32 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
);
}
}

// UNWRAP: parsing the attribute already ensured that it had a name and integer value
// that is a power of 2 and less than 2^29

// if the attribute is malformed, it may return None from this
// but an error will have already been emitted, so this code should just skip such attributes

if let Some((
_,
MetaItemLit {
kind: ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed),
..
},
)) = hint.singleton_lit_list()
{
{
let max = Size::from_bits(self.tcx.sess.target.pointer_width)
.signed_int_max() as u64;
if literal.get() as u64 > max {
self.dcx().emit_err(errors::InvalidReprAlignForTarget {
span: hint.span(),
size: max,
});
}
}
}
}
sym::packed => {
if target != Target::Struct && target != Target::Union {
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,15 @@ pub(crate) struct ReprConflicting {
pub hint_spans: Vec<Span>,
}

#[derive(Diagnostic)]
#[diag(passes_repr_align_greater_than_target_max, code = E0589)]
#[note]
pub(crate) struct InvalidReprAlignForTarget {
#[primary_span]
pub span: Span,
pub size: u64,
}

#[derive(LintDiagnostic)]
#[diag(passes_repr_conflicting, code = E0566)]
pub(crate) struct ReprConflictingLint;
Expand Down
26 changes: 26 additions & 0 deletions tests/ui/repr/repr_align_greater_usize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ revisions: msp430 aarch32
//@[msp430] build-fail
//@[msp430] needs-llvm-components: msp430
//@[msp430] compile-flags: --target=msp430-none-elf
//@[aarch32] build-pass
//@[aarch32] needs-llvm-components: arm
//@[aarch32] compile-flags: --target=thumbv7m-none-eabi

// We should fail to compute alignment for types aligned higher than usize::MAX.
// We can't handle alignments that require all 32 bits, so this only affects 16-bit.

#![feature(lang_items, no_core)]
#![no_core]
#![crate_type = "lib"]

#[lang = "sized"]
trait Sized {}

#[repr(align(16384))]
struct Kitten;

#[repr(align(32768))]
struct Cat;

#[repr(align(65536))]
struct BigCat;

0 comments on commit 0f982de

Please sign in to comment.