From patchwork Fri Jan 11 16:33:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 211378 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 AA1DB2C032B for ; Sat, 12 Jan 2013 03:33:29 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1358526809; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Cc:Subject:References:Date:In-Reply-To: Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=etCzDH3CFfWNhd3bbp65yALJe2Q=; b=fuwZhRIePs23pNreYJLcXzJvSpGiD4d1N2ZEKukhpUGTnaydxwyjK9xtt58H63 IwFgsvqHy4ABw11b7GhmNmtUEQ89rLxQYk5XPKu04VYYSE/Hz+W814023H40E1LG drcl7kxe4oo81/BGVhI7sSTb5n9d21bdWpIAnilcvEE64= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Cc:Subject:References:X-URL:Date:In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=j55fDPnBFH0MmBItluHgGwlnrmUPcAQYxJyJJKV8/5qtTWvUyBgIWc61bIEsp5 keDsjDpmZIhnh1usPvz8JkODPIDrtjbiYaIoPm8SpR53CMDhOs2UOQBcgU3IVcn4 cZnZvOGRKkQE5vc4CkTS5NSWyjFQH7GZyCS0htH1VpmEs=; Received: (qmail 25447 invoked by alias); 11 Jan 2013 16:33:18 -0000 Received: (qmail 25434 invoked by uid 22791); 11 Jan 2013 16:33:15 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 11 Jan 2013 16:33:10 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r0BGXAVR029497 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 11 Jan 2013 11:33:10 -0500 Received: from localhost (ovpn-116-53.ams2.redhat.com [10.36.116.53]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r0BGX86c028145 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 11 Jan 2013 11:33:09 -0500 Received: by localhost (Postfix, from userid 1000) id B1AD39F1A4; Fri, 11 Jan 2013 17:33:07 +0100 (CET) From: Dodji Seketeli To: Jason Merrill Cc: Gabriel Dos Reis , GCC Patches Subject: Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg References: <877gnnwzdg.fsf@redhat.com> <87hamqtlum.fsf@redhat.com> <87k3rlrrkw.fsf@redhat.com> <87fw28ovh5.fsf@redhat.com> <50F01BC3.1030703@redhat.com> X-URL: http://www.redhat.com Date: Fri, 11 Jan 2013 17:33:07 +0100 In-Reply-To: <50F01BC3.1030703@redhat.com> (Jason Merrill's message of "Fri, 11 Jan 2013 09:03:47 -0500") Message-ID: <877gnjof24.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) MIME-Version: 1.0 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 Jason Merrill writes: > On 01/11/2013 05:38 AM, Dodji Seketeli wrote: >> but when I read the code, it looks like this is not necessary. Am I >> missing something? In any case, I haven't put that code in the new >> coerce_innermost_template_parms. Is that OK? > > I agree that it seems unnecessary. But to be safe, let's leave > lookup_template_class_1 alone until after 4.8 branches. OK, here are the patches I am proposing then. The first one is the one I'd like to commit to 4.8 and the second one would be scheduled for 4.9 when its branch opens. Is that OK? gcc/cp/ PR c++/55663 * pt.c (coerce_innermost_template_parms): New static function. (instantiate_alias_template): Use it here. gcc/testsuite/ PR c++/55663 * g++.dg/cpp0x/alias-decl-31.C: New test. --- gcc/cp/pt.c | 64 ++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C | 20 ++++++++++ 2 files changed, 84 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6d78dd2..62fa2d9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -130,6 +130,8 @@ static tree tsubst_initializer_list (tree, tree); static tree get_class_bindings (tree, tree, tree, tree); static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, bool, bool); +static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t, + bool, bool); static void tsubst_enum (tree, tree, tree); static tree add_to_template_args (tree, tree); static tree add_outermost_template_args (tree, tree); @@ -6742,6 +6744,61 @@ coerce_template_parms (tree parms, return new_inner_args; } +/* Like coerce_template_parms. If PARMS represents all template + parameters levels, this function returns a vector of vectors + representing all the resulting argument levels. Note that in this + case, only the innermost arguments are coerced because the + outermost ones are supposed to have been coerced already. + + Otherwise, if PARMS represents only (the innermost) vector of + parameters, this function returns a vector containing just the + innermost resulting arguments. */ + +static tree +coerce_innermost_template_parms (tree parms, + tree args, + tree in_decl, + tsubst_flags_t complain, + bool require_all_args, + bool use_default_args) +{ + int parms_depth = TMPL_PARMS_DEPTH (parms); + int args_depth = TMPL_ARGS_DEPTH (args); + tree coerced_args; + + if (parms_depth > 1) + { + coerced_args = make_tree_vec (parms_depth); + tree level; + int cur_depth; + + for (level = parms, cur_depth = parms_depth; + parms_depth > 0 && level != NULL_TREE; + level = TREE_CHAIN (level), --cur_depth) + { + tree l; + if (cur_depth == args_depth) + l = coerce_template_parms (TREE_VALUE (level), + args, in_decl, complain, + require_all_args, + use_default_args); + else + l = TMPL_ARGS_LEVEL (args, cur_depth); + + if (l == error_mark_node) + return error_mark_node; + + SET_TMPL_ARGS_LEVEL (coerced_args, cur_depth, l); + } + } + else + coerced_args = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parms), + args, in_decl, complain, + require_all_args, + use_default_args); + return coerced_args; +} + /* Returns 1 if template args OT and NT are equivalent. */ static int @@ -14642,6 +14699,13 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain) ggc_free (tinst); return error_mark_node; } + + args = + coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl), + args, tmpl, complain, + /*require_all_args=*/true, + /*use_default_args=*/true); + tree r = instantiate_template (tmpl, args, complain); pop_tinst_level (); /* We can't free this if a pending_template entry or last_error_tinst_level diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C new file mode 100644 index 0000000..83eea47 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C @@ -0,0 +1,20 @@ +// Origin: PR c++/55663 +// { dg-do compile { target c++11 } } + +template +constexpr bool the_truth () { return true; } + +template + struct Takes_bool { }; + +template + using Alias = Takes_bool; + +template + struct test { using type = Alias()>; }; + +int main () { + test a; + + return 0; +} -- 1.7.11.7 gcc/cp/ * pt.c (lookup_template_class_1): Use coerce_inner_template_parms here for the sake of ease of maintenance. --- gcc/cp/pt.c | 65 ++++++++----------------------------------------------------- 1 file changed, 8 insertions(+), 57 deletions(-) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 62fa2d9..3c63407 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7226,63 +7226,14 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, /* From here on, we're only interested in the most general template. */ - /* Calculate the BOUND_ARGS. These will be the args that are - actually tsubst'd into the definition to create the - instantiation. */ - if (parm_depth > 1) - { - /* We have multiple levels of arguments to coerce, at once. */ - int i; - int saved_depth = TMPL_ARGS_DEPTH (arglist); - - tree bound_args = make_tree_vec (parm_depth); - - for (i = saved_depth, - t = DECL_TEMPLATE_PARMS (gen_tmpl); - i > 0 && t != NULL_TREE; - --i, t = TREE_CHAIN (t)) - { - tree a; - if (i == saved_depth) - a = coerce_template_parms (TREE_VALUE (t), - arglist, gen_tmpl, - complain, - /*require_all_args=*/true, - /*use_default_args=*/true); - else - /* Outer levels should have already been coerced. */ - a = TMPL_ARGS_LEVEL (arglist, i); - - /* Don't process further if one of the levels fails. */ - if (a == error_mark_node) - { - /* Restore the ARGLIST to its full size. */ - TREE_VEC_LENGTH (arglist) = saved_depth; - return error_mark_node; - } - - SET_TMPL_ARGS_LEVEL (bound_args, i, a); - - /* We temporarily reduce the length of the ARGLIST so - that coerce_template_parms will see only the arguments - corresponding to the template parameters it is - examining. */ - TREE_VEC_LENGTH (arglist)--; - } - - /* Restore the ARGLIST to its full size. */ - TREE_VEC_LENGTH (arglist) = saved_depth; - - arglist = bound_args; - } - else - arglist - = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), - INNERMOST_TEMPLATE_ARGS (arglist), - gen_tmpl, - complain, - /*require_all_args=*/true, - /*use_default_args=*/true); + /* Convert the innermost template arguments to their appropriate + types. These will be the arguments that are actually + tsubst'd into the definition to create the instantiation. */ + arglist = + coerce_innermost_template_parms (parmlist, arglist, + gen_tmpl, complain, + /*require_all_args=*/true, + /*use_default_args=*/true); if (arglist == error_mark_node) /* We were unable to bind the arguments. */