aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostic.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@wolery.cumb.org>2000-07-21 07:10:36 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-07-21 07:10:36 +0000
commitfbfc11925b971a0d73b7253ba71bef3c32c9fb95 (patch)
treed19f337e85d3fb553f6806af5174bc4df981e7c8 /gcc/diagnostic.c
parent1b493b8185a04b875c99c0dc4ef63005bb5fc54b (diff)
downloadgcc-fbfc11925b971a0d73b7253ba71bef3c32c9fb95.zip
gcc-fbfc11925b971a0d73b7253ba71bef3c32c9fb95.tar.gz
gcc-fbfc11925b971a0d73b7253ba71bef3c32c9fb95.tar.bz2
diagnostic.c (trim_filename, [...]): Moved here from rtl.c.
* diagnostic.c (trim_filename, fancy_abort): Moved here from rtl.c. (fatal_function, set_fatal_function): Removed. (fatal): Don't prepare for or call the fatal_function. (diagnostic_lock, error_recursion): New. (diagnostic_for_decl, report_diagnostic): Guard against re-entering the error reporting routines. (fancy_abort): Assume function is not NULL. * errors.c (fancy_abort): New. Assume function is not NULL. * tradcpp.c (fancy_abort): Assume function is not NULL. * system.h: Provide default definition of __FUNCTION__. * rtl.h: Use __FUNCTION__ not __PRETTY_FUNCTION__ throughout. Always use __FUNCTION__ in definition of abort. * tree.h: Likewise. * varray.h: Likewise. * toplev.h: Likewise. Don't prototype set_fatal_function. From-SVN: r35170
Diffstat (limited to 'gcc/diagnostic.c')
-rw-r--r--gcc/diagnostic.c139
1 files changed, 98 insertions, 41 deletions
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 5ab3266..3fb6f6b 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -96,6 +96,9 @@ static void maybe_wrap_text PARAMS ((output_buffer *, const char *,
static void clear_text_info PARAMS ((output_buffer *));
static void clear_diagnostic_info PARAMS ((output_buffer *));
+static void error_recursion PARAMS ((void)) ATTRIBUTE_NORETURN;
+static const char *trim_filename PARAMS ((const char *));
+
extern int rtl_dump_and_exit;
extern int inhibit_warnings;
extern int warnings_are_errors;
@@ -137,6 +140,10 @@ int diagnostic_message_length_per_line;
/* Used to control every diagnostic message formatting. Front-ends should
call set_message_prefixing_rule to set up their politics. */
static int current_prefixing_rule;
+
+/* Prevent recursion into the error handler. */
+static int diagnostic_lock;
+
/* Initialize the diagnostic message outputting machinery. */
@@ -900,20 +907,25 @@ diagnostic_for_decl (decl, msg, args_ptr, warn)
{
output_state os;
- if (!count_error (warn))
- return;
- os = diagnostic_buffer->state;
- report_error_function (DECL_SOURCE_FILE (decl));
- output_set_prefix
- (diagnostic_buffer, context_as_prefix
- (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), warn));
- output_buffer_ptr_to_format_args (diagnostic_buffer) = args_ptr;
- output_buffer_text_cursor (diagnostic_buffer) = msg;
- format_with_decl (diagnostic_buffer, decl);
- finish_diagnostic ();
- output_destroy_prefix (diagnostic_buffer);
+ if (diagnostic_lock++)
+ error_recursion ();
+
+ if (count_error (warn))
+ {
+ os = diagnostic_buffer->state;
+ report_error_function (DECL_SOURCE_FILE (decl));
+ output_set_prefix
+ (diagnostic_buffer, context_as_prefix
+ (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), warn));
+ output_buffer_ptr_to_format_args (diagnostic_buffer) = args_ptr;
+ output_buffer_text_cursor (diagnostic_buffer) = msg;
+ format_with_decl (diagnostic_buffer, decl);
+ finish_diagnostic ();
+ output_destroy_prefix (diagnostic_buffer);
- diagnostic_buffer->state = os;
+ diagnostic_buffer->state = os;
+ }
+ diagnostic_lock--;
}
@@ -1254,17 +1266,6 @@ error VPARAMS ((const char *msgid, ...))
va_end (ap);
}
-/* Set the function to call when a fatal error occurs. */
-
-static void (*fatal_function) PARAMS ((const char *, va_list));
-
-void
-set_fatal_function (f)
- void (*f) PARAMS ((const char *, va_list));
-{
- fatal_function = f;
-}
-
/* Report a fatal error at the current line number. Allow a front end to
intercept the message. */
void
@@ -1274,18 +1275,13 @@ fatal VPARAMS ((const char *msgid, ...))
const char *msgid;
#endif
va_list ap;
- va_list args_for_fatal_msg;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
#endif
- va_copy (args_for_fatal_msg, ap);
- if (fatal_function != NULL)
- (*fatal_function) (_(msgid), args_for_fatal_msg);
- va_end (args_for_fatal_msg);
report_diagnostic (msgid, &ap, input_filename, lineno, 0);
va_end (ap);
exit (FATAL_EXIT_CODE);
@@ -1482,16 +1478,77 @@ report_diagnostic (msg, args_ptr, file, line, warn)
{
output_state os;
- if (!count_error (warn))
- return;
- os = diagnostic_buffer->state;
- diagnostic_msg = msg;
- diagnostic_args = args_ptr;
- report_error_function (file);
- output_set_prefix
- (diagnostic_buffer, context_as_prefix (file, line, warn));
- output_format (diagnostic_buffer);
- finish_diagnostic ();
- output_destroy_prefix (diagnostic_buffer);
- diagnostic_buffer->state = os;
+ if (diagnostic_lock++)
+ error_recursion ();
+
+ if (count_error (warn))
+ {
+ os = diagnostic_buffer->state;
+ diagnostic_msg = msg;
+ diagnostic_args = args_ptr;
+ report_error_function (file);
+ output_set_prefix
+ (diagnostic_buffer, context_as_prefix (file, line, warn));
+ output_format (diagnostic_buffer);
+ finish_diagnostic ();
+ output_destroy_prefix (diagnostic_buffer);
+ diagnostic_buffer->state = os;
+ }
+
+ diagnostic_lock--;
+}
+
+/* Inform the user that an error occurred while trying to report some
+ other error. This indicates catastrophic internal inconsistencies,
+ so give up now. But do try to flush out the previous error. */
+static void
+error_recursion ()
+{
+ if (diagnostic_lock < 3)
+ finish_diagnostic ();
+
+ fprintf (stderr,
+"Internal compiler error: Error reporting routines re-entered.\n\
+Please submit a full bug report.\n\
+See %s for instructions.\n", GCCBUGURL);
+
+ exit (FATAL_EXIT_CODE);
+}
+
+/* Given a partial pathname as input, return another pathname that
+ shares no directory elements with the pathname of __FILE__. This
+ is used by fancy_abort() to print `Internal compiler error in expr.c'
+ instead of `Internal compiler error in ../../egcs/gcc/expr.c'. */
+static const char *
+trim_filename (name)
+ const char *name;
+{
+ static const char this_file[] = __FILE__;
+ const char *p = name, *q = this_file;
+
+ while (*p == *q && *p != 0 && *q != 0) p++, q++;
+ while (p > name && p[-1] != DIR_SEPARATOR
+#ifdef DIR_SEPARATOR_2
+ && p[-1] != DIR_SEPARATOR_2
+#endif
+ )
+ p--;
+
+ return p;
+}
+
+/* Report an internal compiler error in a friendly manner and without
+ dumping core. */
+
+void
+fancy_abort (file, line, function)
+ const char *file;
+ int line;
+ const char *function;
+{
+ fatal (
+"Internal compiler error in %s, at %s:%d\n\
+Please submit a full bug report.\n\
+See %s for instructions.",
+ function, trim_filename (file), line, GCCBUGURL);
}