From patchwork Fri Jun 26 11:40:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 488753 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2EC18140081 for ; Fri, 26 Jun 2015 21:41:21 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=dCyera8A; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=Um4DK0yZFo8JGLL5WFCeBZu8qrT5zvUs6iClJ2BCy4oJTj2q/mNJ9 4V2CUnFtbia6VkqmolGmp2a5ffsb8yuPjapK8tVQO1CuDEL9uyMCH3paMnbXHqnU RlJayZxU9tASJjek6lJpuhz/Z/O744QGKkyokaoVbckNkInSsWJZYU= 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:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=UaFjJe2kG8sdJwLxTMKn2hqUcII=; b=dCyera8AZ8NzHTGvSdhZ oNQwE4GO7EpPOQZkg7Wx5R9ZhByBpOZbt/7VWdyVaVaH9mJ8KLQeuN5EmK7yRJvD hoqgmEoUzli+i+84l5tg7PQ11T7IENHlE5/3h/NQB0xVQDwWkPeCoqTrOQYctk3j dsV07BHdH3JLukuUTt0D05s= Received: (qmail 96947 invoked by alias); 26 Jun 2015 11:41:12 -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 96935 invoked by uid 89); 26 Jun 2015 11:41:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: mail-qg0-f53.google.com Received: from mail-qg0-f53.google.com (HELO mail-qg0-f53.google.com) (209.85.192.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 26 Jun 2015 11:41:09 +0000 Received: by qgem68 with SMTP id m68so97318qge.0 for ; Fri, 26 Jun 2015 04:41:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=28+p5XEjyROxdMcEyYtVHh22dMttZCZTmrYRQ42LF8k=; b=lpO0a9kOIg94OqhVsr+rqmWnki6wbPhNImnW8ywseMRGyGf3MfHPSLbxeMjXbaKocj xcITNRwGh7Fh+kSfQsB9pndEH9mkJGU0QfsreDfxd2iYL11qXl6IpmJaEbJkesJvm71G +x6DyezrZbtc+tRhZqiVQxqMEVgfj3iCU0AtkRXOc0Kj4Wve5n1AwpFoemSZVR7oTOnj VVHYLeUcpY3fmMoJEKgdC5J7IIzeRC9inin7zZM/OtgI8Yye3seEVDZ/Mk0X6ZQK/yEC xvq17JKe8GW698Ip9ql708BQVDQHmW3rOtNM8ItuRY49aleNAaUDxQAjPCGwF7F9pjtz n/Cg== X-Gm-Message-State: ALoCoQm7CfKASrnhlajSvDEmXjsnT0QQeRJh68bv1njUtjzzHI0N+kwQNpgNLoGk4KsiN86LVGfM X-Received: by 10.55.31.85 with SMTP id f82mr2376726qkf.88.1435318867564; Fri, 26 Jun 2015 04:41:07 -0700 (PDT) Received: from localhost.localdomain (ool-4353acd8.dyn.optonline.net. [67.83.172.216]) by mx.google.com with ESMTPSA id 63sm6670059qkt.27.2015.06.26.04.41.06 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jun 2015 04:41:06 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] Fix PR c++/30044 Date: Fri, 26 Jun 2015 07:40:50 -0400 Message-Id: <1435318850-8803-1-git-send-email-patrick@parcs.ath.cx> In-Reply-To: <1434072342-14126-1-git-send-email-patrick@parcs.ath.cx> References: <1434072342-14126-1-git-send-email-patrick@parcs.ath.cx> Here is a more modest approach to fixing this PR. Instead of updating current_template_parms with each newly processed template parameter, this patch just updates it with a "dummy" parameter level once per parameter list. So now in tsubst(), to fix the reported ICE we just have to avoid substituting a template parameter if it corresponds to an empty "dummy" argument level. One caveat with this approach is that since template template decls will now have dummy parameter levels in their DECL_TEMPLATE_PARMS fields, we have to avoid emitting such dummy levels inside error messages when printing template template parameters. Otherwise the parameter B in template class B> struct Foo { }; would get printed in error messages as template<> template class B> Two new test files are added in this version: shadow2.C, which checks that we emit a shadowing error for identical template parameter names across nested parameter lists, and error55.C, which checks that we correctly emit template template decls in error messages. With this approach the test case provided by Markus no longer takes forever to compile because the added parameter lists are always empty so when doing structural type comparison of a TEMPLATE_TEMPLATE_PARM there is nothing extra to recurse into. Does this approach seem sensible? gcc/cp/ChangeLog: PR c++/30044 * pt.c (begin_template_parm_list): Add a dummy parameter level to current_template_parms. (end_template_parm_list): Remove the dummy parameter level before adding the real one. (tsubst): Don't attempt to substitute for template parameters corresponding to a dummy argument level. (template_parms_to_args): Remove obsolete hack for giving template template arguments the proper level. (splite_late_return_type): Remove obsolete hack for giving template template arguments the proper level. * error.c (dump_template_decl): Don't print dummy template levels. gcc/testsuite/ChangeLog PR c++/30044 * g++.dg/cpp0x/auto45.C: New test. * g++.dg/template/pr30044.C: New test. * g++.dg/template/shadow2.C: New test. * g++.dg/template/error55.C: New test. * g++.dg/template/crash83.C: Accept any error string. * g++.dg/cpp0x/variadic18.C: Adjust to avoid shadowing template parameters. * g++.dg/cpp0x/variadic18.C: Likewise * g++.dg/template/canon-type-13.C: Likewise. * g++.old-deja/g++.pt/ttp42.C: Likewise. * g++.dg/torture/20070621-1.C: Likewise. --- gcc/cp/error.c | 7 ++++++ gcc/cp/pt.c | 32 +++++++++------------------ gcc/testsuite/g++.dg/cpp0x/auto45.C | 5 +++++ gcc/testsuite/g++.dg/cpp0x/variadic18.C | 2 +- gcc/testsuite/g++.dg/cpp0x/variadic19.C | 2 +- gcc/testsuite/g++.dg/template/canon-type-13.C | 2 +- gcc/testsuite/g++.dg/template/crash83.C | 2 +- gcc/testsuite/g++.dg/template/error55.C | 8 +++++++ gcc/testsuite/g++.dg/template/pr30044.C | 14 ++++++++++++ gcc/testsuite/g++.dg/template/shadow2.C | 3 +++ gcc/testsuite/g++.dg/torture/20070621-1.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/ttp42.C | 2 +- 12 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/auto45.C create mode 100644 gcc/testsuite/g++.dg/template/error55.C create mode 100644 gcc/testsuite/g++.dg/template/pr30044.C create mode 100644 gcc/testsuite/g++.dg/template/shadow2.C diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 96fa94d..b21befe 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1296,6 +1296,13 @@ dump_template_decl (cxx_pretty_printer *pp, tree t, int flags) tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); int len = TREE_VEC_LENGTH (inner_parms); + if (len == 0) + { + /* Skip over the dummy template levels of a template template parm. */ + gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM); + continue; + } + pp_cxx_ws_string (pp, "template"); pp_cxx_begin_template_argument_list (pp); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fe5fc14..e7c35d3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -658,6 +658,12 @@ begin_template_parm_list (void) ++processing_template_decl; ++processing_template_parmlist; note_template_header (0); + + /* Add a dummy parameter level while we process the parameter list. */ + current_template_parms + = tree_cons (size_int (processing_template_decl), + make_tree_vec (0), + current_template_parms); } /* This routine is called when a specialization is declared. If it is @@ -3854,6 +3860,9 @@ end_template_parm_list (tree parms) tree parm, next; tree saved_parmlist = make_tree_vec (list_length (parms)); + /* Pop the dummy parameter level and add the real one. */ + current_template_parms = TREE_CHAIN (current_template_parms); + current_template_parms = tree_cons (size_int (processing_template_decl), saved_parmlist, current_template_parms); @@ -3989,21 +3998,6 @@ template_parms_to_args (tree parms) args = a; } - if (length > 1 && TREE_VEC_ELT (args, 0) == NULL_TREE) - /* This can happen for template parms of a template template - parameter, e.g: - - template class TT> struct S; - - Consider the level of the parms of TT; T and U both have - level 2; TT has no template parm of level 1. So in this case - the first element of full_template_args is NULL_TREE. If we - leave it like this TMPL_ARGS_DEPTH on args returns 1 instead - of 2. This will make tsubst wrongly consider that T and U - have level 1. Instead, let's create a dummy vector as the - first element of full_template_args so that TMPL_ARGS_DEPTH - returns the correct depth for args. */ - TREE_VEC_ELT (args, 0) = make_tree_vec (1); return args; } @@ -12029,7 +12023,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) template_parm_level_and_index (t, &level, &idx); levels = TMPL_ARGS_DEPTH (args); - if (level <= levels) + if (level <= levels + && TREE_VEC_LENGTH (TMPL_ARGS_LEVEL (args, level)) > 0) { arg = TMPL_ARG (args, level, idx); @@ -22394,11 +22389,6 @@ splice_late_return_type (tree type, tree late_return_type) return type; argvec = make_tree_vec (1); TREE_VEC_ELT (argvec, 0) = late_return_type; - if (processing_template_parmlist) - /* For a late-specified return type in a template type-parameter, we - need to add a dummy argument level for its parmlist. */ - argvec = add_to_template_args - (make_tree_vec (processing_template_parmlist), argvec); if (current_template_parms) argvec = add_to_template_args (current_template_args (), argvec); return tsubst (type, argvec, tf_warning_or_error, NULL_TREE); diff --git a/gcc/testsuite/g++.dg/cpp0x/auto45.C b/gcc/testsuite/g++.dg/cpp0x/auto45.C new file mode 100644 index 0000000..09e9f44 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto45.C @@ -0,0 +1,5 @@ +// Addendum to auto23.C, now with nested template parameter lists +// { dg-do compile { target c++11 } } + +template