X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdiagnostic.c;h=c25c0ec547279c38192b08d034845833d9024d66;hb=e899394fb23ac27aa81b27136052a13e7f2b840d;hp=db4c8fec4da63e2060bdfa709838f997fac16ab1;hpb=7bd3dcc4338f994821b15d15b47f76779c6b323c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index db4c8fec4da..c25c0ec5472 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -51,7 +51,6 @@ static void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; -static bool text_specifies_location (text_info *, location_t *); static bool diagnostic_count_diagnostic (diagnostic_context *, diagnostic_info *); static void diagnostic_action_after_output (diagnostic_context *, @@ -61,13 +60,6 @@ static void real_abort (void) ATTRIBUTE_NORETURN; /* A diagnostic_context surrogate for stderr. */ static diagnostic_context global_diagnostic_context; diagnostic_context *global_dc = &global_diagnostic_context; - -/* Boilerplate text used in two locations. */ -#define bug_report_request \ -"Please submit a full bug report,\n\ -with preprocessed source if appropriate.\n\ -See %s for instructions.\n" - /* Return a malloc'd string containing MSG formatted a la printf. The caller is responsible for freeing the memory. */ @@ -107,7 +99,8 @@ diagnostic_initialize (diagnostic_context *context) context->printer->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_ONCE; memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); - context->warnings_are_errors_message = warnings_are_errors; + context->issue_warnings_are_errors_message = true; + context->warning_as_error_requested = false; context->abort_on_error = false; context->internal_error = NULL; diagnostic_starter (context) = default_diagnostic_starter; @@ -115,36 +108,6 @@ diagnostic_initialize (diagnostic_context *context) context->last_module = 0; context->last_function = NULL; context->lock = 0; - context->x_data = NULL; -} - -/* Returns true if the next format specifier in TEXT is a format specifier - for a location_t. If so, update the object pointed by LOCUS to reflect - the specified location in *TEXT->args_ptr. */ -static bool -text_specifies_location (text_info *text, location_t *locus) -{ - const char *p; - /* Skip any leading text. */ - for (p = text->format_spec; *p && *p != '%'; ++p) - ; - - /* Extract the location information if any. */ - if (p[0] == '%' && p[1] == 'H') - { - *locus = *va_arg (*text->args_ptr, location_t *); - text->format_spec = p + 2; - return true; - } - else if (p[0] == '%' && p[1] == 'J') - { - tree t = va_arg (*text->args_ptr, tree); - *locus = DECL_SOURCE_LOCATION (t); - text->format_spec = p + 2; - return true; - } - - return false; } void @@ -155,10 +118,7 @@ diagnostic_set_info (diagnostic_info *diagnostic, const char *msgid, diagnostic->message.err_no = errno; diagnostic->message.args_ptr = args; diagnostic->message.format_spec = _(msgid); - /* If the diagnostic message doesn't specify a location, - use LOCATION. */ - if (!text_specifies_location (&diagnostic->message, &diagnostic->location)) - diagnostic->location = location; + diagnostic->location = location; diagnostic->kind = kind; } @@ -174,8 +134,7 @@ diagnostic_build_prefix (diagnostic_info *diagnostic) "must-not-happen" }; expanded_location s = expand_location (diagnostic->location); - if (diagnostic->kind >= DK_LAST_DIAGNOSTIC_KIND) - abort(); + gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); return s.file ? build_message_string ("%s:%d: %s", @@ -194,8 +153,7 @@ diagnostic_count_diagnostic (diagnostic_context *context, switch (kind) { default: - abort(); - break; + gcc_unreachable (); case DK_ICE: #ifndef ENABLE_CHECKING @@ -226,17 +184,16 @@ diagnostic_count_diagnostic (diagnostic_context *context, if (!diagnostic_report_warnings_p ()) return false; - if (!warnings_are_errors) + if (!context->warning_as_error_requested) { ++diagnostic_kind_count (context, DK_WARNING); break; } - - if (context->warnings_are_errors_message) + else if (context->issue_warnings_are_errors_message) { pp_verbatim (context->printer, "%s: warnings being treated as errors\n", progname); - context->warnings_are_errors_message = false; + context->issue_warnings_are_errors_message = false; } /* And fall through. */ @@ -277,7 +234,9 @@ diagnostic_action_after_output (diagnostic_context *context, if (context->abort_on_error) real_abort (); - fnotice (stderr, bug_report_request, bug_report_url); + fnotice (stderr, "Please submit a full bug report,\n" + "with preprocessed source if appropriate.\n" + "See %s for instructions.\n", bug_report_url); exit (FATAL_EXIT_CODE); case DK_FATAL: @@ -288,14 +247,12 @@ diagnostic_action_after_output (diagnostic_context *context, exit (FATAL_EXIT_CODE); default: - real_abort (); + gcc_unreachable (); } } /* Prints out, if necessary, the name of the current function - that caused an error. Called from all error and warning functions. - We ignore the FILE parameter, as it cannot be relied upon. */ - + that caused an error. Called from all error and warning functions. */ void diagnostic_report_current_function (diagnostic_context *context) { @@ -358,11 +315,23 @@ void diagnostic_report_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic) { - if (context->lock++ && diagnostic->kind < DK_SORRY) - error_recursion (context); + if (context->lock > 0) + { + /* 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) + pp_flush (context->printer); + else + error_recursion (context); + } + + context->lock++; if (diagnostic_count_diagnostic (context, diagnostic)) { + pp_prepare_to_format (context->printer, &diagnostic->message, + &diagnostic->location); (*diagnostic_starter (context)) (context, diagnostic); pp_format_text (context->printer, &diagnostic->message); (*diagnostic_finalizer (context)) (context, diagnostic); @@ -386,20 +355,10 @@ trim_filename (const char *name) /* First skip any "../" in each filename. This allows us to give a proper reference to a file in a subdirectory. */ - while (p[0] == '.' && p[1] == '.' - && (p[2] == DIR_SEPARATOR -#ifdef DIR_SEPARATOR_2 - || p[2] == DIR_SEPARATOR_2 -#endif - )) + while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2])) p += 3; - while (q[0] == '.' && q[1] == '.' - && (q[2] == DIR_SEPARATOR -#ifdef DIR_SEPARATOR_2 - || p[2] == DIR_SEPARATOR_2 -#endif - )) + while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2])) q += 3; /* Now skip any parts the two filenames have in common. */ @@ -407,11 +366,7 @@ trim_filename (const char *name) p++, q++; /* Now go backwards until the previous directory separator. */ - while (p > name && p[-1] != DIR_SEPARATOR -#ifdef DIR_SEPARATOR_2 - && p[-1] != DIR_SEPARATOR_2 -#endif - ) + while (p > name && !IS_DIR_SEPARATOR (p[-1])) p--; return p; @@ -529,8 +484,7 @@ fatal_error (const char *msgid, ...) report_diagnostic (&diagnostic); va_end (ap); - /* NOTREACHED */ - real_abort (); + gcc_unreachable (); } /* An internal consistency check has failed. We make no attempt to @@ -548,8 +502,7 @@ internal_error (const char *msgid, ...) report_diagnostic (&diagnostic); va_end (ap); - /* NOTREACHED */ - real_abort (); + gcc_unreachable (); } /* Special case error functions. Most are implemented in terms of the @@ -575,13 +528,22 @@ fnotice (FILE *file, const char *msgid, ...) static void error_recursion (diagnostic_context *context) { + diagnostic_info diagnostic; + if (context->lock < 3) pp_flush (context->printer); fnotice (stderr, "Internal compiler error: Error reporting routines re-entered.\n"); - fnotice (stderr, bug_report_request, bug_report_url); - exit (FATAL_EXIT_CODE); + + /* Call diagnostic_action_after_output to get the "please submit a bug + report" message. It only looks at the kind field of diagnostic_info. */ + diagnostic.kind = DK_ICE; + diagnostic_action_after_output (context, &diagnostic); + + /* Do not use gcc_unreachable here; that goes through internal_error + and therefore would cause infinite recursion. */ + real_abort (); } /* Report an internal compiler error in a friendly manner. This is