Hi!

As has been noted several times in the past, and most recently e.g. in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64511#c13
generating backtrace from internal_error call in driver's execute is
undesirable, there is nothing wrong in the driver, the problem is that
the compiler crashed.  This confuses lots of people.
The following patch avoids printing backtrace in that case.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2015-01-22  Jakub Jelinek  <ja...@redhat.com>

        * diagnostic-core.h (internal_error_no_backtrace): New prototype.
        * diagnostic.def (DK_ICE_NOBT): New kind.
        * diagnostic.c (diagnostic_action_after_output): Handle DK_ICE_NOBT
        like DK_ICE, but never print backtrace.
        (diagnostic_report_diagnostic): Handle DK_ICE_NOBT like DK_ICE.
        (internal_error_no_backtrace): New function.
        * gcc.c (execute): Use internal_error_no_backtrace instead of
        internal_error.
fortran/
        * gfc-diagnostic.def (DK_ICE_NOBT): New kind.

--- gcc/diagnostic-core.h.jj    2015-01-05 13:07:13.000000000 +0100
+++ gcc/diagnostic-core.h       2015-01-22 09:09:09.352920684 +0100
@@ -56,6 +56,8 @@ extern const char *trim_filename (const
 #endif
 extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
      ATTRIBUTE_NORETURN;
+extern void internal_error_no_backtrace (const char *, ...)
+     ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN;
 /* Pass one of the OPT_W* from options.h as the first parameter.  */
 extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool warning_n (location_t, int, int, const char *, const char *, ...)
--- gcc/diagnostic.def.jj       2015-01-05 13:07:13.000000000 +0100
+++ gcc/diagnostic.def  2015-01-22 09:01:48.575490585 +0100
@@ -45,3 +45,6 @@ DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "p
 /* This one is just for counting DK_WARNING promoted to DK_ERROR
    due to -Werror and -Werror=warning.  */
 DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error: ", NULL)
+/* This is like DK_ICE, but backtrace is not printed.  Used in the driver
+   when reporting fatal signal in the compiler.  */
+DEFINE_DIAGNOSTIC_KIND (DK_ICE_NOBT, "internal compiler error: ", "error")
--- gcc/diagnostic.c.jj 2015-01-05 13:07:15.000000000 +0100
+++ gcc/diagnostic.c    2015-01-22 09:13:34.166407314 +0100
@@ -518,9 +518,11 @@ diagnostic_action_after_output (diagnost
       break;
 
     case DK_ICE:
+    case DK_ICE_NOBT:
       {
-       struct backtrace_state *state =
-         backtrace_create_state (NULL, 0, bt_err_callback, NULL);
+       struct backtrace_state *state = NULL;
+       if (diag_kind == DK_ICE)
+         state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
        int count = 0;
        if (state != NULL)
          backtrace_full (state, 2, bt_callback, bt_err_callback,
@@ -739,7 +741,8 @@ diagnostic_report_diagnostic (diagnostic
       /* If we're reporting an ICE in the middle of some other error,
         try to flush out the previous error, then let this one
         through.  Don't do this more than once.  */
-      if (diagnostic->kind == DK_ICE && context->lock == 1)
+      if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
+         && context->lock == 1)
        pp_newline_and_flush (context->printer);
       else
        error_recursion (context);
@@ -812,7 +815,7 @@ diagnostic_report_diagnostic (diagnostic
 
   context->lock++;
 
-  if (diagnostic->kind == DK_ICE)
+  if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
     {
 #ifndef ENABLE_CHECKING
       /* When not checking, ICEs are converted to fatal errors when an
@@ -1237,6 +1240,23 @@ internal_error (const char *gmsgid, ...)
   report_diagnostic (&diagnostic);
   va_end (ap);
 
+  gcc_unreachable ();
+}
+
+/* Like internal_error, but no backtrace will be printed.  Used when
+   the internal error does not happen at the current location, but happened
+   somewhere else.  */
+void
+internal_error_no_backtrace (const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_ICE_NOBT);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+
   gcc_unreachable ();
 }
 
--- gcc/gcc.c.jj        2015-01-15 23:39:03.000000000 +0100
+++ gcc/gcc.c   2015-01-22 09:06:03.565111399 +0100
@@ -2909,8 +2909,9 @@ execute (void)
              }
            else
 #endif
-             internal_error ("%s (program %s)",
-                             strsignal (WTERMSIG (status)), commands[i].prog);
+             internal_error_no_backtrace ("%s (program %s)",
+                                          strsignal (WTERMSIG (status)),
+                                          commands[i].prog);
          }
        else if (WIFEXITED (status)
                 && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
--- gcc/fortran/gfc-diagnostic.def.jj   2015-01-05 13:07:19.000000000 +0100
+++ gcc/fortran/gfc-diagnostic.def      2015-01-22 09:09:52.411186741 +0100
@@ -45,3 +45,6 @@ DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "p
 /* This one is just for counting DK_WARNING promoted to DK_ERROR
    due to -Werror and -Werror=warning.  */
 DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error", NULL)
+/* This is like DK_ICE, but backtrace is not printed.  Used in the driver
+   when reporting fatal signal in the compiler.  */
+DEFINE_DIAGNOSTIC_KIND (DK_ICE_NOBT, "internal compiler error", "error")

        Jakub

Reply via email to