Skip to content

Fix repr(...) validation ICE #85976

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,24 @@ pub enum StrStyle {
Raw(u16),
}

impl StrStyle {
/// Actual string data offset from the start of [Lit] span
pub fn prefix_len(self) -> u32 {
match self {
Self::Cooked => 1,
Self::Raw(n) => u32::from(n) + 2, // r#" is 1 + `#` count long + 1
}
}

/// Actual string data offset from the end of [Lit] span
pub fn suffix_len(self) -> u32 {
match self {
Self::Cooked => 1,
Self::Raw(n) => u32::from(n) + 1, // no starting `r` is present, only add 1
}
}
}

/// An AST literal.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct Lit {
Expand Down
352 changes: 266 additions & 86 deletions compiler/rustc_attr/src/builtin.rs

Large diffs are not rendered by default.

35 changes: 18 additions & 17 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2906,29 +2906,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
} else if tcx.sess.check_name(attr, sym::repr) {
codegen_fn_attrs.alignment = match attr.meta_item_list() {
Some(items) => match items.as_slice() {
[item] => match item.name_value_literal() {
Some((sym::align, literal)) => {
let alignment = rustc_attr::parse_alignment(&literal.kind);

match alignment {
Ok(align) => Some(align),
Err(msg) => {
[item] if item.has_name(sym::align) => {
match item.meta_item_list() {
Some([meta]) => {
let alignment = rustc_attr::parse_alignment(
struct_span_err!(
tcx.sess.diagnostic(),
attr.span,
meta.span(),
E0589,
"invalid `repr(align)` attribute: {}",
msg
)
.emit();

None
"invalid `repr(align)` attribute",
),
&meta,
);

match alignment {
Ok(align) => Some(align),
Err(()) => {
// Error already emitted by parse_alignment
None
}
}
}
_ => None,
}
_ => None,
},
[] => None,
}
_ => None,
},
None => None,
Expand Down
90 changes: 90 additions & 0 deletions src/test/ui/repr/basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#![feature(repr_simd)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if we can make this test also check for diagnostic applicability. It might not be possible (if there are further errors afterwards), but let's confirm.

Suggested change
#![feature(repr_simd)]
// run-rustfix
#![feature(repr_simd)]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a separate file for fixable suggestions

#![feature(no_niche)]

#[repr(transparent())] //~ ERROR invalid `repr(transparent)` attribute: no arguments expected
//~| ERROR invalid `repr(transparent)` attribute: no arguments expected
struct S0(u32);

#[repr(transparent(1, 2, 3))] //~ ERROR invalid `repr(transparent)` attribute: no arguments expected
//~| ERROR invalid `repr(transparent)` attribute: no arguments expected
struct S1(u32);

#[repr(C())] //~ ERROR invalid `repr(C)` attribute: no arguments expected
//~| ERROR invalid `repr(C)` attribute: no arguments expected
struct S2(u32);

#[repr(C(1, 2, 3))] //~ ERROR invalid `repr(C)` attribute: no arguments expected
//~| ERROR invalid `repr(C)` attribute: no arguments expected
struct S3(u32);

#[repr(simd())] //~ ERROR invalid `repr(simd)` attribute: no arguments expected
//~| ERROR invalid `repr(simd)` attribute: no arguments expected
struct S4(u32);

#[repr(simd(1, 2, 3))] //~ ERROR invalid `repr(simd)` attribute: no arguments expected
//~| ERROR invalid `repr(simd)` attribute: no arguments expected
struct S5(u32);

#[repr(no_niche())] //~ ERROR invalid `repr(no_niche)` attribute: no arguments expected
//~| ERROR invalid `repr(no_niche)` attribute: no arguments expected
struct S6(u32);

#[repr(no_niche(1, 2, 3))] //~ ERROR invalid `repr(no_niche)` attribute: no arguments expected
//~| ERROR invalid `repr(no_niche)` attribute: no arguments expected
struct S7(u32);


#[repr(align)] //~ ERROR invalid `repr(align)` attribute: expected a non-negative number
//~| ERROR invalid `repr(align)` attribute: expected a non-negative number
struct S8(u32);

#[repr(align())] //~ ERROR invalid `repr(align)` attribute: expected a non-negative number
//~| ERROR invalid `repr(align)` attribute: expected a non-negative number
struct S9(u32);

#[repr(align(foo()))] //~ ERROR invalid `repr(align)` attribute
//~| ERROR invalid `repr(align)` attribute
struct S10(u32);

#[repr(align = "1")] //~ ERROR incorrect `repr(align)` attribute
//~| ERROR incorrect `repr(align)` attribute
struct S11(u32);

#[repr(align = "")] //~ ERROR incorrect `repr(align)` attribute
//~| ERROR incorrect `repr(align)` attribute
struct S12(u32);

#[repr(align = true)] //~ ERROR incorrect `repr(align)` attribute
//~| ERROR incorrect `repr(align)` attribute
struct S13(u32);

#[repr(align(1, 2, 3))] //~ ERROR invalid `repr(align)` attribute: expected only one value
//~| ERROR invalid `repr(align)` attribute: expected only one value
struct S14(u32);

#[repr(packed())] //~ ERROR invalid `repr(packed)` attribute: expected a non-negative number
//~| ERROR invalid `repr(packed)` attribute: expected a non-negative number
struct S15(u32);

#[repr(packed(1, 2, 3))] //~ ERROR invalid `repr(packed)` attribute: expected only one value
//~| ERROR invalid `repr(packed)` attribute: expected only one value
struct S16(u32);

#[repr(i8())] //~ ERROR invalid `repr(i8)` attribute: no arguments expected
//~| ERROR invalid `repr(i8)` attribute: no arguments expected
enum S17 { A, B }

#[repr(i8(1, 2, 3))] //~ ERROR invalid `repr(i8)` attribute: no arguments expected
//~| ERROR invalid `repr(i8)` attribute: no arguments expected
enum S18 { A, B }

#[repr] //~ ERROR malformed `repr` attribute input
struct S19(u32);

#[repr(123)] //~ ERROR meta item in `repr` must be an identifier
struct S20(u32);

#[repr("foo")] //~ ERROR meta item in `repr` must be an identifier
struct S21(u32);

fn main() {}
Loading