re PR c++/16564 (g++ seems to go into an infinite loop after errors)
authorPaolo Carlini <paolo@gcc.gnu.org>
Tue, 30 Sep 2014 17:10:35 +0000 (17:10 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 30 Sep 2014 17:10:35 +0000 (17:10 +0000)
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

21 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/cp/pt.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/decltype26.C
gcc/testsuite/g++.dg/cpp0x/decltype28.C
gcc/testsuite/g++.dg/cpp0x/decltype29.C
gcc/testsuite/g++.dg/cpp0x/decltype32.C
gcc/testsuite/g++.dg/cpp0x/enum11.C
gcc/testsuite/g++.dg/template/arrow1.C
gcc/testsuite/g++.dg/template/pr23510.C
gcc/testsuite/g++.dg/template/recurse.C
gcc/testsuite/g++.dg/template/recurse2.C
gcc/testsuite/g++.dg/template/vtable2.C
gcc/testsuite/g++.old-deja/g++.pt/infinite1.C
gcc/testsuite/lib/g++.exp
gcc/testsuite/lib/gcc.exp
gcc/testsuite/lib/obj-c++.exp
gcc/testsuite/lib/objc.exp

index 0beb9974521c3081992746b24d17a56a8ab9a4d7..3fe3f8d5775a41fc31d3afa5f532a4208e1aad1b 100644 (file)
@@ -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
index 5d8badcfe7556083ffc89e6e57a706383d64ea95..f0783abff2debcd5401c01785bf0f6192b297d77 100644 (file)
@@ -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);
index a03bfe12c163d859c8bee01fe451b2aabb311072..57f3c31972d221a0b3de2ca50bf2f1a5e0b9273f 100644 (file)
@@ -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);
-}
 \f
 /* Report what constexpr call(s) we're trying to expand, if any.  */
 
index da8bd8f30f63f64b7b8ea4a27e27634189c87ef8..9dd61f3608baa1e7f37af4b51415cb93221c36cd 100644 (file)
@@ -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;
index c6306b519aae288e3021b06beb5e4af4741f25f1..0a851f11596cad58161874eda2289d519298ad7e 100644 (file)
@@ -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))
index 6ffbbee2720f871b6b1d75de4283c2b5088b4c78..fae463c52d6016eabb1b9a046e99c3f36df96bd9 100644 (file)
@@ -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>
 
index 0d320dadd2068b09b139f81309b1569c5b7cecfd..58ba823aca047fbd3e164595d7a118dfa1da8576 100644 (file)
@@ -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 c1c5a1b305ccde4defe09998359f1ff54888a8c0..8c26fd7330dd320b060252339fb16b900c947eb5 100644 (file)
@@ -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" }
index d87299ccccbeeb69c1afade895ec39a2478f4753..51da8ddd0ded6a2c1049c6c720a6d21d2889173d 100644 (file)
@@ -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" }
index 02c6316e16a66e1cf38ef6069bf581ef23e93f33..1deb964577d0ff735bcff3976e2a1752dbda8909 100644 (file)
@@ -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" }
index a449f1c39a7a067b7752e436a47fbac3fb319bd6..f15b6cda49bddae9853942bfd1b9896663f82e7a 100644 (file)
@@ -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" }
index c96141063a0d392a48e0ef853262039086c4d545..690df4c5fcca15c8f1e35ef28ca147bf8501f00b 100644 (file)
@@ -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 7163e30ba2363e290bb6d78df92cf8896504ef2c..c1ffc176c5e0f824a2f1d25c72015a8f87260715 100644 (file)
@@ -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" }
index 94b56f67e99376a3f14ee57ebda22b0fc03b4176..fbd7def061c447bb9fa5ff5259b027fe4b433c63 100644 (file)
@@ -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" }
index eae411b5ead9d7948ead4c8ed5791ff505e58f63..0df8e5244fdd4bbb65ba63ef0abae70ddda6c97f 100644 (file)
@@ -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" }
index 3bcc1ac3f8a687b2037af00eb5e8f7271a6741b3..53b72f6f4e04f51228da14ca5fef5d79bae9e6d9 100644 (file)
 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" }
index 1e2a9f0fbddab9dc0e22070b1c47e0a26341db8c..a5873b09ef575dbde6e16d75208a91896a3cdef9 100644 (file)
@@ -20,4 +20,4 @@ int main()
   f<0>();
 }
 
-// { dg-prune-output "note" }
+// { dg-prune-output "compilation terminated" }
index 6658c58cc2c79c7a6d270cc77ce9f9d9b74fa498..bad36c4222bbe8d862981ed0cda51d412a2079b3 100644 (file)
@@ -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 f9370646ca432ef71eca08aaecb65a3006077290..3507c8a18f35936e679ad6d6a819d5e1f0dea27b 100644 (file)
@@ -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 93c7ff6b19875f7764c4deae864bf11f09429cc2..92a09feeb8bcc4f2d472d7273ab0eaf3c770c0de 100644 (file)
@@ -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 e19b2643863497ea58e3b43cb32f41a85a04c716..c0b4da7360cb9c19d742ff9daa02e76fd2779ec0 100644 (file)
@@ -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"