... 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 '\\)'" }

Reply via email to