From f8f5388c9e94d4324c31d82b335fa138518e3171 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 28 Jan 2021 22:18:32 -0500 Subject: [PATCH] c++: Fix infinite looping with invalid operator [PR96137] 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. 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::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" } +} -- 2.30.2