1
Fork 0

Error on alignments greater than isize::MAX

Co-authored-by: Jieyou Xu <jieyouxu@outlook.com>
This commit is contained in:
asquared31415 2024-10-12 05:37:56 +00:00 committed by 许杰友 Jieyou Xu (Joe)
parent df4ca44d3f
commit 6fc7ce43d2
5 changed files with 100 additions and 1 deletions

View file

@ -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

View file

@ -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};
@ -1785,7 +1786,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| Target::Union
| Target::Enum
| Target::Fn
| Target::Method(_) => continue,
| Target::Method(_) => {}
_ => {
self.dcx().emit_err(
errors::AttrApplication::StructEnumFunctionMethodUnion {
@ -1795,6 +1796,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
);
}
}
self.check_align_value(hint);
}
sym::packed => {
if target != Target::Struct && target != Target::Union {
@ -1892,6 +1895,45 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
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;

View file

@ -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;