From patchwork Fri Feb 18 16:13:34 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 83621 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id DC8F9B7116 for ; Sat, 19 Feb 2011 03:13:51 +1100 (EST) Received: (qmail 30725 invoked by alias); 18 Feb 2011 16:13:46 -0000 Received: (qmail 30714 invoked by uid 22791); 18 Feb 2011 16:13:44 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from seketeli.net (HELO ms.seketeli.net) (91.121.166.71) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 18 Feb 2011 16:13:38 +0000 Received: from localhost (torimasen.com [82.237.12.13]) by ms.seketeli.net (Postfix) with ESMTP id BA5FDEA040; Fri, 18 Feb 2011 17:09:03 +0100 (CET) Received: from adjoa.seketeli.net (localhost.localdomain [127.0.0.1]) by localhost (Postfix) with ESMTP id 555DB8E6046; Fri, 18 Feb 2011 17:13:34 +0100 (CET) From: Dodji Seketeli To: Jason Merrill Cc: GCC Patches Subject: Re: [PATCH] Fix PR c++/46394 References: <4D4D7C0E.9070402@redhat.com> X-URL: http://www.seketeli.net/~dodji Date: Fri, 18 Feb 2011 17:13:34 +0100 In-Reply-To: (Dodji Seketeli's message of "Mon, 07 Feb 2011 14:26:06 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Dodji Seketeli a écrit: > Jason Merrill writes: > >> It seems to me that rather than try hard to make the pre-fixup parm >> compare equal to the post-fixup parm, we could just drop the >> same_type_p/cp_tree_equal check in tsubst_pack_expansion and clear >> arg_pack if the argument is an expansion of *any* parameter pack. After looking into this a bit more, here is a patch along these lines. When comparing an argument pack "arg_pack" [an argument pack whose sole element is an expansion of the parameter P] with a parameter pack P', it checks if P and P' have the same DECL. It looks like this would be a good enough approximation, given that the instances of "arg_pack" are created by template_parm_to_arg, AIUI. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4990636..edb1465 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8717,13 +8717,24 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, { tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0); tree pattern = PACK_EXPANSION_PATTERN (expansion); - if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack)) - || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern))) - /* The argument pack that the parameter maps to is just an - expansion of the parameter itself, such as one would - find in the implicit typedef of a class inside the - class itself. Consider this parameter "unsubstituted", - so that we will maintain the outer pack expansion. */ + if ((/* If ARG_PACK is a type parameter pack named by the + same DECL as parm_pack ... */ + (TYPE_P (pattern) + && TYPE_P (parm_pack) + && TYPE_NAME (pattern) == TYPE_NAME (parm_pack)) + /* ... or if ARG_PACK is a non-type parameter + named by the same DECL as parm_pack ... */ + || (TREE_CODE (pattern) == TEMPLATE_PARM_INDEX + && TREE_CODE (parm_pack) == PARM_DECL + && TEMPLATE_PARM_DECL (pattern) + == TEMPLATE_PARM_DECL (DECL_INITIAL (parm_pack)))) + && template_parameter_pack_p (pattern)) + /* ... then the argument pack that the parameter maps to + is just an expansion of the parameter itself, such as + one would find in the implicit typedef of a class + inside the class itself. Consider this parameter + "unsubstituted", so that we will maintain the outer + pack expansion. */ arg_pack = NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/template/typedef38.C b/gcc/testsuite/g++.dg/template/typedef38.C new file mode 100644 index 0000000..1c76404 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef38.C @@ -0,0 +1,27 @@ +// Origin: PR c++/46394 +// { dg-options "-std=c++0x" } +// { dg-do "compile" } + +template +struct S0 +{ + typedef T type; +}; + +template +struct S1 +{ + typedef int I; +}; + +struct A +{ + template::type...>::I> + A(U...u); +}; + +int +main() +{ + A a(1, 2); +}