Hi,
in this small error-recovery issue, we don't notice that
cp_parser_identifier returns error_mark_node because the
introduction-list is empty and we proceed to assign the error_mark_node
to DECL_NAME (parm) to crash later in find_local_binding - in general
the front-end doesn't expect to find an error_mark_node as DECL_NAME. I
think we can simply add the check here too and early exit the loop in
the cases at issue. I'm also consistently tweaking a bit error-recovery
in the caller, cp_parser_template_introduction - note that currently
nargs is never zero: due to the above slightly broken logic the vector
has always at least an element (possibly with DECL_NAME ==
error_mark_node). Tested x86-64-linux.
Thanks, Paolo.
///////////////////////
/cp
2018-08-29 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/85265
* parser.c (cp_parser_introduction_list): If cp_parser_identifier
returns error_mark_node early exit the loop.
(cp_parser_template_introduction): Improve error-recovery, remove
error call about empty introduction-list.
/testsuite
2018-08-29 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/85265
* g++.dg/concepts/pr85265.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 263947)
+++ cp/parser.c (working copy)
@@ -15242,11 +15242,15 @@ cp_parser_introduction_list (cp_parser *parser)
if (is_pack)
cp_lexer_consume_token (parser->lexer);
+ tree identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ break;
+
/* Build placeholder. */
tree parm = build_nt (WILDCARD_DECL);
DECL_SOURCE_LOCATION (parm)
= cp_lexer_peek_token (parser->lexer)->location;
- DECL_NAME (parm) = cp_parser_identifier (parser);
+ DECL_NAME (parm) = identifier;
WILDCARD_PACK_P (parm) = is_pack;
vec_safe_push (introduction_vec, parm);
@@ -27178,18 +27182,18 @@ cp_parser_template_introduction (cp_parser* parser
matching identifiers. */
tree introduction_list = cp_parser_introduction_list (parser);
+ /* Look for closing brace for introduction. */
+ if (!braces.require_close (parser))
+ return true;
+
/* The introduction-list shall not be empty. */
int nargs = TREE_VEC_LENGTH (introduction_list);
if (nargs == 0)
{
- error ("empty introduction-list");
+ /* In cp_parser_introduction_list we have already issued an error. */
return true;
}
- /* Look for closing brace for introduction. */
- if (!braces.require_close (parser))
- return true;
-
if (tmpl_decl == error_mark_node)
{
cp_parser_name_lookup_error (parser, concept_name, tmpl_decl, NLE_NULL,
Index: testsuite/g++.dg/concepts/pr85265.C
===================================================================
--- testsuite/g++.dg/concepts/pr85265.C (nonexistent)
+++ testsuite/g++.dg/concepts/pr85265.C (working copy)
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-fconcepts" }
+
+template<typename> concept bool C = true;
+
+C{} void foo(); // { dg-error "expected identifier" }