From: Jason Merrill Date: Fri, 8 May 2015 04:42:06 +0000 (-0400) Subject: re PR c++/59012 (alignas does not support parameter pack expansions) X-Git-Tag: basepoints/gcc-7~7335 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=90f11cf950130d1aa6030a3c0df2e400ca14df7b;p=gcc.git re PR c++/59012 (alignas does not support parameter pack expansions) PR c++/59012 * parser.c (cp_parser_std_attribute_list): Handle attribute expansion. (cp_parser_std_attribute_spec): Handle alignas pack expansion. * decl2.c (is_late_template_attribute): An attribute exp is dependent. * pt.c (make_pack_expansion): Allow TREE_LIST for attribute expansion. (apply_late_template_attributes): Handle attribute pack expansion. From-SVN: r222902 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3c32e6f77ddb..8427e9d2782a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2015-05-07 Jason Merrill + + PR c++/59012 + * parser.c (cp_parser_std_attribute_list): Handle attribute expansion. + (cp_parser_std_attribute_spec): Handle alignas pack expansion. + * decl2.c (is_late_template_attribute): An attribute exp is dependent. + * pt.c (make_pack_expansion): Allow TREE_LIST for attribute expansion. + (apply_late_template_attributes): Handle attribute pack expansion. + 2015-05-07 Marek Polacek PR c/65179 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 0d478471925a..2276bd67acea 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1175,6 +1175,10 @@ is_late_template_attribute (tree attr, tree decl) && is_attribute_p ("omp declare simd", name)) return true; + /* An attribute pack is clearly dependent. */ + if (args && PACK_EXPANSION_P (args)) + return true; + /* If any of the arguments are dependent expressions, we can't evaluate the attribute until instantiation time. */ for (arg = args; arg; arg = TREE_CHAIN (arg)) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 30a3fabbb986..3d165da708fe 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22486,6 +22486,13 @@ cp_parser_std_attribute_list (cp_parser *parser) attributes = attribute; } token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_ELLIPSIS) + { + cp_lexer_consume_token (parser->lexer); + TREE_VALUE (attribute) + = make_pack_expansion (TREE_VALUE (attribute)); + token = cp_lexer_peek_token (parser->lexer); + } if (token->type != CPP_COMMA) break; cp_lexer_consume_token (parser->lexer); @@ -22564,20 +22571,27 @@ cp_parser_std_attribute_spec (cp_parser *parser) return alignas_expr; } + alignas_expr = cxx_alignas_expr (alignas_expr); + alignas_expr = build_tree_list (NULL_TREE, alignas_expr); + + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) + { + cp_lexer_consume_token (parser->lexer); + alignas_expr = make_pack_expansion (alignas_expr); + } + if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) == NULL) { cp_parser_error (parser, "expected %<)%>"); return error_mark_node; } - alignas_expr = cxx_alignas_expr (alignas_expr); - /* Build the C++-11 representation of an 'aligned' attribute. */ attributes = build_tree_list (build_tree_list (get_identifier ("gnu"), get_identifier ("aligned")), - build_tree_list (NULL_TREE, alignas_expr)); + alignas_expr); } return attributes; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8e0e789916b2..78714745452c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3338,9 +3338,9 @@ make_pack_expansion (tree arg) if (!arg || arg == error_mark_node) return arg; - if (TREE_CODE (arg) == TREE_LIST) + if (TREE_CODE (arg) == TREE_LIST && TREE_PURPOSE (arg)) { - /* The only time we will see a TREE_LIST here is for a base + /* A TREE_LIST with a non-null TREE_PURPOSE is for a base class initializer. In this case, the TREE_PURPOSE will be a _TYPE node (representing the base class expansion we're initializing) and the TREE_VALUE will be a TREE_LIST @@ -9012,6 +9012,21 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)), chain); } + else if (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))) + { + /* An attribute pack expansion. */ + tree purp = TREE_PURPOSE (t); + tree pack = (tsubst_pack_expansion + (TREE_VALUE (t), args, complain, in_decl)); + int len = TREE_VEC_LENGTH (pack); + for (int i = 0; i < len; ++i) + { + tree elt = TREE_VEC_ELT (pack, i); + *q = build_tree_list (purp, elt); + q = &TREE_CHAIN (*q); + } + continue; + } else TREE_VALUE (t) = tsubst_expr (TREE_VALUE (t), args, complain, in_decl, diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas4.C b/gcc/testsuite/g++.dg/cpp0x/alignas4.C new file mode 100644 index 000000000000..871aaefed1ff --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alignas4.C @@ -0,0 +1,19 @@ +// PR c++/59012 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler "align 8" { target x86_64-*-*-gnu } } } + +template +struct A +{ + alignas(T...) char t; +}; + +A a; + +template +struct A2 +{ + [[gnu::aligned (alignof (T))...]] char t; +}; + +A2 a2;