From patchwork Tue Sep 30 13:54:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 394986 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 3441F14007B for ; Tue, 30 Sep 2014 23:54:20 +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:references :in-reply-to:content-type; q=dns; s=default; b=mMxdBbNtIZ1JgZh11 0pPOmw+HHDTCRQEcepOX1WxmLYgSuxKzzLXB0ol6VBRgXfcORy5ExnsEixQm5IuM Adc23FGbNdsOV4ydWTAP1Ahj+p62dqrcTr+Vd1vxvS0qUieoHVkt15Ph1VasEIPk BdWYGBz1eFx7X33MNnx3rcGIKo= 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:references :in-reply-to:content-type; s=default; bh=qwCqko+fIzyzyhq+Y1N3Fj5 mOfc=; b=uemxQ+aLkKjSczssThwIcZ+78DeO+pIZotiBQ4WWP+oaOny91Gn+qbX yZpVT9ciS4wVZ0gjmSuZ/R37Aw2qS3H5VyEBKu+vU4ECUYRGkxcdAOxjJQZXoMHS XHUZysBiC/6O+yCn1ybJHIZl6Oa+raxIS1LsFhRjFqWsC9aVZmss= Received: (qmail 24356 invoked by alias); 30 Sep 2014 13:54:14 -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 24346 invoked by uid 89); 30 Sep 2014 13:54:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: userp1040.oracle.com Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 30 Sep 2014 13:54:10 +0000 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s8UDs8nb031677 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 30 Sep 2014 13:54:08 GMT Received: from aserz7021.oracle.com (aserz7021.oracle.com [141.146.126.230]) by ucsinet22.oracle.com (8.14.5+Sun/8.14.5) with ESMTP id s8UDs7Cj018425 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 30 Sep 2014 13:54:07 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s8UDs6Ga015415; Tue, 30 Sep 2014 13:54:07 GMT Received: from [192.168.1.4] (/79.36.17.55) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 30 Sep 2014 06:54:06 -0700 Message-ID: <542AB5FA.7000905@oracle.com> Date: Tue, 30 Sep 2014 15:54:02 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0 MIME-Version: 1.0 To: =?UTF-8?B?TWFudWVsIEzDs3Blei1JYsOhw7Fleg==?= , Gcc Patch List CC: Jason Merrill Subject: Re: [C++ Patch PING] Re: [PATCH] make excessive template instantiation depth a fatal error References: <542AB5A7.5020303@oracle.com> In-Reply-To: <542AB5A7.5020303@oracle.com> X-IsSubscribed: yes ... forgot to attach the complete patch ;) Paolo. //////////////////////// Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 215710) +++ cp/cp-tree.h (working copy) @@ -5418,7 +5418,6 @@ extern const char *lang_decl_name (tree, int, boo extern const char *lang_decl_dwarf_name (tree, int, bool); extern const char *language_to_string (enum languages); extern const char *class_key_or_enum_as_string (tree); -extern void print_instantiation_context (void); extern void maybe_warn_variadic_templates (void); extern void maybe_warn_cpp0x (cpp0x_warn_str str); extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); @@ -5633,7 +5632,7 @@ extern tree tsubst_copy_and_build (tree, tree, ts tree, bool, bool); extern tree most_general_template (tree); extern tree get_mostly_instantiated_function_type (tree); -extern int problematic_instantiation_changed (void); +extern bool problematic_instantiation_changed (void); extern void record_last_problematic_instantiation (void); extern struct tinst_level *current_instantiation(void); extern tree maybe_get_template_decl_from_type_decl (tree); @@ -5661,7 +5660,8 @@ 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 bool push_tinst_level (tree); +extern bool push_tinst_level_loc (tree, location_t); extern void pop_tinst_level (void); extern struct tinst_level *outermost_tinst_level(void); extern void init_template_processing (void); Index: cp/error.c =================================================================== --- cp/error.c (revision 215710) +++ cp/error.c (working copy) @@ -3360,16 +3360,6 @@ maybe_print_instantiation_context (diagnostic_cont record_last_problematic_instantiation (); print_instantiation_full_context (context); } - -/* Report the bare minimum context of a template instantiation. */ -void -print_instantiation_context (void) -{ - print_instantiation_partial_context - (global_dc, current_instantiation (), input_location); - pp_newline (global_dc->printer); - diagnostic_flush_buffer (global_dc); -} /* Report what constexpr call(s) we're trying to expand, if any. */ Index: cp/pt.c =================================================================== --- cp/pt.c (revision 215710) +++ cp/pt.c (working copy) @@ -8347,26 +8347,26 @@ static GTY(()) struct tinst_level *last_error_tins /* We're starting to instantiate D; record the template instantiation context for diagnostics and to restore it later. */ -int +bool push_tinst_level (tree d) { + return push_tinst_level_loc (d, input_location); +} + +/* We're starting to instantiate D; record the template instantiation context + at LOC for diagnostics and to restore it later. */ + +bool +push_tinst_level_loc (tree d, location_t loc) +{ 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 (); - - return 0; + fatal_error ("template instantiation depth exceeds maximum of %d" + " (use -ftemplate-depth= to increase the maximum)", + max_tinst_depth); + return false; } /* If the current instantiation caused problems, don't let it instantiate @@ -8373,11 +8373,11 @@ push_tinst_level (tree d) anything else. Do allow deduction substitution and decls usable in constant expressions. */ if (limit_bad_template_recursion (d)) - return 0; + return false; new_level = ggc_alloc (); new_level->decl = d; - new_level->locus = input_location; + new_level->locus = loc; new_level->errors = errorcount+sorrycount; new_level->in_system_header_p = in_system_header_at (input_location); new_level->next = current_tinst_level; @@ -8387,7 +8387,7 @@ push_tinst_level (tree d) if (GATHER_STATISTICS && (tinst_depth > depth_reached)) depth_reached = tinst_depth; - return 1; + return true; } /* We're done instantiating this template; return to the instantiation @@ -20291,10 +20291,10 @@ instantiate_pending_templates (int retries) { tree decl = pending_templates->tinst->decl; - error ("template instantiation depth exceeds maximum of %d" - " instantiating %q+D, possibly from virtual table generation" - " (use -ftemplate-depth= to increase the maximum)", - max_tinst_depth, decl); + fatal_error ("template instantiation depth exceeds maximum of %d" + " instantiating %q+D, possibly from virtual table generation" + " (use -ftemplate-depth= to increase the maximum)", + max_tinst_depth, decl); if (TREE_CODE (decl) == FUNCTION_DECL) /* Pretend that we defined it. */ DECL_INITIAL (decl) = error_mark_node; @@ -20627,7 +20627,7 @@ get_mostly_instantiated_function_type (tree decl) /* Return truthvalue if we're processing a template different from the last one involved in diagnostics. */ -int +bool problematic_instantiation_changed (void) { return current_tinst_level != last_error_tinst_level; Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 215710) +++ cp/typeck2.c (working copy) @@ -1639,8 +1639,13 @@ build_x_arrow (location_t loc, tree expr, tsubst_f if (expr == error_mark_node) return error_mark_node; + /* This provides a better instantiation backtrace in case of + error. */ if (fn && DECL_USE_TEMPLATE (fn)) - push_tinst_level (fn); + push_tinst_level_loc (fn, + (current_instantiation () != actual_inst) + ? DECL_SOURCE_LOCATION (fn) + : input_location); fn = NULL; if (vec_member (TREE_TYPE (expr), types_memoized)) Index: testsuite/g++.dg/cpp0x/decltype26.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype26.C (revision 215708) +++ testsuite/g++.dg/cpp0x/decltype26.C (working copy) @@ -10,7 +10,7 @@ decltype(f(T())) f(T t) // { dg-error "depth" } int main() { - f(A()); // { dg-error "no match" } + f(A()); // { dg-message "from here" } } -// { dg-prune-output "note" } +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/cpp0x/decltype28.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype28.C (revision 215708) +++ testsuite/g++.dg/cpp0x/decltype28.C (working copy) @@ -14,3 +14,5 @@ ft (F f, typename enable_if::type) {} int main() { ft (0, 0); // { dg-message "from here" } } + +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/cpp0x/decltype29.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype29.C (revision 215708) +++ testsuite/g++.dg/cpp0x/decltype29.C (working copy) @@ -13,7 +13,7 @@ decltype (ft (F())) // { dg-error "depth" } ft() {} int main() { - ft(); // { dg-error "no match|wrong number" } + ft(); // { dg-message "from here" } } -// { dg-prune-output "note" } +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/cpp0x/decltype32.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype32.C (revision 215708) +++ testsuite/g++.dg/cpp0x/decltype32.C (working copy) @@ -4,7 +4,7 @@ template auto make_array(const T& il) -> -decltype(make_array(il)) // { dg-error "not declared|no matching|exceeds" } +decltype(make_array(il)) // { dg-error "not declared|no matching|depth" } { } int main() @@ -11,3 +11,5 @@ int main() { int z = make_array(1); // { dg-error "no matching" } } + +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/cpp0x/enum11.C =================================================================== --- testsuite/g++.dg/cpp0x/enum11.C (revision 215708) +++ testsuite/g++.dg/cpp0x/enum11.C (working copy) @@ -4,12 +4,10 @@ template struct Pair { }; struct Foo { enum { Mask = 1 }; } foo; -template class Pair -operator|(const A &, const B &) // { dg-message "substitution" } +template class Pair // { dg-error "depth" } +operator|(const A &, const B &) { } -Pair f = foo|foo; // { dg-message "no match" } +Pair f = foo|foo; // { dg-message "from here" } -// { dg-prune-output "note" } -// { dg-prune-output "here" } -// { dg-prune-output "instantiation depth" } +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/template/arrow1.C =================================================================== --- testsuite/g++.dg/template/arrow1.C (revision 215708) +++ testsuite/g++.dg/template/arrow1.C (working copy) @@ -9,9 +9,7 @@ struct a { }; int main() { - a<0>()->x; // { dg-error "instantiation depth exceeds maximum" } + a<0>()->x; // { dg-error "depth" } } -// { dg-prune-output "incomplete type" } -// { dg-prune-output "declaration of" } -// { dg-prune-output "used but never defined" } +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/template/pr23510.C =================================================================== --- testsuite/g++.dg/template/pr23510.C (revision 215708) +++ testsuite/g++.dg/template/pr23510.C (working copy) @@ -3,21 +3,21 @@ template struct Factorial { - enum { nValue = nFactor * Factorial::nValue }; // { dg-error "depth exceeds maximum" "exceeds" } - // { dg-message "recursively required" "recurse" { target *-*-* } 6 } - // { dg-error "incomplete type" "incomplete" { target *-*-* } 6 } -} // { dg-error "expected ';' after" } + enum { nValue = nFactor * Factorial::nValue }; // { dg-error "depth" } +}; - template<> - struct Factorial<0> - { - enum { nValue = 1 }; - }; +template<> +struct Factorial<0> +{ + enum { nValue = 1 }; +}; - static const unsigned int FACTOR = 20; +static const unsigned int FACTOR = 20; int main() { - Factorial::nValue; + Factorial::nValue; // { dg-message "from here" } return 0; } + +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/template/recurse.C =================================================================== --- testsuite/g++.dg/template/recurse.C (revision 215708) +++ testsuite/g++.dg/template/recurse.C (working copy) @@ -5,10 +5,8 @@ template struct F { int operator()() { - F f; // { dg-error "incomplete type" "incomplete" } - // { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 } - // { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 } - return f()*I; // { dg-message "recursively" "recurse" } + F f; // { dg-error "depth" } + return f()*I; } }; @@ -20,8 +18,7 @@ template <> struct F<52> int main () { F<1> f; - return f(); // { dg-message "from here" "excessive recursion" } + return f(); // { dg-message "from here" } } -// Ignore excess messages from recursion. -// { dg-prune-output "from 'int" } +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/template/recurse2.C =================================================================== --- testsuite/g++.dg/template/recurse2.C (revision 215708) +++ testsuite/g++.dg/template/recurse2.C (working copy) @@ -2,7 +2,8 @@ // We should not see an error about non-constant initialization. template struct X { - static const int value = X::value; // { dg-error "instantiation|incomplete" } - // { dg-message "recursively required" "" { target *-*-* } 5 } + static const int value = X::value; // { dg-error "depth" } }; template struct X<1000>; + +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.dg/template/vtable2.C =================================================================== --- testsuite/g++.dg/template/vtable2.C (revision 215708) +++ testsuite/g++.dg/template/vtable2.C (working copy) @@ -11,8 +11,10 @@ template struct inner {}; template struct parent { - virtual void f() // { dg-error "instantiation depth" } + virtual void f() // { dg-error "depth" } { parent > p; }; }; template struct parent; + +// { dg-prune-output "compilation terminated" } Index: testsuite/g++.old-deja/g++.pt/infinite1.C =================================================================== --- testsuite/g++.old-deja/g++.pt/infinite1.C (revision 215708) +++ testsuite/g++.old-deja/g++.pt/infinite1.C (working copy) @@ -20,4 +20,4 @@ int main() f<0>(); } -// { dg-prune-output "note" } +// { dg-prune-output "compilation terminated" } Index: testsuite/lib/g++.exp =================================================================== --- testsuite/lib/g++.exp (revision 215708) +++ testsuite/lib/g++.exp (working copy) @@ -267,7 +267,7 @@ proc g++_init { args } { lappend ALWAYS_CXXFLAGS "additional_flags=-fmessage-length=0" set gcc_warning_prefix "warning:" - set gcc_error_prefix "error:" + set gcc_error_prefix "(fatal )?error:" if { [istarget *-*-darwin*] } { lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress" Index: testsuite/lib/gcc.exp =================================================================== --- testsuite/lib/gcc.exp (revision 215708) +++ testsuite/lib/gcc.exp (working copy) @@ -111,7 +111,7 @@ proc gcc_init { args } { } set gcc_warning_prefix "warning:" - set gcc_error_prefix "error:" + set gcc_error_prefix "(fatal )?error:" gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o" } Index: testsuite/lib/obj-c++.exp =================================================================== --- testsuite/lib/obj-c++.exp (revision 215708) +++ testsuite/lib/obj-c++.exp (working copy) @@ -275,7 +275,7 @@ proc obj-c++_init { args } { lappend ALWAYS_OBJCXXFLAGS "additional_flags=-fmessage-length=0" set gcc_warning_prefix "warning:" - set gcc_error_prefix "error:" + set gcc_error_prefix "(fatal )?error:" if { [istarget *-*-darwin*] } { lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress" Index: testsuite/lib/objc.exp =================================================================== --- testsuite/lib/objc.exp (revision 215708) +++ testsuite/lib/objc.exp (working copy) @@ -124,7 +124,7 @@ proc objc_init { args } { } set gcc_warning_prefix "warning:" - set gcc_error_prefix "error:" + set gcc_error_prefix "(fatal )?error:" objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o"