From 987009bf0d31f2aa399cbf58ddf91a90b09848ca Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Thu, 26 Aug 1999 05:18:44 +0000 Subject: [PATCH] system.h: Don't redefine abort or trim_filename. 1999-08-25 22:10 -0700 Zack Weinberg * system.h: Don't redefine abort or trim_filename. * rtl.h: Define abort to fancy_abort (__FILE__, __LINE__, 0) or fancy_abort (__FILE__, __LINE__, __FUNCTION__) depending on whether or not __FUNCTION__ is available. * tree.h: Duplicate rtl.h's definition of abort, for files that don't include rtl.h. Delete all code to perform type checking with a compiler other than GCC. * varray.h: Delete all code to perform type checking with a compiler other than GCC. Make VARRAY_CHECK() always evaluate its arguments exactly once, using a statement expression. Adjust the VARRAY_ accessor macros to match. * toplev.h (fatal_insn, fatal_insn_not_found): Kill. (_fatal_insn, _fatal_insn_not_found): New fns, take info on caller's location. Define fatal_insn and fatal_insn_not_found as macros that use _fatal_insn and _fatal_insn_not_found. (fancy_abort, trim_filename): Kill prototypes. * rtl.c (trim_filename): Move here from toplev.c. (fancy_abort): New function. (DIR_SEPARATOR): Provide default definition. * tree.c (tree_check_failed, tree_class_check_failed): Go through fancy_abort. (tree_check, tree_class_check, cst_or_constructor_check, expr_check): Delete. * varray.c (varray_check_failed): New function. * toplev.c (fatal_insn, fatal_insn_not_found): Replace with _fatal_insn and _fatal_insn_not_found. Go through fancy_abort. (trim_filename, fancy_abort): Delete. * builtins.c (expand_builtin_args_info): Report ICE with abort. * except.c (start_catch_handler): Report ICE with error/abort combo. * final.c (output_operand_lossage): Likewise. * flow.c (verify_flow_info): Likewise. * gcc.c: Prototype fatal. * gengenrtl.c: Undef abort after including rtl.h not system.h. * genattr.c, genattrtab.c, genemit.c, genextract.c, genflags.c, genopinit.c, genoutput.c, genpeep.c, genrecog.c: Don't define fancy_abort. From-SVN: r28889 --- gcc/ChangeLog | 44 +++++++++++++++++++++ gcc/builtins.c | 3 +- gcc/except.c | 5 ++- gcc/final.c | 5 ++- gcc/flow.c | 42 +++++++++++--------- gcc/gcc.c | 2 + gcc/genattr.c | 10 ----- gcc/genattrtab.c | 10 ----- gcc/gencodes.c | 10 ----- gcc/genconfig.c | 10 ----- gcc/genemit.c | 10 ----- gcc/genextract.c | 10 ----- gcc/genflags.c | 10 ----- gcc/gengenrtl.c | 2 +- gcc/genopinit.c | 10 ----- gcc/genoutput.c | 10 ----- gcc/genpeep.c | 10 ----- gcc/genrecog.c | 10 ----- gcc/rtl.c | 54 +++++++++++++++++++++++++ gcc/rtl.h | 14 +++++++ gcc/system.h | 19 --------- gcc/toplev.c | 100 +++++++++++++---------------------------------- gcc/toplev.h | 28 +++++++++---- gcc/tree.c | 89 ++++------------------------------------- gcc/tree.h | 43 ++++++++------------ gcc/varray.c | 21 ++++++++++ gcc/varray.h | 63 +++++++++++++++-------------- 27 files changed, 273 insertions(+), 371 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f73c4da31a4..1177d1a5526 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,47 @@ +1999-08-25 22:10 -0700 Zack Weinberg + + * system.h: Don't redefine abort or trim_filename. + * rtl.h: Define abort to fancy_abort (__FILE__, __LINE__, 0) + or fancy_abort (__FILE__, __LINE__, __FUNCTION__) depending on + whether or not __FUNCTION__ is available. + * tree.h: Duplicate rtl.h's definition of abort, for files + that don't include rtl.h. Delete all code to perform type + checking with a compiler other than GCC. + * varray.h: Delete all code to perform type checking with a + compiler other than GCC. Make VARRAY_CHECK() always evaluate + its arguments exactly once, using a statement expression. + Adjust the VARRAY_ accessor macros to match. + * toplev.h (fatal_insn, fatal_insn_not_found): Kill. + (_fatal_insn, _fatal_insn_not_found): New fns, take info on + caller's location. Define fatal_insn and fatal_insn_not_found + as macros that use _fatal_insn and _fatal_insn_not_found. + (fancy_abort, trim_filename): Kill prototypes. + + * rtl.c (trim_filename): Move here from toplev.c. + (fancy_abort): New function. + (DIR_SEPARATOR): Provide default definition. + * tree.c (tree_check_failed, tree_class_check_failed): Go + through fancy_abort. + (tree_check, tree_class_check, cst_or_constructor_check, + expr_check): Delete. + * varray.c (varray_check_failed): New function. + * toplev.c (fatal_insn, fatal_insn_not_found): Replace with + _fatal_insn and _fatal_insn_not_found. Go through + fancy_abort. + (trim_filename, fancy_abort): Delete. + + * builtins.c (expand_builtin_args_info): Report ICE with abort. + * except.c (start_catch_handler): Report ICE with error/abort + combo. + * final.c (output_operand_lossage): Likewise. + * flow.c (verify_flow_info): Likewise. + + * gcc.c: Prototype fatal. + * gengenrtl.c: Undef abort after including rtl.h not system.h. + * genattr.c, genattrtab.c, genemit.c, genextract.c, + genflags.c, genopinit.c, genoutput.c, genpeep.c, genrecog.c: + Don't define fancy_abort. + Wed Aug 25 17:56:59 1999 Richard Henderson * optabs.c (emit_cmp_and_jump_insns): Be more thorough in diff --git a/gcc/builtins.c b/gcc/builtins.c index 8e69652a0ad..c4e36059d07 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1734,8 +1734,7 @@ expand_builtin_args_info (exp) #endif if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0) - fatal ("CUMULATIVE_ARGS type defined badly; see %s, line %d", - __FILE__, __LINE__); + abort (); if (arglist != 0) { diff --git a/gcc/except.c b/gcc/except.c index 952021bbdcc..0d6abc39e14 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1692,7 +1692,10 @@ start_catch_handler (rtime) rtx call_rtx, rtime_address; if (catchstack.top->entry->false_label != NULL_RTX) - fatal ("Compiler Bug: Never issued previous false_label"); + { + error ("Never issued previous false_label"); + abort (); + } catchstack.top->entry->false_label = gen_exception_label (); rtime_address = expand_expr (rtime, NULL_RTX, Pmode, EXPAND_INITIALIZER); diff --git a/gcc/final.c b/gcc/final.c index 0b30246cfb9..9d725adc98c 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -3324,7 +3324,10 @@ output_operand_lossage (msgid) if (this_is_asm_operands) error_for_asm (this_is_asm_operands, "invalid `asm': %s", _(msgid)); else - fatal ("Internal compiler error, output_operand_lossage `%s'", _(msgid)); + { + error ("output_operand: %s", _(msgid)); + abort (); + } } /* Output of assembler code from a template, and its subroutines. */ diff --git a/gcc/flow.c b/gcc/flow.c index a6420a74507..0f151e7c262 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -6171,8 +6171,9 @@ verify_flow_info () break; if (!x) { - fatal ("verify_flow_info: Head insn %d for block %d not found in the insn stream.\n", + error ("Head insn %d for block %d not found in the insn stream.", INSN_UID (bb->head), bb->index); + abort (); } /* Check the end pointer and make sure that it is pointing into @@ -6181,8 +6182,9 @@ verify_flow_info () { if (bb_info[INSN_UID (x)] != NULL) { - fatal ("verify_flow_info: Insn %d is in multiple basic blocks (%d and %d)", + error ("Insn %d is in multiple basic blocks (%d and %d)", INSN_UID (x), bb->index, bb_info[INSN_UID (x)]->index); + abort (); } bb_info[INSN_UID (x)] = bb; @@ -6191,8 +6193,9 @@ verify_flow_info () } if (!x) { - fatal ("verify_flow_info: End insn %d for block %d not found in the insn stream.\n", + error ("End insn %d for block %d not found in the insn stream.", INSN_UID (bb->end), bb->index); + abort (); } } @@ -6224,8 +6227,8 @@ verify_flow_info () e2 = e2->pred_next; if (!e2) { - fatal ("verify_flow_info: Basic block %i edge lists are corrupted\n", - bb->index); + error ("Basic block %i edge lists are corrupted", bb->index); + abort (); } } e = e->succ_next; @@ -6236,13 +6239,12 @@ verify_flow_info () { if (e->dest != bb) { - fprintf (stderr, "verify_flow_info: Basic block %d pred edge is corrupted\n", - bb->index); - fprintf (stderr, "Predecessor: "); + error ("Basic block %d pred edge is corrupted", bb->index); + fputs ("Predecessor: ", stderr); dump_edge_info (stderr, e, 0); - fprintf (stderr, "\nSuccessor: "); + fputs ("\nSuccessor: ", stderr); dump_edge_info (stderr, e, 1); - fflush (stderr); + fputc ('\n', stderr); abort (); } if (e->src != ENTRY_BLOCK_PTR) @@ -6252,8 +6254,8 @@ verify_flow_info () e2 = e2->succ_next; if (!e2) { - fatal ("verify_flow_info: Basic block %i edge lists are corrupted\n", - bb->index); + error ("Basic block %i edge lists are corrupted", bb->index); + abort; } } e = e->pred_next; @@ -6267,7 +6269,9 @@ verify_flow_info () { if (bb->end == x) { - fatal ("verify_flow_info: Basic block contains only CODE_LABEL and no NOTE_INSN_BASIC_BLOCK note\n"); + error ("NOTE_INSN_BASIC_BLOCK is missing for block %d", + bb->index); + abort (); } x = NEXT_INSN (x); } @@ -6275,8 +6279,9 @@ verify_flow_info () || NOTE_LINE_NUMBER (x) != NOTE_INSN_BASIC_BLOCK || NOTE_BASIC_BLOCK (x) != bb) { - fatal ("verify_flow_info: NOTE_INSN_BASIC_BLOCK is missing for block %d\n", + error ("NOTE_INSN_BASIC_BLOCK is missing for block %d\n", bb->index); + abort (); } if (bb->end == x) @@ -6291,8 +6296,9 @@ verify_flow_info () if (GET_CODE (x) == NOTE && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK) { - fatal ("verify_flow_info: NOTE_INSN_BASIC_BLOCK %d in the middle of basic block %d\n", + error ("NOTE_INSN_BASIC_BLOCK %d in the middle of basic block %d", INSN_UID (x), bb->index); + abort (); } if (x == bb->end) @@ -6302,8 +6308,8 @@ verify_flow_info () || GET_CODE (x) == CODE_LABEL || GET_CODE (x) == BARRIER) { - fatal_insn ("verify_flow_info: Incorrect insn in the middle of basic block %d\n", - x, bb->index); + error ("In basic block %d:", bb->index); + fatal_insn ("Flow control insn inside a basic block", x); } x = NEXT_INSN (x); @@ -6336,7 +6342,7 @@ verify_flow_info () break; default: - fatal_insn ("verify_flow_info: Insn outside basic block\n", x); + fatal_insn ("Insn outside basic block", x); } } diff --git a/gcc/gcc.c b/gcc/gcc.c index b3092064226..f62ac40a9a3 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -205,6 +205,8 @@ static void pfatal_with_name PROTO((const char *)) ATTRIBUTE_NORETURN; static void perror_with_name PROTO((const char *)); static void pfatal_pexecute PROTO((const char *, const char *)) ATTRIBUTE_NORETURN; +static void fatal PVPROTO((const char *, ...)) + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; static void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; static void notice PVPROTO((const char *, ...)) diff --git a/gcc/genattr.c b/gcc/genattr.c index 35bc4b221bc..cfa6c595aa0 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -33,7 +33,6 @@ struct obstack *rtl_obstack = &obstack; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* Define this so we can link with print-rtl.o to get debug_rtx function. */ char **insn_name_ptr = 0; @@ -246,15 +245,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 2aba0b5ab77..83b3780bdd1 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -121,7 +121,6 @@ char **insn_name_ptr = 0; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* enough space to reserve for printing out ints */ #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3) @@ -5928,15 +5927,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - /* Determine if an insn has a constant number of delay slots, i.e., the number of delay slots is not a function of the length of the insn. */ diff --git a/gcc/gencodes.c b/gcc/gencodes.c index 2658216760e..385dae1bb55 100644 --- a/gcc/gencodes.c +++ b/gcc/gencodes.c @@ -35,7 +35,6 @@ struct obstack *rtl_obstack = &obstack; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* Define this so we can link with print-rtl.o to get debug_rtx function. */ char **insn_name_ptr = 0; @@ -103,15 +102,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/genconfig.c b/gcc/genconfig.c index d5e6f9b1d63..10bf89c154b 100644 --- a/gcc/genconfig.c +++ b/gcc/genconfig.c @@ -51,7 +51,6 @@ static int dup_operands_seen_this_insn; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; static void walk_insn_part PROTO((rtx, int, int)); static void gen_insn PROTO((rtx)); @@ -292,15 +291,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/genemit.c b/gcc/genemit.c index aa9bc531ae5..0443ea6d158 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -32,7 +32,6 @@ struct obstack *rtl_obstack = &obstack; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* Define this so we can link with print-rtl.o to get debug_rtx function. */ char **insn_name_ptr = 0; @@ -728,15 +727,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/genextract.c b/gcc/genextract.c index 18909580c11..174d56ebe34 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -100,7 +100,6 @@ static void walk_rtx PROTO ((rtx, const char *)); static void print_path PROTO ((char *)); void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO ((void)) ATTRIBUTE_NORETURN; static void gen_insn (insn) @@ -391,15 +390,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - char * xstrdup (input) const char *input; diff --git a/gcc/genflags.c b/gcc/genflags.c index 5f1dc349b55..7d521a4447e 100644 --- a/gcc/genflags.c +++ b/gcc/genflags.c @@ -35,7 +35,6 @@ struct obstack *rtl_obstack = &obstack; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* Names for patterns. Need to allow linking with print-rtl. */ char **insn_name_ptr; @@ -223,15 +222,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c index 37bdd9cb081..e07b9402c88 100644 --- a/gcc/gengenrtl.c +++ b/gcc/gengenrtl.c @@ -21,10 +21,10 @@ Boston, MA 02111-1307, USA. */ #include "hconfig.h" #include "system.h" -#undef abort #define NO_GENRTL_H #include "rtl.h" +#undef abort struct rtx_definition diff --git a/gcc/genopinit.c b/gcc/genopinit.c index 31eecd2af8a..ef9f3c75ce8 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -32,7 +32,6 @@ struct obstack *rtl_obstack = &obstack; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* Many parts of GCC use arrays that are indexed by machine mode and contain the insn codes for pattern in the MD file that perform a given @@ -328,15 +327,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/genoutput.c b/gcc/genoutput.c index 91180868a9d..095b67c7a24 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -109,7 +109,6 @@ struct obstack *rtl_obstack = &obstack; void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; static void error PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1; static int n_occurrences PROTO((int, char *)); @@ -953,15 +952,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - static void error VPROTO ((const char *format, ...)) { diff --git a/gcc/genpeep.c b/gcc/genpeep.c index ff0cc5c9a4f..7b02160d7a8 100644 --- a/gcc/genpeep.c +++ b/gcc/genpeep.c @@ -48,7 +48,6 @@ struct link void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; static int max_opno; @@ -431,15 +430,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 8fb846be90d..748c2a1882a 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -195,7 +195,6 @@ static void write_tree PROTO((struct decision *, const char *, static void change_state PROTO((const char *, const char *, int)); void fatal PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; /* Construct and return a sequence of decisions that will recognize INSN. @@ -1732,15 +1731,6 @@ fatal VPROTO ((const char *format, ...)) exit (FATAL_EXIT_CODE); } -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - int main (argc, argv) int argc; diff --git a/gcc/rtl.c b/gcc/rtl.c index bf997509f78..e50d5a759c7 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -29,6 +29,10 @@ Boston, MA 02111-1307, USA. */ #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + /* Obstack used for allocating RTL objects. Between functions, this is the permanent_obstack. While parsing and expanding a function, this is maybepermanent_obstack @@ -962,3 +966,53 @@ init_rtl () } } } + +/* 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. There are two versions because __FUNCTION__ isn't + available except in gcc 2.7 and later. */ + +extern void fatal PVPROTO ((const char *, ...)) + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; + +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 \ +for instructions.", + function, trim_filename (file), line); +} diff --git a/gcc/rtl.h b/gcc/rtl.h index 3c8a1924eb5..c8c25d4e4fb 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1544,6 +1544,20 @@ extern int supports_one_only PROTO ((void)); extern void init_rtl PROTO ((void)); extern void rtx_free PROTO ((rtx)); +/* Redefine abort to report an internal error w/o coredump, and + reporting the location of the error in the source file. This logic + is duplicated in rtl.h and tree.h because every file that needs the + special abort includes one or both. toplev.h gets too few files, + system.h gets too many. */ + +extern void fancy_abort PROTO((const char *, int, const char *)) + ATTRIBUTE_NORETURN; +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +#define abort() fancy_abort (__FILE__, __LINE__, 0) +#else +#define abort() fancy_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__) +#endif + /* In alias.c */ extern int true_dependence PROTO ((rtx, enum machine_mode, rtx, int (*)(rtx))); diff --git a/gcc/system.h b/gcc/system.h index 7d6082ccf29..41282bf56ba 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -384,28 +384,9 @@ extern int setrlimit (); #define volatile #endif -/* Redefine abort to report an internal error w/o coredump, and reporting the - location of the error in the source file. - Some files undefine abort again, so we must prototype the real thing - for their sake. */ #ifdef NEED_DECLARATION_ABORT extern void abort (); #endif -extern void fatal PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; - -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -#define abort() fatal ("Internal compiler error at %s:%d\n", \ - trim_filename (__FILE__), __LINE__) -#else -#define abort() fatal ("Internal compiler error in `%s', at %s:%d\n" \ - "Please submit a full bug report.\n" \ - "See for instructions.", \ - __PRETTY_FUNCTION__, trim_filename (__FILE__), __LINE__) -#endif /* recent gcc */ - -/* trim_filename is in toplev.c. Define a stub macro for files that - don't link toplev.c. toplev.h will reset it to the real version. */ -#define trim_filename(x) (x) /* Define a STRINGIFY macro that's right for ANSI or traditional C. HAVE_CPP_STRINGIFY only refers to the stage1 compiler. Assume that diff --git a/gcc/toplev.c b/gcc/toplev.c index 19b98333248..5acf1312d83 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1454,44 +1454,6 @@ fatal_io_error (name) exit (FATAL_EXIT_CODE); } -/* Called to give a better error message for a bad insn rather than - just calling abort(). */ - -void -fatal_insn VPROTO((const char *msgid, rtx insn, ...)) -{ -#ifndef ANSI_PROTOTYPES - const char *msgid; - rtx insn; -#endif - va_list ap; - - VA_START (ap, insn); - -#ifndef ANSI_PROTOTYPES - msgid = va_arg (ap, const char *); - insn = va_arg (ap, rtx); -#endif - - verror (msgid, ap); - debug_rtx (insn); - exit (FATAL_EXIT_CODE); -} - -/* Called to give a better error message when we don't have an insn to match - what we are looking for or if the insn's constraints aren't satisfied, - rather than just calling abort(). */ - -void -fatal_insn_not_found (insn) - rtx insn; -{ - if (INSN_CODE (insn) < 0) - fatal_insn ("internal error--unrecognizable insn:", insn); - else - fatal_insn ("internal error--insn does not satisfy its constraints:", insn); -} - /* This is the default decl_printable_name function. */ static char * @@ -1953,6 +1915,33 @@ fatal VPROTO((const char *msgid, ...)) va_end (ap); } +void +_fatal_insn (msgid, insn, file, line, function) + const char *msgid; + rtx insn; + const char *file; + int line; + const char *function; +{ + error (msgid); + debug_rtx (insn); + fancy_abort (file, line, function); +} + +void +_fatal_insn_not_found (insn, file, line, function) + rtx insn; + const char *file; + int line; + const char *function; +{ + if (INSN_CODE (insn) < 0) + _fatal_insn ("Unrecognizable insn:", insn, file, line, function); + else + _fatal_insn ("Insn does not satisfy its constraints:", + insn, file, line, function); +} + /* Report a warning at line LINE of file FILE. */ static void @@ -2243,41 +2232,6 @@ sorry VPROTO((const char *msgid, ...)) va_end (ap); } -/* Given a partial pathname as input, return another pathname that shares - no elements with the pathname of __FILE__. This is used by abort() to - print `Internal compiler error in expr.c' instead of `Internal compiler - error in ../../egcs/gcc/expr.c'. */ -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; -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. - - I don't think this is actually a good idea. - Other sorts of crashes will look a certain way. - It is a good thing if crashes from calling abort look the same way. - -- RMS */ - -void -fancy_abort () -{ - fatal ("internal gcc abort"); -} /* This calls abort and is used to avoid problems when abort if a macro. It is used when we need to pass the address of abort. */ diff --git a/gcc/toplev.h b/gcc/toplev.h index 49adb413cd2..30080980df6 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -41,11 +41,27 @@ extern void fatal_io_error PROTO ((const char *)) ATTRIBUTE_NORETURN; extern void pfatal_with_name PROTO ((const char *)) ATTRIBUTE_NORETURN; -extern void fatal_insn_not_found PROTO ((struct rtx_def *)) +extern void _fatal_insn_not_found PROTO ((struct rtx_def *, + const char *, int, + const char *)) ATTRIBUTE_NORETURN; -extern void fatal_insn PVPROTO ((const char *, - struct rtx_def *, ...)) - ATTRIBUTE_PRINTF(1, 3) ATTRIBUTE_NORETURN; +extern void _fatal_insn PROTO ((const char *, + struct rtx_def *, + const char *, int, + const char *)) + ATTRIBUTE_NORETURN; + +#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) +#define fatal_insn(msgid, insn) \ + _fatal_insn (msgid, insn, __FILE__, __LINE__, __PRETTY_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 extern void warning PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1; extern void error PVPROTO ((const char *, ...)) @@ -100,8 +116,6 @@ extern int do_float_handler PROTO((void (*) (PTR), PTR)); extern void output_quoted_string PROTO ((FILE *, const char *)); extern void output_file_directive PROTO ((FILE *, const char *)); #endif - -extern void fancy_abort PROTO ((void)) ATTRIBUTE_NORETURN; extern void do_abort PROTO ((void)) ATTRIBUTE_NORETURN; extern void botch PROTO ((const char *)) ATTRIBUTE_NORETURN; @@ -111,8 +125,6 @@ extern void fnotice PROTO ((FILE *, const char *, ...)) ATTRIBUTE_PRINTF_2; #endif -#undef trim_filename -extern const char *trim_filename PROTO ((const char *)); extern int wrapup_global_declarations PROTO ((union tree_node **, int)); extern void check_global_declarations PROTO ((union tree_node **, int)); extern int errorcount; diff --git a/gcc/tree.c b/gcc/tree.c index fb8f08a425b..aca04f6520a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5073,14 +5073,9 @@ get_set_constructor_bytes (init, buffer, wd_size) return non_const_bits; } -#ifdef ENABLE_CHECKING - -#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) - +#if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) /* Complain that the tree code of NODE does not match the expected CODE. - FILE, LINE, and FUNCTION are of the caller. - - FIXME: should print the blather about reporting the bug. */ + FILE, LINE, and FUNCTION are of the caller. */ void tree_check_failed (node, code, file, line, function) const tree node; @@ -5089,10 +5084,9 @@ tree_check_failed (node, code, file, line, function) int line; const char *function; { - fatal ("Internal compiler error in `%s', at %s:%d:\n\ -\texpected %s, have %s\n", - function, trim_filename (file), line, + error ("Tree check: expected %s, have %s", tree_code_name[code], tree_code_name[TREE_CODE (node)]); + fancy_abort (file, line, function); } /* Similar to above, except that we check for a class of tree @@ -5105,81 +5099,12 @@ tree_class_check_failed (node, cl, file, line, function) int line; const char *function; { - fatal ("Internal compiler error in `%s', at %s:%d:\n\ -\texpected '%c', have '%c' (%s)\n", - function, trim_filename (file), line, cl, - TREE_CODE_CLASS (TREE_CODE (node)), + error ("Tree check: expected class '%c', have '%c' (%s)", + cl, TREE_CODE_CLASS (TREE_CODE (node)), tree_code_name[TREE_CODE (node)]); + fancy_abort (file, line, function); } -#else /* not gcc or old gcc */ - -/* These functions are just like the above, but they have to - do the check as well as report the error. */ -tree -tree_check (node, code, file, line) - const tree node; - enum tree_code code; - const char *file; - int line; -{ - if (TREE_CODE (node) == code) - return node; - - fatal ("Internal compiler error at %s:%d:\n\texpected %s, have %s\n", - file, trim_filename (file), tree_code_name[code], tree_code_name[TREE_CODE(node)]); -} - -tree -tree_class_check (node, class, file, line) - const tree node; - char class; - const char *file; - int line; -{ - if (TREE_CODE_CLASS (TREE_CODE (node)) == class) - return node; - - fatal ("Internal compiler error at %s:%d:\n\ -\texpected '%c', have '%c' (%s)\n", - file, trim_filename (file), class, TREE_CODE_CLASS (TREE_CODE (node)), - tree_code_name[TREE_CODE(node)]); -} - -tree -cst_or_constructor_check (node, file, line) - const tree node; - const char *file; - int line; -{ - enum tree_code code = TREE_CODE (node); - - if (code == CONSTRUCTOR || TREE_CODE_CLASS (code) == 'c') - return node; - - fatal ("Internal compiler error at %s:%d:\n\ -\texpected constructor, have %s\n", - file, line, tree_code_name[code]); -} - -tree -expr_check (node, file, line) - const tree node; - const char *file; - int line; -{ - char c = TREE_CODE_CLASS (TREE_CODE (node)); - - if (c == 'r' || c == 's' || c == '<' - || c == '1' || c == '2' || c == 'e') - return node; - - fatal ("Internal compiler error at %s:%d:\n\ -\texpected 'e', have '%c' (%s)\n", - file, trim_filename (file), c, tree_code_name[TREE_CODE (node)]); -} - -#endif /* not gcc or old gcc */ #endif /* ENABLE_CHECKING */ /* Return the alias set for T, which may be either a type or an diff --git a/gcc/tree.h b/gcc/tree.h index 82d3cf640d1..c21ecec32d6 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -312,14 +312,8 @@ struct tree_common /* When checking is enabled, errors will be generated if a tree node is accessed incorrectly. The macros abort with a fatal error. */ +#if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) -#ifdef ENABLE_CHECKING - -#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) -/* This optimization can only be done in stage2/3, because it - uses statement expressions. You might think that you could use - conditional (?:) expressions, but you would be wrong: these macros - need to evaluate `t' only once. */ #define TREE_CHECK(t, code) \ ({ const tree __t = t; \ if (TREE_CODE(__t) != (code)) \ @@ -357,25 +351,7 @@ extern void tree_class_check_failed PROTO((const tree, char, const char *, int, const char *)) ATTRIBUTE_NORETURN; -#else /* not gcc or old gcc */ - -#define TREE_CHECK(t, code) \ - tree_check (t, code, __FILE__, __LINE__) -#define TREE_CLASS_CHECK(t, code) \ - tree_class_check (t, code, __FILE__, __LINE__) -#define CST_OR_CONSTRUCTOR_CHECK(t) \ - cst_or_constructor_check (t, __FILE__, __LINE__) -#define EXPR_CHECK(t) \ - expr_check (t, __FILE__, __LINE__) - -extern tree tree_check PROTO((const tree, enum tree_code, const char *, int)); -extern tree tree_class_check PROTO((const tree, char, const char *, int)); -extern tree cst_or_constructor_check PROTO((const tree, const char *, int)); -extern tree expr_check PROTO((const tree, enum tree_code, const char *, int)); - -#endif /* not gcc or old gcc */ - -#else /* not ENABLE_CHECKING */ +#else /* not ENABLE_CHECKING, or not gcc */ #define TREE_CHECK(t, code) (t) #define TREE_CLASS_CHECK(t, code) (t) @@ -2425,3 +2401,18 @@ extern void dwarf2out_begin_prologue PROTO((void)); code for a function definition. */ extern void dwarf2out_end_epilogue PROTO((void)); + +/* Redefine abort to report an internal error w/o coredump, and + reporting the location of the error in the source file. This logic + is duplicated in rtl.h and tree.h because every file that needs the + special abort includes one or both. toplev.h gets too few files, + system.h gets too many. */ + +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +extern void fancy_abort PROTO((const char *, int)) ATTRIBUTE_NORETURN; +#define abort() fancy_abort (__FILE__, __LINE__) +#else +extern void fancy_abort PROTO((const char *, int, const char *)) + ATTRIBUTE_NORETURN; +#define abort() fancy_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__) +#endif diff --git a/gcc/varray.c b/gcc/varray.c index 80f15b264b4..8d65b181ec8 100644 --- a/gcc/varray.c +++ b/gcc/varray.c @@ -68,3 +68,24 @@ varray_grow (va, n) return va; } + +/* Check the bounds of a varray access. */ + +#if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) + +extern void error PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1; + +void +varray_check_failed (va, n, file, line, function) + varray_type va; + size_t n; + const char *file; + int line; + const char *function; +{ + error("Virtual array %s[%lu]: element %lu out of bounds", + va->name, (unsigned long) va->num_elements, (unsigned long) n); + fancy_abort (file, line, function); +} + +#endif diff --git a/gcc/varray.h b/gcc/varray.h index 7d4f6972f26..5d773a39ed1 100644 --- a/gcc/varray.h +++ b/gcc/varray.h @@ -162,38 +162,41 @@ extern varray_type varray_grow PROTO((varray_type, size_t)); #define VARRAY_SIZE(VA) ((VA)->num_elements) -/* Check for VARRAY_xxx macros being in bound, return N for use as an - index. */ -#ifdef ENABLE_CHECKING -#define VARRAY_CHECK(VA, N) \ -((((size_t)(N) < (VA)->num_elements) \ - ? 0 \ - : (fatal ("Virtual array %s element %ld out of bounds, at %s:%d", \ - (VA)->name, (long)(N), __FILE__, __LINE__), 0)), \ - (N)) +/* Check for VARRAY_xxx macros being in bound. */ +#if defined ENABLE_CHECKING && (__GNUC__ > 2 || __GNUC_MINOR__ > 6) +extern void varray_check_failed PROTO ((varray_type, size_t, + const char *, int, + const char *)) ATTRIBUTE_NORETURN; +#define VARRAY_CHECK(VA, N, T) \ +(*({ varray_type _va = VA; \ + size_t _n = N; \ + if (_n >= _va->num_elements) \ + varray_check_failed (_va, _n, __FILE__, __LINE__, \ + __PRETTY_FUNCTION__); \ + &_va->data.T[_n]; })) #else -#define VARRAY_CHECK(VA, N) (N) +#define VARRAY_CHECK(VA, N, T) ((VA)->data.T[N]) #endif -#define VARRAY_CHAR(VA, N) ((VA)->data.c[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_UCHAR(VA, N) ((VA)->data.uc[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_SHORT(VA, N) ((VA)->data.s[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_USHORT(VA, N) ((VA)->data.us[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_INT(VA, N) ((VA)->data.i[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_UINT(VA, N) ((VA)->data.u[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_LONG(VA, N) ((VA)->data.l[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_ULONG(VA, N) ((VA)->data.ul[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_WIDE_INT(VA, N) ((VA)->data.hint[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_UWIDE_INT(VA, N) ((VA)->data.uhint[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_GENERIC_PTR(VA,N) ((VA)->data.generic[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_CHAR_PTR(VA,N) ((VA)->data.cptr[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_RTX(VA, N) ((VA)->data.rtx[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_RTVEC(VA, N) ((VA)->data.rtvec[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_TREE(VA, N) ((VA)->data.tree[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_BITMAP(VA, N) ((VA)->data.bitmap[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_SCHED(VA, N) ((VA)->data.sched[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_REG(VA, N) ((VA)->data.reg[ VARRAY_CHECK (VA, N) ]) -#define VARRAY_CONST_EQUIV(VA, N) ((VA)->data.const_equiv[VARRAY_CHECK (VA, N)]) -#define VARRAY_BB(VA, N) ((VA)->data.bb[ VARRAY_CHECK (VA, N) ]) +#define VARRAY_CHAR(VA, N) VARRAY_CHECK (VA, N, c) +#define VARRAY_UCHAR(VA, N) VARRAY_CHECK (VA, N, uc) +#define VARRAY_SHORT(VA, N) VARRAY_CHECK (VA, N, s) +#define VARRAY_USHORT(VA, N) VARRAY_CHECK (VA, N, us) +#define VARRAY_INT(VA, N) VARRAY_CHECK (VA, N, i) +#define VARRAY_UINT(VA, N) VARRAY_CHECK (VA, N, u) +#define VARRAY_LONG(VA, N) VARRAY_CHECK (VA, N, l) +#define VARRAY_ULONG(VA, N) VARRAY_CHECK (VA, N, ul) +#define VARRAY_WIDE_INT(VA, N) VARRAY_CHECK (VA, N, hint) +#define VARRAY_UWIDE_INT(VA, N) VARRAY_CHECK (VA, N, uhint) +#define VARRAY_GENERIC_PTR(VA,N) VARRAY_CHECK (VA, N, generic) +#define VARRAY_CHAR_PTR(VA,N) VARRAY_CHECK (VA, N, cptr) +#define VARRAY_RTX(VA, N) VARRAY_CHECK (VA, N, rtx) +#define VARRAY_RTVEC(VA, N) VARRAY_CHECK (VA, N, rtvec) +#define VARRAY_TREE(VA, N) VARRAY_CHECK (VA, N, tree) +#define VARRAY_BITMAP(VA, N) VARRAY_CHECK (VA, N, bitmap) +#define VARRAY_SCHED(VA, N) VARRAY_CHECK (VA, N, sched) +#define VARRAY_REG(VA, N) VARRAY_CHECK (VA, N, reg) +#define VARRAY_CONST_EQUIV(VA, N) VARRAY_CHECK (VA, N, const_equiv) +#define VARRAY_BB(VA, N) VARRAY_CHECK (VA, N, bb) #endif /* _VARRAY_H_ */