This fix is similar to c++/79653: if something went wrong during
make_pack_expansion, return error_mark instead of building up the attribute
otherwise we end up with "gnu aligned <<<error>>>" and that would mean crashing
later on at a lot of spots.

Also, dump_expr wasn't able to print TREE_LISTs.  It's easy to do so using
dump_expr_list, so that we print '__alignof__ (A<T>)' instead of ugly
'#'tree_list' not supported by dump_expr#<expression error>'.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-03-30  Marek Polacek  <pola...@redhat.com>

        PR c++/80241 - ICE with alignas pack expansion.
        * error.c (dump_expr): Handle TREE_LIST.
        * parser.c (cp_parser_std_attribute_list): Return error_mark if
        make_pack_expansion returns an error.

        * g++.dg/cpp0x/alignas11.C: New test.

diff --git gcc/cp/error.c gcc/cp/error.c
index d8c5d5e..10af9d0 100644
--- gcc/cp/error.c
+++ gcc/cp/error.c
@@ -2821,6 +2821,10 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
       pp_string (pp, M_("*this"));
       break;
 
+    case TREE_LIST:
+      dump_expr_list (pp, t, flags);
+      break;
+
       /*  This list is incomplete, but should suffice for now.
          It is very important that `sorry' does not call
          `report_error_function'.  That could cause an infinite loop.  */
diff --git gcc/cp/parser.c gcc/cp/parser.c
index c1b6496..efca2e1 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -24842,8 +24842,12 @@ cp_parser_std_attribute_list (cp_parser *parser, tree 
attr_ns)
            error_at (token->location,
                      "expected attribute before %<...%>");
          else
-           TREE_VALUE (attribute)
-             = make_pack_expansion (TREE_VALUE (attribute));
+           {
+             tree pack = make_pack_expansion (TREE_VALUE (attribute));
+             if (pack == error_mark_node)
+               return error_mark_node;
+             TREE_VALUE (attribute) = pack;
+           }
          token = cp_lexer_peek_token (parser->lexer);
        }
       if (token->type != CPP_COMMA)
diff --git gcc/testsuite/g++.dg/cpp0x/alignas11.C 
gcc/testsuite/g++.dg/cpp0x/alignas11.C
index e69de29..73c54da 100644
--- gcc/testsuite/g++.dg/cpp0x/alignas11.C
+++ gcc/testsuite/g++.dg/cpp0x/alignas11.C
@@ -0,0 +1,10 @@
+// PR c++/80241
+// { dg-do compile { target c++11 } }
+
+template <typename... T>
+struct A
+{
+  [[gnu::aligned (alignof(A))...]] char c; // { dg-error "expansion pattern" }
+};
+
+A<int> a;

        Marek

Reply via email to