From b963d599a7df2cb8e8b6bc3b1006cb1c5b89c5be Mon Sep 17 00:00:00 2001 From: liushuyu Date: Wed, 4 Dec 2024 11:13:59 -0700 Subject: [PATCH] gccrs: fix a compiler crash when path expression contains nothing gcc/rust/ChangeLog: * ast/rust-path.h: allows error nodes to specify the source location, so that it could be used in diagnostics later. * parse/rust-parse-impl.h: creates the PathInExpression error node with source location and prints proper diagnostics if the path is empty. gcc/testsuite/ChangeLog: * rust/compile/paamayim-nekudotayim.rs: add a test for testing proper error recovery logic when there is no path names. --- gcc/rust/ast/rust-path.h | 4 ++-- gcc/rust/parse/rust-parse-impl.h | 11 ++++++++--- gcc/testsuite/rust/compile/paamayim-nekudotayim.rs | 5 +++++ 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/rust/compile/paamayim-nekudotayim.rs diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 2df1506923d7..1bbac6883e1c 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -727,9 +727,9 @@ class PathInExpression : public Pattern, public ExprWithoutBlock } // Creates an error state path in expression. - static PathInExpression create_error () + static PathInExpression create_error (location_t locus = UNDEF_LOCATION) { - return PathInExpression ({}, {}, UNDEF_LOCATION); + return PathInExpression ({}, {}, locus); } // Returns whether path in expression is in an error state. diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index aff81448deae..73c55962023a 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -6713,9 +6713,9 @@ Parser::parse_path_in_expression () AST::PathExprSegment initial_segment = parse_path_expr_segment (); if (initial_segment.is_error ()) { - // skip after somewhere? - // don't necessarily throw error but yeah - return AST::PathInExpression::create_error (); + // we can not throw an error here because if entered from macro expansion + // the macro expander can throw another error which might confuse the user + return AST::PathInExpression::create_error (locus); } segments.push_back (std::move (initial_segment)); @@ -11637,6 +11637,11 @@ Parser::parse_stmt_or_expr () AST::PathInExpression path = parse_path_in_expression (); std::unique_ptr null_denotation; + if (path.is_error ()) + { + rust_error_at (path.get_locus (), "expected identifier"); + } + if (lexer.peek_token ()->get_id () == EXCLAM) { std::unique_ptr invoc diff --git a/gcc/testsuite/rust/compile/paamayim-nekudotayim.rs b/gcc/testsuite/rust/compile/paamayim-nekudotayim.rs new file mode 100644 index 000000000000..59f80feb6452 --- /dev/null +++ b/gcc/testsuite/rust/compile/paamayim-nekudotayim.rs @@ -0,0 +1,5 @@ +// http://phpsadness.com/sad/1 +fn main() { + ::; + // { dg-error "expected identifier" "" { target *-*-* } .-1 } +}