... today I played a bit with the other idea inspired by your feedback.
Irrespective of the special issue at hand, it seems in principle
interesting to me that when we are sure that we aren't parsing
tentatively anymore we can do something more radical for the sake of
better error recovery. Anyway, the below passes testing and yes, there
are cases in our testsuite where cp_parser_std_attribute_spec returns
error_mark_node and cp_parser_uncommitted_to_tentative_parse_p is true.
Paolo.
///////////////////
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 256543)
+++ cp/parser.c (working copy)
@@ -25382,7 +25382,15 @@ 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;
+ {
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ /* When guaranteed to be correct, behaving as if the
+ erroneous attributes weren't there in the first place
+ makes for very good error recovery (c++/78344). */
+ return NULL_TREE;
+ else
+ return error_mark_node;
+ }
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 '\\)'" }