Error on alignments greater than isize::MAX
Co-authored-by: Jieyou Xu <jieyouxu@outlook.com>
This commit is contained in:
parent
df4ca44d3f
commit
6fc7ce43d2
@ -622,6 +622,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
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
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};
|
||||
@ -1785,7 +1786,7 @@ fn check_repr(
|
||||
| Target::Union
|
||||
| Target::Enum
|
||||
| Target::Fn
|
||||
| Target::Method(_) => continue,
|
||||
| Target::Method(_) => {}
|
||||
_ => {
|
||||
self.dcx().emit_err(
|
||||
errors::AttrApplication::StructEnumFunctionMethodUnion {
|
||||
@ -1795,6 +1796,8 @@ fn check_repr(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.check_align_value(hint);
|
||||
}
|
||||
sym::packed => {
|
||||
if target != Target::Struct && target != Target::Union {
|
||||
@ -1892,6 +1895,45 @@ fn check_repr(
|
||||
}
|
||||
}
|
||||
|
||||
fn check_align_value(&self, item: &MetaItemInner) {
|
||||
match item.singleton_lit_list() {
|
||||
Some((
|
||||
_,
|
||||
MetaItemLit {
|
||||
kind: ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed), ..
|
||||
},
|
||||
)) => {
|
||||
let val = literal.get() as u64;
|
||||
if val > 2_u64.pow(29) {
|
||||
// for values greater than 2^29, a different error will be emitted, make sure that happens
|
||||
self.dcx().span_delayed_bug(
|
||||
item.span(),
|
||||
"alignment greater than 2^29 should be errored on elsewhere",
|
||||
);
|
||||
} else {
|
||||
// only do this check when <= 2^29 to prevent duplicate errors:
|
||||
// alignment greater than 2^29 not supported
|
||||
// alignment is too large for the current target
|
||||
|
||||
let max =
|
||||
Size::from_bits(self.tcx.sess.target.pointer_width).signed_int_max() as u64;
|
||||
if val > max {
|
||||
self.dcx().emit_err(errors::InvalidReprAlignForTarget {
|
||||
span: item.span(),
|
||||
size: max,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the attribute is malformed, singleton_lit_list may not be of the expected type or may be None
|
||||
// but an error will have already been emitted, so this code should just skip such attributes
|
||||
Some((_, _)) | None => {
|
||||
self.dcx().span_delayed_bug(item.span(), "malformed repr(align(N))");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_used(&self, attrs: &[Attribute], target: Target, target_span: Span) {
|
||||
let mut used_linker_span = None;
|
||||
let mut used_compiler_span = None;
|
||||
|
@ -567,6 +567,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;
|
||||
|
19
tests/ui/repr/repr_align_greater_usize.msp430.stderr
Normal file
19
tests/ui/repr/repr_align_greater_usize.msp430.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0589]: alignment must not be greater than `isize::MAX` bytes
|
||||
--> $DIR/repr_align_greater_usize.rs:21:8
|
||||
|
|
||||
LL | #[repr(align(32768))]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: `isize::MAX` is 32767 for the current target
|
||||
|
||||
error[E0589]: alignment must not be greater than `isize::MAX` bytes
|
||||
--> $DIR/repr_align_greater_usize.rs:24:8
|
||||
|
|
||||
LL | #[repr(align(65536))]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: `isize::MAX` is 32767 for the current target
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0589`.
|
25
tests/ui/repr/repr_align_greater_usize.rs
Normal file
25
tests/ui/repr/repr_align_greater_usize.rs
Normal file
@ -0,0 +1,25 @@
|
||||
//@ revisions: msp430 aarch32
|
||||
//@[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))] //[msp430]~ ERROR alignment must not be greater than `isize::MAX`
|
||||
struct Cat;
|
||||
|
||||
#[repr(align(65536))] //[msp430]~ ERROR alignment must not be greater than `isize::MAX`
|
||||
struct BigCat;
|
Loading…
Reference in New Issue
Block a user