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
This commit is contained in:
parent
cc811a8ae6
commit
75a0d32006
@ -1,3 +1,21 @@
|
||||
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>
|
||||
|
||||
* 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);
|
||||
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, tsubst_flags_t,
|
||||
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, tsubst_flags_t);
|
||||
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);
|
||||
|
@ -3360,16 +3360,6 @@ maybe_print_instantiation_context (diagnostic_context *context)
|
||||
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. */
|
||||
|
||||
|
44
gcc/cp/pt.c
44
gcc/cp/pt.c
@ -8347,37 +8347,37 @@ static GTY(()) struct tinst_level *last_error_tinst_level;
|
||||
/* 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
|
||||
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<tinst_level> ();
|
||||
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;
|
||||
|
@ -1639,8 +1639,13 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
|
||||
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))
|
||||
|
@ -1,3 +1,27 @@
|
||||
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>
|
||||
|
||||
PR preprocessor/58893
|
||||
@ -9,7 +33,7 @@
|
||||
PR middle-end/62120
|
||||
* gcc.target/i386/avx512f-additional-reg-names.c: Use register valid
|
||||
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>
|
||||
|
||||
|
@ -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" }
|
||||
|
@ -14,3 +14,5 @@ ft (F f, typename enable_if<N==0, int>::type) {}
|
||||
int main() {
|
||||
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" }
|
||||
ft() {}
|
||||
|
||||
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 @@
|
||||
|
||||
template <typename T>
|
||||
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 z = make_array(1); // { dg-error "no matching" }
|
||||
}
|
||||
|
||||
// { dg-prune-output "compilation terminated" }
|
||||
|
@ -4,12 +4,10 @@
|
||||
|
||||
template<unsigned int N> struct Pair { };
|
||||
struct Foo { enum { Mask = 1 }; } foo;
|
||||
template<typename A, typename B> class Pair<A::Mask | B::Mask>
|
||||
operator|(const A &, const B &) // { dg-message "substitution" }
|
||||
template<typename A, typename B> class Pair<A::Mask | B::Mask> // { dg-error "depth" }
|
||||
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 "here" }
|
||||
// { dg-prune-output "instantiation depth" }
|
||||
// { dg-prune-output "compilation terminated" }
|
||||
|
@ -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" }
|
||||
|
@ -3,21 +3,21 @@
|
||||
template<unsigned int nFactor>
|
||||
struct Factorial
|
||||
{
|
||||
enum { nValue = nFactor * Factorial<nFactor - 1>::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<nFactor - 1>::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<FACTOR>::nValue;
|
||||
Factorial<FACTOR>::nValue; // { dg-message "from here" }
|
||||
return 0;
|
||||
}
|
||||
|
||||
// { dg-prune-output "compilation terminated" }
|
||||
|
@ -5,10 +5,8 @@ template <int I> struct F
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
F<I+1> 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<I+1> 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" }
|
||||
|
@ -2,7 +2,8 @@
|
||||
// We should not see an error about non-constant initialization.
|
||||
|
||||
template <int N> struct X {
|
||||
static const int value = X<N-1>::value; // { dg-error "instantiation|incomplete" }
|
||||
// { dg-message "recursively required" "" { target *-*-* } 5 }
|
||||
static const int value = X<N-1>::value; // { dg-error "depth" }
|
||||
};
|
||||
template struct X<1000>;
|
||||
|
||||
// { dg-prune-output "compilation terminated" }
|
||||
|
@ -11,8 +11,10 @@
|
||||
template <class T> struct inner {};
|
||||
|
||||
template <class T> struct parent {
|
||||
virtual void f() // { dg-error "instantiation depth" }
|
||||
virtual void f() // { dg-error "depth" }
|
||||
{ parent<inner<T> > p; };
|
||||
};
|
||||
|
||||
template struct parent<int>;
|
||||
|
||||
// { dg-prune-output "compilation terminated" }
|
||||
|
@ -20,4 +20,4 @@ int main()
|
||||
f<0>();
|
||||
}
|
||||
|
||||
// { dg-prune-output "note" }
|
||||
// { dg-prune-output "compilation terminated" }
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user