On 1/28/21 10:57 PM, Marek Polacek wrote:
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?
OK.
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