From patchwork Thu Aug 8 19:54:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 265804 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 434A62C00A0 for ; Fri, 9 Aug 2013 05:54:24 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=TeDZyDBWKEvzcsNVOkctXgY4oBosmbcjriIWKk8B/yl WE9wTWFXbEM+xMLCFe0q8X3KcqoDPI/1YpHRZCqbUNtG85vTlmBO3RChE3YU5W8k kMXTs41pTJzfMiB3Dd/p6m9dMkAgL+Pa+jLq9aVq/n4lWJwwoG2lZN6Q+ElxvwPY = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=aLSZhgogP5nxQj1l9Qasq2eytO4=; b=bRd/k3dfH0/ePjl3O 0RmNFHvMm8PDXr29jW0pDmFdlehXHe49T/UhnzndkT43lqFB65dkGIM5nf1Iw1/E HPJVs2K5Y3moBcq1ORB7I01G+E5KoodSVPbVgks9ozJpPSreXkssceXz41vbjXCj N+1l97B1DRl23KtRvyG4dt6/zw= Received: (qmail 28365 invoked by alias); 8 Aug 2013 19:54:17 -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 28355 invoked by uid 89); 8 Aug 2013 19:54:16 -0000 X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_20, RCVD_IN_DNSWL_MED, RCVD_IN_HOSTKARMA_YE, RDNS_NONE, SPF_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from Unknown (HELO aserp1040.oracle.com) (141.146.126.69) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 08 Aug 2013 19:54:15 +0000 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r78Js6gS020013 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 8 Aug 2013 19:54:07 GMT Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r78Js5H7024915 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 8 Aug 2013 19:54:06 GMT Received: from abhmt115.oracle.com (abhmt115.oracle.com [141.146.116.67]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r78Js5gh021085; Thu, 8 Aug 2013 19:54:05 GMT Received: from poldo4.casa (/79.52.193.87) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 08 Aug 2013 12:54:04 -0700 Message-ID: <5203F75A.9080206@oracle.com> Date: Thu, 08 Aug 2013 21:54:02 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130620 Thunderbird/17.0.7 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ RFC / Patch] PR 54080, PR 52875 and more (aka SFINAE vs template recursion depth) X-Virus-Found: No Hi, this is, IMHO, a rather interesting issue. I was working on PR 54080, where currently with ICE pretty badly for Error reporting routines re-entered without producing any sensible error message. Figured out that the core of the issue are the error messages in push_tinst_level about template instantiation depth exceeded. Drafted the attached, the error message is great with no ICE: 54080.C: In instantiation of ‘decltype (foo class vector>(foo(input, func1), funcrest)) foo(const vector&, const Func1&, FuncRest) [with OutType = vector; Func1 = int; FuncRest = int; decltype (foo(foo(input, func1), funcrest)) = vector]’: 54080.C:25:22: required from here 54080.C:19:2: error: return-statement with no value, in function returning ‘vector’ [-fpermissive] return; when I ran the testsuite, I found something (tidied): FAIL: g++.dg/cpp0x/decltype26.C (test for errors, line 6) FAIL: g++.dg/cpp0x/decltype26.C (test for excess errors) FAIL: g++.dg/cpp0x/decltype28.C (test for errors, line 11) FAIL: g++.dg/cpp0x/decltype28.C (test for warnings, line 15) FAIL: g++.dg/cpp0x/decltype29.C (test for errors, line 12) FAIL: g++.dg/cpp0x/decltype29.C (test for excess errors) the really interesting one is decltype28.C, which we don't reject anymore, we simply accept it. What is happening is that the overload which leads to excessive template instantiation depth is SFINAE-ed away and the other one "wins"! Thus, this is the core of my message: it seems that we behave wrt this issue - SFINAE vs template instantiation depth - in a different way vs current clang++ and icc: we produce hard error messages in SFINAE contexts. Is that intended? I find the issue interesting, arguably a template instantiation depth exceeded isn't just like any other error. With the attached draft we handle quite a few other testcases I have seen around in a different way, for example c++/52875 is automatically fixed (assuming we want to behave like clang++ and icc). Thanks! Paolo. Index: cp-tree.h =================================================================== --- cp-tree.h (revision 201588) +++ cp-tree.h (working copy) @@ -5541,7 +5541,7 @@ extern tree fold_non_dependent_expr_sfinae (tree, extern bool alias_type_or_template_p (tree); extern bool alias_template_specialization_p (const_tree); extern bool explicit_class_specialization_p (tree); -extern int push_tinst_level (tree); +extern int push_tinst_level (tree, tsubst_flags_t); extern void pop_tinst_level (void); extern struct tinst_level *outermost_tinst_level(void); extern void init_template_processing (void); Index: mangle.c =================================================================== --- mangle.c (revision 201588) +++ mangle.c (working copy) @@ -3429,7 +3429,7 @@ mangle_decl_string (const tree decl) { struct tinst_level *tl = current_instantiation (); if ((!tl || tl->decl != decl) - && push_tinst_level (decl)) + && push_tinst_level (decl, tf_warning_or_error)) { template_p = true; saved_fn = current_function_decl; Index: pt.c =================================================================== --- pt.c (revision 201588) +++ pt.c (working copy) @@ -6995,7 +6995,7 @@ add_pending_template (tree d) level = !current_tinst_level || current_tinst_level->decl != d; if (level) - push_tinst_level (d); + push_tinst_level (d, tf_warning_or_error); pt = ggc_alloc_pending_template (); pt->next = NULL; @@ -8021,24 +8021,28 @@ static GTY(()) struct tinst_level *last_error_tins for diagnostics and to restore it later. */ int -push_tinst_level (tree d) +push_tinst_level (tree d, tsubst_flags_t complain) { struct tinst_level *new_level; if (tinst_depth >= max_tinst_depth) { last_error_tinst_level = current_tinst_level; - if (TREE_CODE (d) == TREE_LIST) - error ("template instantiation depth exceeds maximum of %d (use " - "-ftemplate-depth= to increase the maximum) substituting %qS", - max_tinst_depth, d); - else - error ("template instantiation depth exceeds maximum of %d (use " - "-ftemplate-depth= to increase the maximum) instantiating %qD", - max_tinst_depth, d); - print_instantiation_context (); + if (complain & tf_error) + { + if (TREE_CODE (d) == TREE_LIST) + error ("template instantiation depth exceeds maximum of %d (use " + "-ftemplate-depth= to increase the maximum) " + "substituting %qS", max_tinst_depth, d); + else + error ("template instantiation depth exceeds maximum of %d (use " + "-ftemplate-depth= to increase the maximum) " + "instantiating %qD", max_tinst_depth, d); + print_instantiation_context (); + } + return 0; } @@ -8691,7 +8695,7 @@ instantiate_class_template_1 (tree type) return type; /* If we've recursively instantiated too many templates, stop. */ - if (! push_tinst_level (type)) + if (! push_tinst_level (type, tf_warning_or_error)) return type; /* Now we're really doing the instantiation. Mark the type as in @@ -15005,7 +15009,7 @@ instantiate_alias_template (tree tmpl, tree args, if (tmpl == error_mark_node || args == error_mark_node) return error_mark_node; tree tinst = build_tree_list (tmpl, args); - if (!push_tinst_level (tinst)) + if (!push_tinst_level (tinst, complain)) { ggc_free (tinst); return error_mark_node; @@ -15219,7 +15223,7 @@ fn_type_unification (tree fn, } TREE_VALUE (tinst) = explicit_targs; - if (!push_tinst_level (tinst)) + if (!push_tinst_level (tinst, complain)) { excessive_deduction_depth = true; goto fail; @@ -15270,7 +15274,7 @@ fn_type_unification (tree fn, any errors (e.g. from class instantiations triggered by instantiation of default template arguments) come from. If we are explaining, this context is redundant. */ - if (!explain_p && !push_tinst_level (tinst)) + if (!explain_p && !push_tinst_level (tinst, complain)) { excessive_deduction_depth = true; goto fail; @@ -15327,7 +15331,7 @@ fn_type_unification (tree fn, substitution results in an invalid type, as described above, type deduction fails. */ TREE_VALUE (tinst) = targs; - if (!push_tinst_level (tinst)) + if (!push_tinst_level (tinst, complain)) { excessive_deduction_depth = true; goto fail; @@ -18876,7 +18880,7 @@ maybe_instantiate_noexcept (tree fn) if (TREE_CODE (noex) == DEFERRED_NOEXCEPT) { - if (push_tinst_level (fn)) + if (push_tinst_level (fn, tf_warning_or_error)) { push_access_scope (fn); push_deferring_access_checks (dk_no_deferred); @@ -19000,7 +19004,7 @@ instantiate_decl (tree d, int defer_ok, || spec == NULL_TREE); /* This needs to happen before any tsubsting. */ - if (! push_tinst_level (d)) + if (! push_tinst_level (d, tf_warning_or_error)) return d; timevar_push (TV_TEMPLATE_INST); Index: typeck2.c =================================================================== --- typeck2.c (revision 201588) +++ typeck2.c (working copy) @@ -1564,7 +1564,7 @@ build_x_arrow (location_t loc, tree expr, tsubst_f return error_mark_node; if (fn && DECL_USE_TEMPLATE (fn)) - push_tinst_level (fn); + push_tinst_level (fn, complain); fn = NULL; if (vec_member (TREE_TYPE (expr), types_memoized))