Mercurial > hg > CbC > CbC_gcc
diff gcc/diagnostic.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/diagnostic.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/diagnostic.c Tue Mar 22 17:18:12 2011 +0900 @@ -27,16 +27,14 @@ #include "system.h" #include "coretypes.h" #include "version.h" -#include "flags.h" #include "input.h" -#include "toplev.h" #include "intl.h" #include "diagnostic.h" -#include "opts.h" -#include "plugin.h" -#define pedantic_warning_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING) -#define permissive_error_kind() (flag_permissive ? DK_WARNING : DK_ERROR) +#define pedantic_warning_kind(DC) \ + ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING) +#define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR) +#define permissive_error_option(DC) ((DC)->opt_permissive) /* Prototypes. */ static char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1; @@ -47,6 +45,10 @@ diagnostic_info *); static void real_abort (void) ATTRIBUTE_NORETURN; +/* Name of program invoked, sans directories. */ + +const char *progname; + /* A diagnostic_context surrogate for stderr. */ static diagnostic_context global_diagnostic_context; diagnostic_context *global_dc = &global_diagnostic_context; @@ -78,8 +80,10 @@ /* Initialize the diagnostic message outputting machinery. */ void -diagnostic_initialize (diagnostic_context *context) +diagnostic_initialize (diagnostic_context *context, int n_opts) { + int i; + /* Allocate a basic pretty-printer. Clients will replace this a much more elaborated pretty-printer if they wish. */ context->printer = XNEW (pretty_printer); @@ -92,13 +96,26 @@ memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); context->some_warnings_are_errors = false; context->warning_as_error_requested = false; - memset (context->classify_diagnostic, DK_UNSPECIFIED, - sizeof context->classify_diagnostic); + context->n_opts = n_opts; + context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); + for (i = 0; i < n_opts; i++) + context->classify_diagnostic[i] = DK_UNSPECIFIED; context->show_option_requested = false; context->abort_on_error = false; + context->show_column = false; + context->pedantic_errors = false; + context->permissive = false; + context->opt_permissive = 0; + context->fatal_errors = false; + context->dc_inhibit_warnings = false; + context->dc_warn_system_headers = false; + context->max_errors = 0; context->internal_error = NULL; diagnostic_starter (context) = default_diagnostic_starter; diagnostic_finalizer (context) = default_diagnostic_finalizer; + context->option_enabled = NULL; + context->option_state = NULL; + context->option_name = NULL; context->last_module = 0; context->x_data = NULL; context->lock = 0; @@ -156,7 +173,8 @@ /* Return a malloc'd string describing a location. The caller is responsible for freeing the memory. */ char * -diagnostic_build_prefix (diagnostic_info *diagnostic) +diagnostic_build_prefix (diagnostic_context *context, + diagnostic_info *diagnostic) { static const char *const diagnostic_kind_text[] = { #define DEFINE_DIAGNOSTIC_KIND(K, T) (T), @@ -173,7 +191,7 @@ return (s.file == NULL ? build_message_string ("%s: %s", progname, text) - : flag_show_column + : context->show_column ? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text) : build_message_string ("%s:%d: %s", s.file, s.line, text)); } @@ -196,12 +214,23 @@ case DK_SORRY: if (context->abort_on_error) real_abort (); - if (flag_fatal_errors) + if (context->fatal_errors) { fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n"); diagnostic_finish (context); exit (FATAL_EXIT_CODE); } + if (context->max_errors != 0 + && ((unsigned) (diagnostic_kind_count (context, DK_ERROR) + + diagnostic_kind_count (context, DK_SORRY)) + >= context->max_errors)) + { + fnotice (stderr, + "compilation terminated due to -fmax-errors=%u.\n", + context->max_errors); + diagnostic_finish (context); + exit (FATAL_EXIT_CODE); + } break; case DK_ICE: @@ -246,7 +275,7 @@ if (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); - if (flag_show_column) + if (context->show_column) pp_verbatim (context->printer, "In file included from %s:%d:%d", map->to_file, @@ -273,7 +302,8 @@ diagnostic_info *diagnostic) { diagnostic_report_current_module (context); - pp_set_prefix (context->printer, diagnostic_build_prefix (diagnostic)); + pp_set_prefix (context->printer, diagnostic_build_prefix (context, + diagnostic)); } void @@ -289,20 +319,77 @@ diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *context, int option_index, - diagnostic_t new_kind) + diagnostic_t new_kind, + location_t where) { diagnostic_t old_kind; if (option_index <= 0 - || option_index >= N_OPTS + || option_index >= context->n_opts || new_kind >= DK_LAST_DIAGNOSTIC_KIND) return DK_UNSPECIFIED; old_kind = context->classify_diagnostic[option_index]; - context->classify_diagnostic[option_index] = new_kind; + + /* Handle pragmas separately, since we need to keep track of *where* + the pragmas were. */ + if (where != UNKNOWN_LOCATION) + { + int i; + + for (i = context->n_classification_history - 1; i >= 0; i --) + if (context->classification_history[i].option == option_index) + { + old_kind = context->classification_history[i].kind; + break; + } + + i = context->n_classification_history; + context->classification_history = + (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) + * sizeof (diagnostic_classification_change_t)); + context->classification_history[i].location = where; + context->classification_history[i].option = option_index; + context->classification_history[i].kind = new_kind; + context->n_classification_history ++; + } + else + context->classify_diagnostic[option_index] = new_kind; + return old_kind; } +/* Save all diagnostic classifications in a stack. */ +void +diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED) +{ + context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int)); + context->push_list[context->n_push ++] = context->n_classification_history; +} + +/* Restore the topmost classification set off the stack. If the stack + is empty, revert to the state based on command line parameters. */ +void +diagnostic_pop_diagnostics (diagnostic_context *context, location_t where) +{ + int jump_to; + int i; + + if (context->n_push) + jump_to = context->push_list [-- context->n_push]; + else + jump_to = 0; + + i = context->n_classification_history; + context->classification_history = + (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) + * sizeof (diagnostic_classification_change_t)); + context->classification_history[i].location = where; + context->classification_history[i].option = jump_to; + context->classification_history[i].kind = DK_POP; + context->n_classification_history ++; +} + /* Report a diagnostic message (an error or a warning) as specified by DC. This function is *the* subroutine in terms of which front-ends should implement their specific diagnostic handling modules. The @@ -321,12 +408,12 @@ /* Give preference to being able to inhibit warnings, before they get reclassified to something else. */ if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN) - && !diagnostic_report_warnings_p (location)) + && !diagnostic_report_warnings_p (context, location)) return false; if (diagnostic->kind == DK_PEDWARN) { - diagnostic->kind = pedantic_warning_kind (); + diagnostic->kind = pedantic_warning_kind (context); /* We do this to avoid giving the message for -pedantic-errors. */ orig_diag_kind = diagnostic->kind; } @@ -357,13 +444,42 @@ if (diagnostic->option_index) { + diagnostic_t diag_class = DK_UNSPECIFIED; + /* This tests if the user provided the appropriate -Wfoo or -Wno-foo option. */ - if (! option_enabled (diagnostic->option_index)) + if (! context->option_enabled (diagnostic->option_index, + context->option_state)) return false; + + /* This tests for #pragma diagnostic changes. */ + if (context->n_classification_history > 0) + { + int i; + /* FIXME: Stupid search. Optimize later. */ + for (i = context->n_classification_history - 1; i >= 0; i --) + { + if (context->classification_history[i].location <= location) + { + if (context->classification_history[i].kind == (int) DK_POP) + { + i = context->classification_history[i].option; + continue; + } + if (context->classification_history[i].option == diagnostic->option_index) + { + diag_class = context->classification_history[i].kind; + if (diag_class != DK_UNSPECIFIED) + diagnostic->kind = diag_class; + break; + } + } + } + } /* This tests if the user provided the appropriate -Werror=foo option. */ - if (context->classify_diagnostic[diagnostic->option_index] != DK_UNSPECIFIED) + if (diag_class == DK_UNSPECIFIED + && context->classify_diagnostic[diagnostic->option_index] != DK_UNSPECIFIED) { diagnostic->kind = context->classify_diagnostic[diagnostic->option_index]; } @@ -378,14 +494,6 @@ context->lock++; - if (diagnostic->kind == DK_ICE && plugins_active_p ()) - { - fnotice (stderr, "*** WARNING *** there are active plugins, do not report" - " this as a bug unless you can reproduce it without enabling" - " any plugins.\n"); - dump_active_plugins (stderr); - } - if (diagnostic->kind == DK_ICE) { #ifndef ENABLE_CHECKING @@ -403,7 +511,8 @@ } #endif if (context->internal_error) - (*context->internal_error) (diagnostic->message.format_spec, + (*context->internal_error) (context, + diagnostic->message.format_spec, diagnostic->message.args_ptr); } ++diagnostic_kind_count (context, diagnostic->kind); @@ -411,38 +520,20 @@ saved_format_spec = diagnostic->message.format_spec; if (context->show_option_requested) { - const char * option_text = NULL; + char *option_text; - if (diagnostic->option_index) - { - /* A warning classified as an error. */ - if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN) - && diagnostic->kind == DK_ERROR) - option_text - = ACONCAT ((cl_options[OPT_Werror_].opt_text, - /* Skip over "-W". */ - cl_options[diagnostic->option_index].opt_text + 2, - NULL)); - /* A warning with option. */ - else - option_text = cl_options[diagnostic->option_index].opt_text; - } - /* A warning without option classified as an error. */ - else if (orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN - || diagnostic->kind == DK_WARNING) - { - if (context->warning_as_error_requested) - option_text = cl_options[OPT_Werror].opt_text; - else - option_text = _("enabled by default"); - } + option_text = context->option_name (context, diagnostic->option_index, + orig_diag_kind, diagnostic->kind); if (option_text) - diagnostic->message.format_spec - = ACONCAT ((diagnostic->message.format_spec, - " ", - "[", option_text, "]", - NULL)); + { + diagnostic->message.format_spec + = ACONCAT ((diagnostic->message.format_spec, + " ", + "[", option_text, "]", + NULL)); + free (option_text); + } } diagnostic->message.locus = &diagnostic->location; diagnostic->message.x_data = &diagnostic->x_data; @@ -524,8 +615,8 @@ if (kind == DK_PERMERROR) { diagnostic_set_info (&diagnostic, gmsgid, &ap, location, - permissive_error_kind ()); - diagnostic.option_index = OPT_fpermissive; + permissive_error_kind (global_dc)); + diagnostic.option_index = permissive_error_option (global_dc); } else { diagnostic_set_info (&diagnostic, gmsgid, &ap, location, kind); @@ -643,8 +734,8 @@ va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, location, - permissive_error_kind ()); - diagnostic.option_index = OPT_fpermissive; + permissive_error_kind (global_dc)); + diagnostic.option_index = permissive_error_option (global_dc); va_end (ap); return report_diagnostic (&diagnostic); } @@ -708,6 +799,14 @@ va_end (ap); } +/* Return true if an error or a "sorry" has been seen. Various + processing is disabled after errors. */ +bool +seen_error (void) +{ + return errorcount || sorrycount; +} + /* An error which is severe enough that we make no attempt to continue. Do not use this for internal consistency checks; that's internal_error. Use of this function should be rare. */