https://gcc.gnu.org/g:4721d3dc0b70868a974441c5268a1b7e87d46a88
commit r17-2237-g4721d3dc0b70868a974441c5268a1b7e87d46a88 Author: hriztam <[email protected]> Date: Sat Apr 4 01:40:59 2026 +0530 gccrs: rust: avoid ICE on attributed struct base parsing gcc/rust/ChangeLog: * parse/rust-parse-error.h (StructExprField): Add STRUCT_BASE_ATTRIBUTES. * parse/rust-parse-impl-expr.hxx (Parser<ManagedTokenSource>::parse_struct_expr_field): Reject attributes before struct-base `..`. (Parser<ManagedTokenSource>::parse_struct_expr_struct_partial): Handle struct-base parse results without dereferencing an errored expected. gcc/testsuite/ChangeLog: * rust/compile/issue-4476.rs: New test. Signed-off-by: Hritam Shrivastava <[email protected]> Diff: --- gcc/rust/parse/rust-parse-error.h | 1 + gcc/rust/parse/rust-parse-impl-expr.hxx | 20 ++++++++++++++++++-- gcc/testsuite/rust/compile/issue-4476.rs | 10 ++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/gcc/rust/parse/rust-parse-error.h b/gcc/rust/parse/rust-parse-error.h index 46ac46245b47..a4eb34c12b87 100644 --- a/gcc/rust/parse/rust-parse-error.h +++ b/gcc/rust/parse/rust-parse-error.h @@ -358,6 +358,7 @@ enum class StructExprField { MALFORMED, CHILD_ERROR, + STRUCT_BASE_ATTRIBUTES, // Not a hard error STRUCT_BASE, }; diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx b/gcc/rust/parse/rust-parse-impl-expr.hxx index 887991541631..aaffa3dcba65 100644 --- a/gcc/rust/parse/rust-parse-impl-expr.hxx +++ b/gcc/rust/parse/rust-parse-impl-expr.hxx @@ -1752,6 +1752,16 @@ Parser<ManagedTokenSource>::parse_struct_expr_field () case DOT_DOT: /* this is a struct base and can't be parsed here, so just return * nothing without erroring */ + if (!outer_attrs.empty ()) + { + add_error ( + Error (t->get_locus (), + "attributes are not allowed before %<..%> in a struct " + "expression")); + + return tl::unexpected<Parse::Error::StructExprField> ( + Parse::Error::StructExprField::STRUCT_BASE_ATTRIBUTES); + } return tl::unexpected<Parse::Error::StructExprField> ( Parse::Error::StructExprField::STRUCT_BASE); @@ -4068,9 +4078,15 @@ Parser<ManagedTokenSource>::parse_struct_expr_struct_partial ( while (t->get_id () != RIGHT_CURLY && t->get_id () != DOT_DOT) { auto field = parse_struct_expr_field (); - if (!field - && field.error () != Parse::Error::StructExprField::STRUCT_BASE) + if (!field) { + if (field.error () == Parse::Error::StructExprField::STRUCT_BASE) + break; + if (field.error () + == Parse::Error::StructExprField::STRUCT_BASE_ATTRIBUTES) + return tl::unexpected<Parse::Error::Expr> ( + Parse::Error::Expr::CHILD_ERROR); + Error error (t->get_locus (), "failed to parse struct (or enum) expr field"); add_error (std::move (error)); diff --git a/gcc/testsuite/rust/compile/issue-4476.rs b/gcc/testsuite/rust/compile/issue-4476.rs new file mode 100644 index 000000000000..2427a67ebcba --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4476.rs @@ -0,0 +1,10 @@ +#![feature(no_core)] +#![no_core] + +struct Foo {} +struct S {} + +fn main() { + Foo { #[cfg(feature = -1)] .. } = S {}; + // { dg-error "attributes are not allowed before .* in a struct expression" "" { target *-*-* } .-1 } +}
