My r11-86 adjusted cp_parser_class_name to do

-  scope = parser->scope;
+  scope = parser->scope ? parser->scope : parser->context->object_type;
   if (scope == error_mark_node)
     return error_mark_node;

but that caused endless looping in cp_parser_type_specifier_seq (the
while (true) loop) in this invalid test, because we never set a parser
error, therefore cp_parser_type_specifier returned error_mark_node
instead of NULL_TREE, and we never issued the "expected type-specifier"
error.

At first I thought I'd just add cp_parser_simulate_error right before
the return, but that regresses crash81.C -- we'd emit multiple errors
for "T::X".  So the next best thing seemed to revert to pre-r11-86
behavior: return early when parser->scope is bad, otherwise proceed to
get the parser error.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

gcc/cp/ChangeLog:

        PR c++/96137
        * parser.c (cp_parser_class_name): If parser->scope is
        error_mark_node, return it, otherwise continue.

gcc/testsuite/ChangeLog:

        PR c++/96137
        * g++.dg/parse/error63.C: New test.
---
 gcc/cp/parser.c                      | 4 +++-
 gcc/testsuite/g++.dg/parse/error63.C | 8 ++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/parse/error63.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e196db14113..5c1d880c9fc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -24559,7 +24559,9 @@ cp_parser_class_name (cp_parser *parser,
       where we first want to look up A<T>::a in the class of the object
       expression, as per [basic.lookup.classref].  */
   tree scope = parser->scope ? parser->scope : parser->context->object_type;
-  if (scope == error_mark_node)
+  /* This only checks parser->scope to avoid duplicate errors; if
+     ->object_type is erroneous, go on to give a parse error.  */
+  if (parser->scope == error_mark_node)
     return error_mark_node;
 
   /* Any name names a type if we're following the `typename' keyword
diff --git a/gcc/testsuite/g++.dg/parse/error63.C 
b/gcc/testsuite/g++.dg/parse/error63.C
new file mode 100644
index 00000000000..5472ef05a64
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/error63.C
@@ -0,0 +1,8 @@
+// PR c++/96137
+// { dg-do compile }
+
+void
+fn ()
+{
+  X.operator T(); // { dg-error ".X. was not declared in this scope|expected" }
+}

base-commit: e6bce7fe17bf32ce969abc6f77f07acd352f6977
-- 
2.29.2

Reply via email to