Hi,
in this error recovery issue cp_check_const_attributes and more
generally cplus_decl_attributes have lots of troubles handling the
error_mark_node returned by cp_parser_std_attribute_spec_seq, as called
by cp_parser_direct_declarator. I fiddled quite a bit with these parsing
facilities to eventually notice that boldly changing
cp_parser_std_attribute_spec_seq to return NULL_TREE instead of
error_mark_node when cp_parser_std_attribute_spec returns
error_mark_node in the loop cures the bug at issue as a special case.
I also noticed that in cp_parser_std_attribute_spec we are using
token_pair::require_open / require_close very peculiarly, issuing a
cp_parser_error when the returned bool is false instead of simply
bailing out with error_mark_node and that in fact causes duplicate
diagnostics about expected '(' / ')', respectively.
Tested x86_64-linux.
Thanks, Paolo.
///////////////////////////
/cp
2017-12-22 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/78344
* parser.c (cp_parser_std_attribute_spec_seq): When
cp_parser_std_attribute_spec returns error_mark_node return
back NULL_TREE instead of error_mark_node.
* parser.c (cp_parser_std_attribute_spec): When
token_pair::require_open / require_close returns false simply
return error_mark_node, do not issue a duplicate cp_parser_error
about expected '(' / ')', respectively.
/testsuite
2017-12-22 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/78344
* g++.dg/cpp0x/alignas13.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 255983)
+++ cp/parser.c (working copy)
@@ -25300,10 +25300,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
matching_parens parens;
if (!parens.require_open (parser))
- {
- cp_parser_error (parser, "expected %<(%>");
- return error_mark_node;
- }
+ return error_mark_node;
cp_parser_parse_tentatively (parser);
alignas_expr = cp_parser_type_id (parser);
@@ -25333,10 +25330,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
return error_mark_node;
if (!parens.require_close (parser))
- {
- cp_parser_error (parser, "expected %<)%>");
- return error_mark_node;
- }
+ return error_mark_node;
/* Build the C++-11 representation of an 'aligned'
attribute. */
@@ -25367,7 +25361,7 @@ cp_parser_std_attribute_spec_seq (cp_parser *parse
if (attr_spec == NULL_TREE)
break;
if (attr_spec == error_mark_node)
- return error_mark_node;
+ return NULL_TREE;
if (attr_last)
TREE_CHAIN (attr_last) = attr_spec;
Index: testsuite/g++.dg/cpp0x/alignas13.C
===================================================================
--- testsuite/g++.dg/cpp0x/alignas13.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/alignas13.C (working copy)
@@ -0,0 +1,5 @@
+// PR c++/78344
+// { dg-do compile { target c++11 } }
+
+alignas(double) int f alignas; // { dg-error "30:expected '\\('" }
+alignas(double) int g alignas(double; // { dg-error "37:expected '\\)'" }