From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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-Archive: List-Post: List-Help: Sender: gcc-patches-owner@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 12:05:00 -0000 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> X-SW-Source: 2015-06/txt/msg01937.txt.bz2 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