This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Clean ups for error handling
- To: gcc-patches at gcc dot gnu dot org
- Subject: Clean ups for error handling
- From: Zack Weinberg <zack at wolery dot cumb dot org>
- Date: Thu, 20 Jul 2000 12:46:14 -0700
Now that we have diagnostic.c, we can put fancy_abort there instead of
in rtl.c.
No one uses set_fatal_function, and it causes us to need va_copy in
diagnostic.c, which is not portable. (Did we or did we not have a
long argument about this last week?)
Use __FUNCTION__ instead of __PRETTY_FUNCTION__ in all the ICE
messages (they're the same thing in C), and put a default definition
in system.h, which reduces the number of #ifdefs.
Add a guard against recursive entry to the error-handling routines in
diagnostic.c. This is inspired by the guard for recursive aborts in
the C++ front end.
We're still stuck with abort() being defined in both tree.h and rtl.h.
Bootstrapped i386-linux.
zw
* diagnostic.c (trim_filename): Move here from rtl.c.
(fancy_abort): Likewise. No need to worry about function
being NULL.
(fatal_function, set_fatal_function): Removed.
(fatal): Do not prepare for or call the fatal_function.
(error_recursion): New function.
(diagnostic_lock): New variable.
(report_diagnostic): Guard against error recursion.
* errors.c (fancy_abort): New.
* tradcpp.c (fancy_abort): No need to worry about function
being NULL.
* system.h: Provide default definition of __FUNCTION__.
* rtl.h: Replace __PRETTY_FUNCTION__ with __FUNCTION__
throughout.
* tree.h: Likewise.
* varray.h: Likewise.
* toplev.h: Likewise. Don't prototype set_fatal_function.
* rtl.h, tree.h: Define abort with no concern for GCC version.
===================================================================
Index: diagnostic.c
--- diagnostic.c 2000/07/18 08:40:32 1.26
+++ diagnostic.c 2000/07/20 19:36:57
@@ -96,6 +96,9 @@ static void maybe_wrap_text PARAMS ((out
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. */
@@ -1254,17 +1261,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 +1270,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,8 +1473,12 @@ report_diagnostic (msg, args_ptr, file,
{
output_state os;
+ if (diagnostic_lock++)
+ error_recursion ();
+
if (!count_error (warn))
- return;
+ goto out;
+
os = diagnostic_buffer->state;
diagnostic_msg = msg;
diagnostic_args = args_ptr;
@@ -1494,4 +1489,62 @@ report_diagnostic (msg, args_ptr, file,
finish_diagnostic ();
output_destroy_prefix (diagnostic_buffer);
diagnostic_buffer->state = os;
+
+ out:
+ 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);
}
===================================================================
Index: errors.c
--- errors.c 2000/01/14 17:14:42 1.3
+++ errors.c 2000/07/20 19:36:57
@@ -104,3 +104,15 @@ fatal VPARAMS ((const char *format, ...)
fputc('\n', stderr);
exit (FATAL_EXIT_CODE);
}
+
+/* "Fancy" abort. Reports where in the compiler someone gave up.
+ This file is used only by build programs, so we're not as polite as
+ the version in diagnostic.c. */
+void
+fancy_abort (file, line, func)
+ const char *file;
+ int line;
+ const char *func;
+{
+ fatal ("ICE in %s, at %s:%d", func, file, line);
+}
===================================================================
Index: tradcpp.c
--- tradcpp.c 2000/07/20 17:14:23 1.7
+++ tradcpp.c 2000/07/20 19:36:59
@@ -4249,10 +4249,7 @@ fancy_abort (line, func)
int line;
const char *func;
{
- if (!func)
- func = "?";
-
- fatal ("Internal error in \"%s\", at tradcpp.c:%d\n\
+ fatal ("Internal error in %s, at tradcpp.c:%d\n\
Please submit a full bug report.\n\
See %s for instructions.", func, line, GCCBUGURL);
}
===================================================================
Index: rtl.c
--- rtl.c 2000/06/29 10:24:19 1.72
+++ rtl.c 2000/07/20 19:37:01
@@ -265,7 +265,7 @@ static void fatal_with_file_and_line PAR
ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
static void fatal_expected_char PARAMS ((FILE *, int, int)) ATTRIBUTE_NORETURN;
static void read_name PARAMS ((char *, FILE *));
-static const char *trim_filename PARAMS ((const char *));
+
/* Allocate an rtx vector of N elements.
Store the length, and initialize all elements to zero. */
@@ -1196,48 +1196,3 @@ rtvec_check_failed_bounds (r, n, file, l
fancy_abort (file, line, func);
}
#endif /* ENABLE_RTL_CHECKING */
-
-/* These are utility functions used by fatal-error functions all over the
- code. rtl.c happens to be linked by all the programs that need them,
- so these are here. In the future we want to break out all error handling
- to its own module. */
-
-/* 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;
-{
- if (function == NULL)
- 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);
-}
===================================================================
Index: rtl.h
--- rtl.h 2000/05/31 18:36:05 1.208
+++ rtl.h 2000/07/20 19:37:01
@@ -223,45 +223,40 @@ typedef struct rtvec_def{
(*({ rtx _rtx = (RTX); int _n = (N); \
enum rtx_code _code = GET_CODE (_rtx); \
if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \
- rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, __FUNCTION__); \
if (GET_RTX_FORMAT(_code)[_n] != C1) \
- rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ rtl_check_failed_type1(_rtx, _n, C1, __FILE__, __LINE__, __FUNCTION__); \
&_rtx->fld[_n]; }))
#define RTL_CHECK2(RTX, N, C1, C2) __extension__ \
(*({ rtx _rtx = (RTX); int _n = (N); \
enum rtx_code _code = GET_CODE (_rtx); \
if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \
- rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, __FUNCTION__); \
if (GET_RTX_FORMAT(_code)[_n] != C1 \
&& GET_RTX_FORMAT(_code)[_n] != C2) \
rtl_check_failed_type2 (_rtx, _n, C1, C2, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ __FUNCTION__); \
&_rtx->fld[_n]; }))
#define RTL_CHECKC1(RTX, N, C) __extension__ \
(*({ rtx _rtx = (RTX); int _n = (N); \
if (GET_CODE (_rtx) != C) \
- rtl_check_failed_code1 (_rtx, C, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ rtl_check_failed_code1 (_rtx, C, __FILE__, __LINE__, __FUNCTION__); \
&_rtx->fld[_n]; }))
#define RTL_CHECKC2(RTX, N, C1, C2) __extension__ \
(*({ rtx _rtx = (RTX); int _n = (N); \
enum rtx_code _code = GET_CODE (_rtx); \
if (_code != C1 && _code != C2) \
- rtl_check_failed_code2 (_rtx, C1, C2, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ rtl_check_failed_code2(_rtx, C1, C2, __FILE__, __LINE__, __FUNCTION__); \
&_rtx->fld[_n]; }))
#define RTVEC_ELT(RTVEC, I) __extension__ \
(*({ rtvec _rtvec = (RTVEC); int _i = (I); \
if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec)) \
rtvec_check_failed_bounds (_rtvec, _i, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ __FUNCTION__); \
&_rtvec->elem[_i]; }))
extern void rtl_check_failed_bounds PARAMS ((rtx, int,
@@ -1809,11 +1804,7 @@ extern int read_rtx_lineno;
extern void fancy_abort PARAMS ((const char *, int, const char *))
ATTRIBUTE_NORETURN;
-#if (GCC_VERSION >= 2007)
-#define abort() fancy_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
-#define abort() fancy_abort (__FILE__, __LINE__, 0)
-#endif
+#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
/* In alias.c */
extern rtx canon_rtx PARAMS ((rtx));
===================================================================
Index: system.h
--- system.h 2000/07/13 19:09:23 1.74
+++ system.h 2000/07/20 19:37:01
@@ -615,4 +615,9 @@ extern void abort PARAMS ((void));
extern void *alloca (__SIZE_TYPE__);
#endif
+/* Various error reporting routines want to use __FUNCTION__. */
+#if (GCC_VERSION < 2007)
+#define __FUNCTION__ "?"
+#endif
+
#endif /* __GCC_SYSTEM_H__ */
===================================================================
Index: toplev.h
--- toplev.h 2000/07/12 14:12:50 1.44
+++ toplev.h 2000/07/20 19:44:35
@@ -57,17 +57,11 @@ extern void _fatal_insn PARAMS ((const
const char *))
ATTRIBUTE_NORETURN;
-#if (GCC_VERSION >= 2007)
#define fatal_insn(msgid, insn) \
- _fatal_insn (msgid, insn, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+ _fatal_insn (msgid, insn, __FILE__, __LINE__, __FUNCTION__)
#define fatal_insn_not_found(insn) \
- _fatal_insn_not_found (insn, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
-#define fatal_insn(msgid, insn) \
- _fatal_insn (msgid, insn, __FILE__, __LINE__, 0)
-#define fatal_insn_not_found(insn) \
- _fatal_insn_not_found (insn, __FILE__, __LINE__, 0)
-#endif
+ _fatal_insn_not_found (insn, __FILE__, __LINE__, __FUNCTION__)
+
extern void warning PARAMS ((const char *, ...))
ATTRIBUTE_PRINTF_1;
extern void error PARAMS ((const char *, ...))
@@ -140,5 +134,4 @@ extern int sorrycount;
extern const char *progname;
-extern void set_fatal_function PARAMS ((void (*) (const char *, va_list)));
#endif /* __GCC_TOPLEV_H */
===================================================================
Index: tree.h
--- tree.h 2000/07/10 07:18:05 1.183
+++ tree.h 2000/07/20 19:37:04
@@ -281,14 +281,12 @@ struct tree_common
#define TREE_CHECK(t, code) __extension__ \
({ const tree __t = t; \
if (TREE_CODE(__t) != (code)) \
- tree_check_failed (__t, code, __FILE__, \
- __LINE__, __PRETTY_FUNCTION__); \
+ tree_check_failed (__t, code, __FILE__, __LINE__, __FUNCTION__); \
__t; })
#define TREE_CLASS_CHECK(t, class) __extension__ \
({ const tree __t = t; \
if (TREE_CODE_CLASS(TREE_CODE(__t)) != (class)) \
- tree_class_check_failed (__t, class, __FILE__, \
- __LINE__, __PRETTY_FUNCTION__); \
+ tree_class_check_failed (__t, class, __FILE__, __LINE__, __FUNCTION__); \
__t; })
/* These checks have to be special cased. */
@@ -296,16 +294,14 @@ struct tree_common
({ const tree __t = t; \
enum tree_code __c = TREE_CODE(__t); \
if (__c != CONSTRUCTOR && TREE_CODE_CLASS(__c) != 'c') \
- tree_check_failed (__t, CONSTRUCTOR, __FILE__, \
- __LINE__, __PRETTY_FUNCTION__); \
+ tree_check_failed (__t, CONSTRUCTOR, __FILE__, __LINE__, __FUNCTION__); \
__t; })
#define EXPR_CHECK(t) __extension__ \
({ const tree __t = t; \
char __c = TREE_CODE_CLASS(TREE_CODE(__t)); \
if (__c != 'r' && __c != 's' && __c != '<' \
&& __c != '1' && __c != '2' && __c != 'e') \
- tree_class_check_failed(__t, 'e', __FILE__, \
- __LINE__, __PRETTY_FUNCTION__); \
+ tree_class_check_failed(__t, 'e', __FILE__, __LINE__, __FUNCTION__); \
__t; })
extern void tree_check_failed PARAMS ((const tree, enum tree_code,
@@ -2876,8 +2872,4 @@ extern void dwarf2out_end_epilogue PARAM
extern void fancy_abort PARAMS ((const char *, int, const char *))
ATTRIBUTE_NORETURN;
-#if (GCC_VERSION >= 2007)
-#define abort() fancy_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
-#define abort() fancy_abort (__FILE__, __LINE__, 0)
-#endif
+#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
===================================================================
Index: varray.h
--- varray.h 2000/06/01 20:13:29 1.20
+++ varray.h 2000/07/20 19:37:05
@@ -180,8 +180,7 @@ extern void varray_check_failed PARAMS (
(*({ varray_type _va = VA; \
size_t _n = N; \
if (_n >= _va->num_elements) \
- varray_check_failed (_va, _n, __FILE__, __LINE__, \
- __PRETTY_FUNCTION__); \
+ varray_check_failed (_va, _n, __FILE__, __LINE__, __FUNCTION__); \
&_va->data.T[_n]; }))
#else
#define VARRAY_CHECK(VA, N, T) ((VA)->data.T[N])