From patchwork Tue Dec 13 17:49:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 87920 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp2334070qgi; Tue, 13 Dec 2016 09:50:28 -0800 (PST) X-Received: by 10.99.159.26 with SMTP id g26mr178850299pge.62.1481651428833; Tue, 13 Dec 2016 09:50:28 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id j190si48683615pgd.278.2016.12.13.09.50.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Dec 2016 09:50:28 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-444320-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-444320-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-444320-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=UfGMf8Ymw65/Xjwxq Kxya3RdBhfGSh9FIfqz3XHU3jh1/nomxsK1CG+qU6tYi0Sdwl1Ze3O7D+ZHqxyMU 6l7eb91WXxTx0347MBAA+VSUCaA1OJMSo3soLF/i2RfsXXr0t9D2jxHzBZU9gZtS RZIGtTdXrU7YkAWsc0NeOE2uY4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=2nLv2vSuwQLLnD11mCFy73H 79kY=; b=Bds26848wEr8NxC4i6bqIaJgSMxgnDEdFxZNg9JO1ZVXFedvOSL1rVz iHwkVXe1xsmcOk5gYIBneKqrNVsWrFIVbubKCmkqQnjJtMeuo3Nq4ECghLBEpfFz VyAos/eajiFWUEFmH/UWyK5t2jY5pDrpdZ+976nVzXWcV1hxUoDc= Received: (qmail 71016 invoked by alias); 13 Dec 2016 17:50:13 -0000 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 Received: (qmail 70994 invoked by uid 89); 13 Dec 2016 17:50:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=tmpl, FOUND, sk:DECL_LA, sk:decl_la X-HELO: mail-yb0-f195.google.com Received: from mail-yb0-f195.google.com (HELO mail-yb0-f195.google.com) (209.85.213.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Dec 2016 17:50:02 +0000 Received: by mail-yb0-f195.google.com with SMTP id d128so2414172ybh.3 for ; Tue, 13 Dec 2016 09:50:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:subject:to:references:cc:from:message-id :date:user-agent:mime-version:in-reply-to; bh=TmZbQ5zbwKtHaDNYybTdtoA06mpR5fqEvPuW7aULmCU=; b=RPyeZvhv4mT5gs2QgLhcGMtNlshqj2A5lBL/38RaQrZGUCD8BrtUm004SgabZNrqfq +uuqlarIV7uADRPLkj+bTAv5lZATHKuJTiOGmkDHMkAGcofdAsahGmQW6DlI46YVPIjv wOqQpJ9r8xJFHaHNYLlXWZsXf1CydN16IhH2LVRdLRR+1JYhHgJ5nVCzxu0yJHbTQ1Zo 2SfmBQfiPfzzS9gjmSKe0ymmqm+2N9FJxwD4PbZXkEmAmFx9rrJ3ikizqO6MbMO/eyjG IGDk2gOQCpQCPwc56Dt41sVVrz7ws1l9XoufUBSuK+hTUAySby82Kr1XK19A8WBJBq3Y CNHw== X-Gm-Message-State: AKaTC00Z5kwLaRQJ5JN0QVOhVA9QXGI7zFaTfI5xCXaVl9WLKBtgZUlHN6yCjz6mED1Wxg== X-Received: by 10.37.163.197 with SMTP id e63mr45284862ybi.125.1481651401083; Tue, 13 Dec 2016 09:50:01 -0800 (PST) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::640]) by smtp.googlemail.com with ESMTPSA id h14sm19868381ywa.9.2016.12.13.09.50.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Dec 2016 09:50:00 -0800 (PST) Subject: Re: [C++ PATCH] c++/78776 fix alias template ICE To: Jason Merrill References: Cc: GCC Patches From: Nathan Sidwell Message-ID: Date: Tue, 13 Dec 2016 12:49:59 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: On 12/12/2016 10:28 PM, Jason Merrill wrote: > I suspect that most uses don't need to change. Indeed. This addresses the ones I could find. Both by grepping pt.c and fixing subsequent test fall out. took the opportunity to make the control flow in get_underlying_template somewhat clearer. I don't think there's anything unsurprising in this patch. ok? nathan -- Nathan Sidwell 2016-12-12 Nathan Sidwell PR c++/69481 * cp-tree.h (TYPE_TEMPLATE_INFO): Remove alias type checking. (TYPE_ALIAS_TEMPLATE_INFO): New. (TYPE_TEMPLATE_INFO_MAYBE_ALIAS): New. Use those macros. * error.c (dump_alias_template_specialization): Adjust. * pt.c (maybe_process_partial_specialization, iterative_has_template_arg, find_parameter_packs_r, alias_template_specialization_p, dependent_alias_template_spec_p, get_underlying_template, lookup_template_class_1, unify): Adjust template using decl access. PR c++/69481 * g++.dg/cpp0x/pr69481.C: New. Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 243604) +++ cp/cp-tree.h (working copy) @@ -3038,23 +3038,30 @@ extern void decl_shadowed_for_var_insert ->template_info) /* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or - BOUND_TEMPLATE_TEMPLATE_PARM type. Note that if NODE is a - specialization of an alias template, this accessor returns the - template info for the alias template, not the one (if any) for the - template of the underlying type. */ + BOUND_TEMPLATE_TEMPLATE_PARM type. This ignores any alias + templateness of NODE. */ #define TYPE_TEMPLATE_INFO(NODE) \ - ((TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \ - ? (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \ - ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \ - : NULL_TREE) \ - : ((TREE_CODE (NODE) == ENUMERAL_TYPE) \ - ? ENUM_TEMPLATE_INFO (NODE) \ - : ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \ - ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ - : (CLASS_TYPE_P (NODE) \ - ? CLASSTYPE_TEMPLATE_INFO (NODE) \ - : NULL_TREE)))) + (TREE_CODE (NODE) == ENUMERAL_TYPE \ + ? ENUM_TEMPLATE_INFO (NODE) \ + : (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \ + ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ + : (CLASS_TYPE_P (NODE) \ + ? CLASSTYPE_TEMPLATE_INFO (NODE) \ + : NULL_TREE))) +/* Template information for an alias template type. */ +#define TYPE_ALIAS_TEMPLATE_INFO(NODE) \ + (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \ + ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \ + : NULL_TREE) + +/* If NODE is a specialization of an alias template, this accessor + returns the template info for the alias template. Otherwise behave + as TYPE_TEMPLATE_INFO. */ +#define TYPE_TEMPLATE_INFO_MAYBE_ALIAS(NODE) \ + (TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \ + ? TYPE_ALIAS_TEMPLATE_INFO (NODE) \ + : TYPE_TEMPLATE_INFO (NODE)) /* Set the template information for an ENUMERAL_, RECORD_, or UNION_TYPE to VAL. */ Index: cp/error.c =================================================================== --- cp/error.c (revision 243604) +++ cp/error.c (working copy) @@ -365,15 +365,13 @@ dump_template_bindings (cxx_pretty_print static void dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags) { - tree name; - gcc_assert (alias_template_specialization_p (t)); + tree decl = TYPE_NAME (t); if (!(flags & TFF_UNQUALIFIED_NAME)) - dump_scope (pp, CP_DECL_CONTEXT (TYPE_NAME (t)), flags); - name = TYPE_IDENTIFIER (t); - pp_cxx_tree_identifier (pp, name); - dump_template_parms (pp, TYPE_TEMPLATE_INFO (t), + dump_scope (pp, CP_DECL_CONTEXT (decl), flags); + pp_cxx_tree_identifier (pp, DECL_NAME (decl)); + dump_template_parms (pp, DECL_TEMPLATE_INFO (decl), /*primary=*/false, flags & ~TFF_TEMPLATE_HEADER); } Index: cp/pt.c =================================================================== --- cp/pt.c (revision 243604) +++ cp/pt.c (working copy) @@ -940,10 +940,11 @@ maybe_process_partial_specialization (tr if (TYPE_ALIAS_P (type)) { - if (TYPE_TEMPLATE_INFO (type) - && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (type))) + tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (type); + + if (tinfo && DECL_ALIAS_TEMPLATE_P (TI_TEMPLATE (tinfo))) error ("specialization of alias template %qD", - TYPE_TI_TEMPLATE (type)); + TI_TEMPLATE (tinfo)); else error ("explicit specialization of non-template %qT", type); return error_mark_node; @@ -1829,7 +1830,7 @@ iterative_hash_template_arg (tree arg, h // left alone, or untouched specializations because // coerce_template_parms returns the unconverted template // arguments if it sees incomplete argument packs. - tree ti = TYPE_TEMPLATE_INFO (arg); + tree ti = TYPE_ALIAS_TEMPLATE_INFO (arg); return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti)); } if (TYPE_CANONICAL (arg)) @@ -3459,8 +3460,8 @@ find_parameter_packs_r (tree *tp, int *w /* Handle type aliases/typedefs. */ if (TYPE_ALIAS_P (t)) { - if (TYPE_TEMPLATE_INFO (t)) - cp_walk_tree (&TYPE_TI_ARGS (t), + if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t)) + cp_walk_tree (&TI_ARGS (tinfo), &find_parameter_packs_r, ppd, ppd->visited); *walk_subtrees = 0; @@ -5794,15 +5795,9 @@ alias_template_specialization_p (const_t /* It's an alias template specialization if it's an alias and its TYPE_NAME is a specialization of a primary template. */ if (TYPE_ALIAS_P (t)) - { - tree name = TYPE_NAME (t); - if (DECL_LANG_SPECIFIC (name)) - if (tree ti = DECL_TEMPLATE_INFO (name)) - { - tree tmpl = TI_TEMPLATE (ti); - return PRIMARY_TEMPLATE_P (tmpl); - } - } + if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t)) + return PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)); + return false; } @@ -5854,10 +5849,18 @@ complex_alias_template_p (const_tree tmp bool dependent_alias_template_spec_p (const_tree t) { - return (alias_template_specialization_p (t) - && TEMPLATE_DECL_COMPLEX_ALIAS_P (DECL_TI_TEMPLATE (TYPE_NAME (t))) - && (any_dependent_template_arguments_p - (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t))))); + if (!alias_template_specialization_p (t)) + return false; + + tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t); + if (!TEMPLATE_DECL_COMPLEX_ALIAS_P (TI_TEMPLATE (tinfo))) + return false; + + tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)); + if (!any_dependent_template_arguments_p (args)) + return false; + + return true; } /* Return the number of innermost template parameters in TMPL. */ @@ -5879,26 +5882,27 @@ get_underlying_template (tree tmpl) gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); while (DECL_ALIAS_TEMPLATE_P (tmpl)) { - tree result = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); - if (TYPE_TEMPLATE_INFO (result)) - { - tree sub = TYPE_TI_TEMPLATE (result); - if (PRIMARY_TEMPLATE_P (sub) - && (num_innermost_template_parms (tmpl) - == num_innermost_template_parms (sub))) - { - tree alias_args = INNERMOST_TEMPLATE_ARGS - (template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl))); - if (!comp_template_args (TYPE_TI_ARGS (result), alias_args)) - break; - /* The alias type is equivalent to the pattern of the - underlying template, so strip the alias. */ - tmpl = sub; - continue; - } - } - break; + /* Determine if the alias is equivalent to an underlying template. */ + tree orig_type = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); + tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (orig_type); + if (!tinfo) + break; + + tree underlying = TI_TEMPLATE (tinfo); + if (!PRIMARY_TEMPLATE_P (underlying) + || (num_innermost_template_parms (tmpl) + != num_innermost_template_parms (underlying))) + break; + + tree alias_args = INNERMOST_TEMPLATE_ARGS + (template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl))); + if (!comp_template_args (TI_ARGS (tinfo), alias_args)) + break; + + /* Alias is equivalent. Strip it and repeat. */ + tmpl = underlying; } + return tmpl; } @@ -8375,9 +8379,8 @@ lookup_template_class_1 (tree d1, tree a TEMPLATE will be `template template struct S1::S2'. We must fill in the missing arguments. */ - arglist - = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)), - arglist); + tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (templ)); + arglist = add_outermost_template_args (TI_ARGS (ti), arglist); arg_depth = TMPL_ARGS_DEPTH (arglist); } @@ -8407,13 +8410,15 @@ lookup_template_class_1 (tree d1, tree a the `C' is just the same as `C'. Outside of the class, however, such a reference is an instantiation. */ - if ((entering_scope - || !PRIMARY_TEMPLATE_P (gen_tmpl) - || currently_open_class (template_type)) - /* comp_template_args is expensive, check it last. */ - && comp_template_args (TYPE_TI_ARGS (template_type), - arglist)) - return template_type; + if (entering_scope + || !PRIMARY_TEMPLATE_P (gen_tmpl) + || currently_open_class (template_type)) + { + tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (template_type); + + if (comp_template_args (TI_ARGS (tinfo), arglist)) + return template_type; + } /* If we already have this specialization, return it. */ elt.tmpl = gen_tmpl; @@ -8641,12 +8646,11 @@ lookup_template_class_1 (tree d1, tree a && CLASS_TYPE_P (context) && !same_type_p (context, DECL_CONTEXT (gen_tmpl))) { - tree partial_inst_args; TREE_VEC_LENGTH (arglist)--; ++processing_template_decl; - partial_inst_args = - tsubst (INNERMOST_TEMPLATE_ARGS - (TYPE_TI_ARGS (TREE_TYPE (gen_tmpl))), + tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (gen_tmpl)); + tree partial_inst_args = + tsubst (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)), arglist, complain, NULL_TREE); --processing_template_decl; TREE_VEC_LENGTH (arglist)++; @@ -8678,11 +8682,11 @@ lookup_template_class_1 (tree d1, tree a for parameters in the TYPE_DECL of the alias template done earlier. So be careful while getting the template of FOUND. */ - found = TREE_CODE (found) == TEMPLATE_DECL - ? found - : TREE_CODE (found) == TYPE_DECL - ? TYPE_TI_TEMPLATE (TREE_TYPE (found)) - : CLASSTYPE_TI_TEMPLATE (found); + found = (TREE_CODE (found) == TEMPLATE_DECL + ? found + : (TREE_CODE (found) == TYPE_DECL + ? DECL_TI_TEMPLATE (found) + : CLASSTYPE_TI_TEMPLATE (found))); } // Build template info for the new specialization. @@ -20035,10 +20039,13 @@ unify (tree tparms, tree targs, tree par return unify_template_deduction_failure (explain_p, parm, arg); { tree parmvec = TYPE_TI_ARGS (parm); + /* An alias template name is never deduced. */ if (TYPE_ALIAS_P (arg)) arg = strip_typedefs (arg); - tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg)); + + tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (arg); + tree argvec = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)); tree full_argvec = add_to_template_args (targs, argvec); tree parm_parms = DECL_INNERMOST_TEMPLATE_PARMS Index: testsuite/g++.dg/cpp0x/pr69481.C =================================================================== --- testsuite/g++.dg/cpp0x/pr69481.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr69481.C (working copy) @@ -0,0 +1,26 @@ +// PR c++/69481 +// { dg-do compile { target c++11 } } + +// ICE with canonical type verification + +template struct Traits; + +template +struct Bob { + using Loc = Traits; + using typename Loc::Thing; + + Thing Foo (); +}; + +template struct tt +{ + using ut = tt; + ut Bob (); +}; + +template +tt tt::Bob () +{ + return tt(); +}