This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH to fix ICEs with alignas and template parameter pack (PR c++/79653)
- From: Jason Merrill <jason at redhat dot com>
- To: Marek Polacek <polacek at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 22 Feb 2017 11:24:34 -0800
- Subject: Re: C++ PATCH to fix ICEs with alignas and template parameter pack (PR c++/79653)
- Authentication-results: sourceware.org; auth=none
- References: <20170222185353.GL3892@redhat.com>
OK.
On Wed, Feb 22, 2017 at 10:53 AM, Marek Polacek <polacek@redhat.com> wrote:
> This patch oughta fix a couple of ice-on-invalids.
>
> The parser.c part: I think it makes no sense for cp_parser_std_attribute_spec
> to create an attribute if something went wrong, e.g. in make_pack_expansion, so
> return error_mark_node to signal an issue.
>
> The pt.c part: tsubst_pack_expansion can return error_mark_node to indicate
> that it couldn't handle something, in which case we cannot use TREE_VEC_LENGTH
> on the result.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2017-02-22 Marek Polacek <polacek@redhat.com>
>
> PR c++/79653
> * parser.c (cp_parser_std_attribute_spec): Don't build the attribute
> if the alignas expression is erroneous.
> * pt.c (tsubst_attribute): If tsubst_pack_expansion fails, return
> error_mark_node.
>
> * g++.dg/cpp0x/alignas10.C: New test.
> * g++.dg/cpp0x/alignas9.C: New test.
>
> diff --git gcc/cp/parser.c gcc/cp/parser.c
> index 3992516..e20257c 100644
> --- gcc/cp/parser.c
> +++ gcc/cp/parser.c
> @@ -24977,12 +24977,17 @@ cp_parser_std_attribute_spec (cp_parser *parser)
> alignas_expr = cxx_alignas_expr (alignas_expr);
> alignas_expr = build_tree_list (NULL_TREE, alignas_expr);
>
> + /* Handle alignas (pack...). */
> if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
> {
> cp_lexer_consume_token (parser->lexer);
> alignas_expr = make_pack_expansion (alignas_expr);
> }
>
> + /* Something went wrong, so don't build the attribute. */
> + if (alignas_expr == error_mark_node)
> + return error_mark_node;
> +
> if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) == NULL)
> {
> cp_parser_error (parser, "expected %<)%>");
> diff --git gcc/cp/pt.c gcc/cp/pt.c
> index 38a01e1..5b0f62d 100644
> --- gcc/cp/pt.c
> +++ gcc/cp/pt.c
> @@ -10012,6 +10012,8 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
> /* An attribute pack expansion. */
> tree purp = TREE_PURPOSE (t);
> tree pack = tsubst_pack_expansion (val, args, complain, in_decl);
> + if (pack == error_mark_node)
> + return error_mark_node;
> int len = TREE_VEC_LENGTH (pack);
> tree list = NULL_TREE;
> tree *q = &list;
> diff --git gcc/testsuite/g++.dg/cpp0x/alignas10.C gcc/testsuite/g++.dg/cpp0x/alignas10.C
> index e69de29..164994e 100644
> --- gcc/testsuite/g++.dg/cpp0x/alignas10.C
> +++ gcc/testsuite/g++.dg/cpp0x/alignas10.C
> @@ -0,0 +1,7 @@
> +// PR c++/79653
> +// { dg-do compile { target c++11 } }
> +
> +template <typename... A> struct outer {
> + template <typename... B> struct alignas(alignof(A) * alignof(B)...) inner {}; // { dg-error "mismatched argument pack lengths" }
> +};
> +outer<int>::inner<> mismatched_packs;
> diff --git gcc/testsuite/g++.dg/cpp0x/alignas9.C gcc/testsuite/g++.dg/cpp0x/alignas9.C
> index e69de29..98fe707 100644
> --- gcc/testsuite/g++.dg/cpp0x/alignas9.C
> +++ gcc/testsuite/g++.dg/cpp0x/alignas9.C
> @@ -0,0 +1,6 @@
> +// PR c++/79653
> +// { dg-do compile { target c++11 } }
> +
> +template <typename... T>
> +struct A { alignas(int...) char c; }; // { dg-error "no argument packs|expected" }
> +A<int, double> a;
>
> Marek