Commit 75a0d320 by Paolo Carlini

re PR c++/16564 (g++ seems to go into an infinite loop after errors)

cp/
2014-09-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>

       PR c++/16564
       * error.c (print_instantiation_context): Delete.
       * typeck2.c (build_x_arrow): Record location when pushing
       template instantiation.
       * pt.c (push_tinst_level): Make it a wrapper around ...
       (push_tinst_level_loc): ... this. New function. Make excessive
       template instantiation depth a fatal error. Record location. Use
       bool as return type.
       (instantiate_pending_templates): Make excessive
       template instantiation depth a fatal error.
       (problematic_instantiation_changed): Use bool as return type.
       * cp-tree.h (print_instantiation_context): Delete.
       (push_tinst_level): Update declaration.
       (problematic_instantiation_changed): Likewise.
       (push_tinst_level_loc): New.

testsuite/
2014-09-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>

       PR c++/16564
       * lib/gcc.exp: Accept "fatal error:" as error prefix.
       * lib/g++.exp: Likewise.
       * lib/obj-c++.exp: Likewise.
       * lib/objc.exp: Likewise.
       * g++.dg/template/pr16564.C: New test.

2014-09-30  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/16564
	* g++.dg/cpp0x/decltype26.C: Adjust.
	* g++.dg/cpp0x/decltype28.C: Likewise.
	* g++.dg/cpp0x/decltype29.C: Likewise.
	* g++.dg/cpp0x/decltype32.C: Likewise.
	* g++.dg/cpp0x/enum11.C: Likewise.
	* g++.dg/template/arrow1.C: Likewise.
	* g++.dg/template/pr23510.C: Likewise.
	* g++.dg/template/recurse.C: Likewise.
	* g++.dg/template/recurse2.C: Likewise.
	* g++.dg/template/vtable2.C: Likewise.
	* g++.old-deja/g++.pt/infinite1.C: Likewise.

From-SVN: r215733
parent cc811a8a
2014-09-30 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/16564
* error.c (print_instantiation_context): Delete.
* typeck2.c (build_x_arrow): Record location when pushing
template instantiation.
* pt.c (push_tinst_level): Make it a wrapper around ...
(push_tinst_level_loc): ... this. New function. Make excessive
template instantiation depth a fatal error. Record location. Use
bool as return type.
(instantiate_pending_templates): Make excessive
template instantiation depth a fatal error.
(problematic_instantiation_changed): Use bool as return type.
* cp-tree.h (print_instantiation_context): Delete.
(push_tinst_level): Update declaration.
(problematic_instantiation_changed): Likewise.
(push_tinst_level_loc): New.
2014-09-29 Richard Biener <rguenther@suse.de> 2014-09-29 Richard Biener <rguenther@suse.de>
* typeck.c (enum_cast_to_int): Use CONVERT_EXPR_P to check * typeck.c (enum_cast_to_int): Use CONVERT_EXPR_P to check
......
...@@ -5418,7 +5418,6 @@ extern const char *lang_decl_name (tree, int, bool); ...@@ -5418,7 +5418,6 @@ extern const char *lang_decl_name (tree, int, bool);
extern const char *lang_decl_dwarf_name (tree, int, bool); extern const char *lang_decl_dwarf_name (tree, int, bool);
extern const char *language_to_string (enum languages); extern const char *language_to_string (enum languages);
extern const char *class_key_or_enum_as_string (tree); 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_variadic_templates (void);
extern void maybe_warn_cpp0x (cpp0x_warn_str str); extern void maybe_warn_cpp0x (cpp0x_warn_str str);
extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); 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, tsubst_flags_t, ...@@ -5633,7 +5632,7 @@ extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t,
tree, bool, bool); tree, bool, bool);
extern tree most_general_template (tree); extern tree most_general_template (tree);
extern tree get_mostly_instantiated_function_type (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 void record_last_problematic_instantiation (void);
extern struct tinst_level *current_instantiation(void); extern struct tinst_level *current_instantiation(void);
extern tree maybe_get_template_decl_from_type_decl (tree); extern tree maybe_get_template_decl_from_type_decl (tree);
...@@ -5661,7 +5660,8 @@ extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t); ...@@ -5661,7 +5660,8 @@ extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t);
extern bool alias_type_or_template_p (tree); extern bool alias_type_or_template_p (tree);
extern bool alias_template_specialization_p (const_tree); extern bool alias_template_specialization_p (const_tree);
extern bool explicit_class_specialization_p (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 void pop_tinst_level (void);
extern struct tinst_level *outermost_tinst_level(void); extern struct tinst_level *outermost_tinst_level(void);
extern void init_template_processing (void); extern void init_template_processing (void);
......
...@@ -3360,16 +3360,6 @@ maybe_print_instantiation_context (diagnostic_context *context) ...@@ -3360,16 +3360,6 @@ maybe_print_instantiation_context (diagnostic_context *context)
record_last_problematic_instantiation (); record_last_problematic_instantiation ();
print_instantiation_full_context (context); 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. */ /* Report what constexpr call(s) we're trying to expand, if any. */
......
...@@ -8347,37 +8347,37 @@ static GTY(()) struct tinst_level *last_error_tinst_level; ...@@ -8347,37 +8347,37 @@ static GTY(()) struct tinst_level *last_error_tinst_level;
/* We're starting to instantiate D; record the template instantiation context /* We're starting to instantiate D; record the template instantiation context
for diagnostics and to restore it later. */ for diagnostics and to restore it later. */
int bool
push_tinst_level (tree d) 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; struct tinst_level *new_level;
if (tinst_depth >= max_tinst_depth) if (tinst_depth >= max_tinst_depth)
{ {
last_error_tinst_level = current_tinst_level; fatal_error ("template instantiation depth exceeds maximum of %d"
if (TREE_CODE (d) == TREE_LIST) " (use -ftemplate-depth= to increase the maximum)",
error ("template instantiation depth exceeds maximum of %d (use " max_tinst_depth);
"-ftemplate-depth= to increase the maximum) substituting %qS", return false;
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;
} }
/* If the current instantiation caused problems, don't let it instantiate /* If the current instantiation caused problems, don't let it instantiate
anything else. Do allow deduction substitution and decls usable in anything else. Do allow deduction substitution and decls usable in
constant expressions. */ constant expressions. */
if (limit_bad_template_recursion (d)) if (limit_bad_template_recursion (d))
return 0; return false;
new_level = ggc_alloc<tinst_level> (); new_level = ggc_alloc<tinst_level> ();
new_level->decl = d; new_level->decl = d;
new_level->locus = input_location; new_level->locus = loc;
new_level->errors = errorcount+sorrycount; new_level->errors = errorcount+sorrycount;
new_level->in_system_header_p = in_system_header_at (input_location); new_level->in_system_header_p = in_system_header_at (input_location);
new_level->next = current_tinst_level; new_level->next = current_tinst_level;
...@@ -8387,7 +8387,7 @@ push_tinst_level (tree d) ...@@ -8387,7 +8387,7 @@ push_tinst_level (tree d)
if (GATHER_STATISTICS && (tinst_depth > depth_reached)) if (GATHER_STATISTICS && (tinst_depth > depth_reached))
depth_reached = tinst_depth; depth_reached = tinst_depth;
return 1; return true;
} }
/* We're done instantiating this template; return to the instantiation /* We're done instantiating this template; return to the instantiation
...@@ -20291,10 +20291,10 @@ instantiate_pending_templates (int retries) ...@@ -20291,10 +20291,10 @@ instantiate_pending_templates (int retries)
{ {
tree decl = pending_templates->tinst->decl; tree decl = pending_templates->tinst->decl;
error ("template instantiation depth exceeds maximum of %d" fatal_error ("template instantiation depth exceeds maximum of %d"
" instantiating %q+D, possibly from virtual table generation" " instantiating %q+D, possibly from virtual table generation"
" (use -ftemplate-depth= to increase the maximum)", " (use -ftemplate-depth= to increase the maximum)",
max_tinst_depth, decl); max_tinst_depth, decl);
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
/* Pretend that we defined it. */ /* Pretend that we defined it. */
DECL_INITIAL (decl) = error_mark_node; DECL_INITIAL (decl) = error_mark_node;
...@@ -20627,7 +20627,7 @@ get_mostly_instantiated_function_type (tree decl) ...@@ -20627,7 +20627,7 @@ get_mostly_instantiated_function_type (tree decl)
/* Return truthvalue if we're processing a template different from /* Return truthvalue if we're processing a template different from
the last one involved in diagnostics. */ the last one involved in diagnostics. */
int bool
problematic_instantiation_changed (void) problematic_instantiation_changed (void)
{ {
return current_tinst_level != last_error_tinst_level; return current_tinst_level != last_error_tinst_level;
......
...@@ -1639,8 +1639,13 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain) ...@@ -1639,8 +1639,13 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
if (expr == error_mark_node) if (expr == error_mark_node)
return error_mark_node; return error_mark_node;
/* This provides a better instantiation backtrace in case of
error. */
if (fn && DECL_USE_TEMPLATE (fn)) 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; fn = NULL;
if (vec_member (TREE_TYPE (expr), types_memoized)) if (vec_member (TREE_TYPE (expr), types_memoized))
......
2014-09-30 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/16564
* lib/gcc.exp: Accept "fatal error:" as error prefix.
* lib/g++.exp: Likewise.
* lib/obj-c++.exp: Likewise.
* lib/objc.exp: Likewise.
* g++.dg/template/pr16564.C: New test.
2014-09-30 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/16564
* g++.dg/cpp0x/decltype26.C: Adjust.
* g++.dg/cpp0x/decltype28.C: Likewise.
* g++.dg/cpp0x/decltype29.C: Likewise.
* g++.dg/cpp0x/decltype32.C: Likewise.
* g++.dg/cpp0x/enum11.C: Likewise.
* g++.dg/template/arrow1.C: Likewise.
* g++.dg/template/pr23510.C: Likewise.
* g++.dg/template/recurse.C: Likewise.
* g++.dg/template/recurse2.C: Likewise.
* g++.dg/template/vtable2.C: Likewise.
* g++.old-deja/g++.pt/infinite1.C: Likewise.
2014-09-30 Bernd Edlinger <bernd.edlinger@hotmail.de> 2014-09-30 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR preprocessor/58893 PR preprocessor/58893
...@@ -9,7 +33,7 @@ ...@@ -9,7 +33,7 @@
PR middle-end/62120 PR middle-end/62120
* gcc.target/i386/avx512f-additional-reg-names.c: Use register valid * gcc.target/i386/avx512f-additional-reg-names.c: Use register valid
in 32-bit mode. in 32-bit mode.
* gcc.target/i386/pr62120.c: New. * gcc.target/i386/pr62120.c: New.
2014-09-30 James Greenhalgh <james.greenhalgh@arm.com> 2014-09-30 James Greenhalgh <james.greenhalgh@arm.com>
......
...@@ -10,7 +10,7 @@ decltype(f(T())) f(T t) // { dg-error "depth" } ...@@ -10,7 +10,7 @@ decltype(f(T())) f(T t) // { dg-error "depth" }
int main() int main()
{ {
f(A()); // { dg-error "no match" } f(A()); // { dg-message "from here" }
} }
// { dg-prune-output "note" } // { dg-prune-output "compilation terminated" }
...@@ -14,3 +14,5 @@ ft (F f, typename enable_if<N==0, int>::type) {} ...@@ -14,3 +14,5 @@ ft (F f, typename enable_if<N==0, int>::type) {}
int main() { int main() {
ft<struct a*, 2> (0, 0); // { dg-message "from here" } ft<struct a*, 2> (0, 0); // { dg-message "from here" }
} }
// { dg-prune-output "compilation terminated" }
...@@ -13,7 +13,7 @@ decltype (ft<F> (F())) // { dg-error "depth" } ...@@ -13,7 +13,7 @@ decltype (ft<F> (F())) // { dg-error "depth" }
ft() {} ft() {}
int main() { int main() {
ft<struct a*, 0>(); // { dg-error "no match|wrong number" } ft<struct a*, 0>(); // { dg-message "from here" }
} }
// { dg-prune-output "note" } // { dg-prune-output "compilation terminated" }
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
template <typename T> template <typename T>
auto make_array(const T& il) -> 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() int main()
{ {
int z = make_array(1); // { dg-error "no matching" } int z = make_array(1); // { dg-error "no matching" }
} }
// { dg-prune-output "compilation terminated" }
...@@ -4,12 +4,10 @@ ...@@ -4,12 +4,10 @@
template<unsigned int N> struct Pair { }; template<unsigned int N> struct Pair { };
struct Foo { enum { Mask = 1 }; } foo; struct Foo { enum { Mask = 1 }; } foo;
template<typename A, typename B> class Pair<A::Mask | B::Mask> template<typename A, typename B> class Pair<A::Mask | B::Mask> // { dg-error "depth" }
operator|(const A &, const B &) // { dg-message "substitution" } operator|(const A &, const B &)
{ } { }
Pair<Foo::Mask> f = foo|foo; // { dg-message "no match" } Pair<Foo::Mask> f = foo|foo; // { dg-message "from here" }
// { dg-prune-output "note" } // { dg-prune-output "compilation terminated" }
// { dg-prune-output "here" }
// { dg-prune-output "instantiation depth" }
...@@ -9,9 +9,7 @@ struct a { ...@@ -9,9 +9,7 @@ struct a {
}; };
int main() { 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 "compilation terminated" }
// { dg-prune-output "declaration of" }
// { dg-prune-output "used but never defined" }
...@@ -3,21 +3,21 @@ ...@@ -3,21 +3,21 @@
template<unsigned int nFactor> template<unsigned int nFactor>
struct Factorial struct Factorial
{ {
enum { nValue = nFactor * Factorial<nFactor - 1>::nValue }; // { dg-error "depth exceeds maximum" "exceeds" } enum { nValue = nFactor * Factorial<nFactor - 1>::nValue }; // { dg-error "depth" }
// { dg-message "recursively required" "recurse" { target *-*-* } 6 } };
// { dg-error "incomplete type" "incomplete" { target *-*-* } 6 }
} // { dg-error "expected ';' after" }
template<> template<>
struct Factorial<0> struct Factorial<0>
{ {
enum { nValue = 1 }; enum { nValue = 1 };
}; };
static const unsigned int FACTOR = 20; static const unsigned int FACTOR = 20;
int main() int main()
{ {
Factorial<FACTOR>::nValue; Factorial<FACTOR>::nValue; // { dg-message "from here" }
return 0; return 0;
} }
// { dg-prune-output "compilation terminated" }
...@@ -5,10 +5,8 @@ template <int I> struct F ...@@ -5,10 +5,8 @@ template <int I> struct F
{ {
int operator()() int operator()()
{ {
F<I+1> f; // { dg-error "incomplete type" "incomplete" } F<I+1> f; // { dg-error "depth" }
// { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 } return f()*I;
// { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 }
return f()*I; // { dg-message "recursively" "recurse" }
} }
}; };
...@@ -20,8 +18,7 @@ template <> struct F<52> ...@@ -20,8 +18,7 @@ template <> struct F<52>
int main () int main ()
{ {
F<1> f; 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 "compilation terminated" }
// { dg-prune-output "from 'int" }
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
// We should not see an error about non-constant initialization. // We should not see an error about non-constant initialization.
template <int N> struct X { template <int N> struct X {
static const int value = X<N-1>::value; // { dg-error "instantiation|incomplete" } static const int value = X<N-1>::value; // { dg-error "depth" }
// { dg-message "recursively required" "" { target *-*-* } 5 }
}; };
template struct X<1000>; template struct X<1000>;
// { dg-prune-output "compilation terminated" }
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
template <class T> struct inner {}; template <class T> struct inner {};
template <class T> struct parent { template <class T> struct parent {
virtual void f() // { dg-error "instantiation depth" } virtual void f() // { dg-error "depth" }
{ parent<inner<T> > p; }; { parent<inner<T> > p; };
}; };
template struct parent<int>; template struct parent<int>;
// { dg-prune-output "compilation terminated" }
...@@ -20,4 +20,4 @@ int main() ...@@ -20,4 +20,4 @@ int main()
f<0>(); f<0>();
} }
// { dg-prune-output "note" } // { dg-prune-output "compilation terminated" }
...@@ -267,7 +267,7 @@ proc g++_init { args } { ...@@ -267,7 +267,7 @@ proc g++_init { args } {
lappend ALWAYS_CXXFLAGS "additional_flags=-fmessage-length=0" lappend ALWAYS_CXXFLAGS "additional_flags=-fmessage-length=0"
set gcc_warning_prefix "warning:" set gcc_warning_prefix "warning:"
set gcc_error_prefix "error:" set gcc_error_prefix "(fatal )?error:"
if { [istarget *-*-darwin*] } { if { [istarget *-*-darwin*] } {
lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress" lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress"
......
...@@ -111,7 +111,7 @@ proc gcc_init { args } { ...@@ -111,7 +111,7 @@ proc gcc_init { args } {
} }
set gcc_warning_prefix "warning:" set gcc_warning_prefix "warning:"
set gcc_error_prefix "error:" set gcc_error_prefix "(fatal )?error:"
gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o" gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o"
} }
......
...@@ -275,7 +275,7 @@ proc obj-c++_init { args } { ...@@ -275,7 +275,7 @@ proc obj-c++_init { args } {
lappend ALWAYS_OBJCXXFLAGS "additional_flags=-fmessage-length=0" lappend ALWAYS_OBJCXXFLAGS "additional_flags=-fmessage-length=0"
set gcc_warning_prefix "warning:" set gcc_warning_prefix "warning:"
set gcc_error_prefix "error:" set gcc_error_prefix "(fatal )?error:"
if { [istarget *-*-darwin*] } { if { [istarget *-*-darwin*] } {
lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress" lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress"
......
...@@ -124,7 +124,7 @@ proc objc_init { args } { ...@@ -124,7 +124,7 @@ proc objc_init { args } {
} }
set gcc_warning_prefix "warning:" set gcc_warning_prefix "warning:"
set gcc_error_prefix "error:" set gcc_error_prefix "(fatal )?error:"
objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o" objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment