Hi again,

thus the below is a rather "dull" solution at the level of cplus_decl_attributes itself: cp_check_const_attributes is tweaked to check for error_mark_node at each outer iteration and consistently return a bool, which is then checked by the caller in order to possibly bail out (this is similar to the check_for_bare_parameter_packs call a few lines before). Testing is Ok on x86_64-linux.

Thanks,
Paolo.

////////////////////////////
/cp
2018-01-11  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/78344
        * decl2.c (cp_check_const_attributes): Check for error_mark_node
        at each outer iterations; return a bool.
        (cplus_decl_attributes): Adjust cp_check_const_attributes call.

/testsuite
2018-01-10  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/78344
        * g++.dg/cpp0x/alignas13.C: New.
Index: cp/decl2.c
===================================================================
--- cp/decl2.c  (revision 256451)
+++ cp/decl2.c  (working copy)
@@ -1396,19 +1396,17 @@ cp_reconstruct_complex_type (tree type, tree botto
 }
 
 /* Replaces any constexpr expression that may be into the attributes
-   arguments with their reduced value.  */
+   arguments with their reduced value.  Returns FALSE if encounters
+   error_mark_node, TRUE otherwise.  */
 
-static void
+static bool
 cp_check_const_attributes (tree attributes)
 {
-  if (attributes == error_mark_node)
-    return;
-
-  tree attr;
-  for (attr = attributes; attr; attr = TREE_CHAIN (attr))
+  for (tree attr = attributes; attr; attr = TREE_CHAIN (attr))
     {
-      tree arg;
-      for (arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
+      if (attr == error_mark_node)
+       return false;
+      for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
        {
          tree expr = TREE_VALUE (arg);
          if (EXPR_P (expr))
@@ -1415,6 +1413,7 @@ cp_check_const_attributes (tree attributes)
            TREE_VALUE (arg) = maybe_constant_value (expr);
        }
     }
+  return true;
 }
 
 /* Return true if TYPE is an OpenMP mappable type.  */
@@ -1528,7 +1527,8 @@ cplus_decl_attributes (tree *decl, tree attributes
       save_template_attributes (&attributes, decl, flags);
     }
 
-  cp_check_const_attributes (attributes);
+  if (!cp_check_const_attributes (attributes))
+    return;
 
   if (TREE_CODE (*decl) == TEMPLATE_DECL)
     decl = &DECL_TEMPLATE_RESULT (*decl);
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