00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032 #undef FLOAT
00033 #undef FFS
00034 #include "system.h"
00035 #include "coretypes.h"
00036 #include "tm.h"
00037 #include "tree.h"
00038 #include "version.h"
00039 #include "tm_p.h"
00040 #include "flags.h"
00041 #include "input.h"
00042 #include "toplev.h"
00043 #include "intl.h"
00044 #include "diagnostic.h"
00045 #include "langhooks.h"
00046 #include "langhooks-def.h"
00047
00048 #ifdef KEY
00049 #define RC_GCC_INTERNAL_ERROR 34
00050 #endif
00051
00052
00053 static char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
00054
00055 static void default_diagnostic_starter (diagnostic_context *,
00056 diagnostic_info *);
00057 static void default_diagnostic_finalizer (diagnostic_context *,
00058 diagnostic_info *);
00059
00060 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
00061 static bool diagnostic_count_diagnostic (diagnostic_context *,
00062 diagnostic_info *);
00063 static void diagnostic_action_after_output (diagnostic_context *,
00064 diagnostic_info *);
00065 static void real_abort (void) ATTRIBUTE_NORETURN;
00066
00067
00068 static diagnostic_context global_diagnostic_context;
00069 diagnostic_context *global_dc = &global_diagnostic_context;
00070
00071
00072
00073 static char *
00074 build_message_string (const char *msg, ...)
00075 {
00076 char *str;
00077 va_list ap;
00078
00079 va_start (ap, msg);
00080 vasprintf (&str, msg, ap);
00081 va_end (ap);
00082
00083 return str;
00084 }
00085
00086
00087 char *
00088 file_name_as_prefix (const char *f)
00089 {
00090 return build_message_string ("%s: ", f);
00091 }
00092
00093
00094
00095
00096 void
00097 diagnostic_initialize (diagnostic_context *context)
00098 {
00099
00100
00101 context->printer = xmalloc (sizeof (pretty_printer));
00102 pp_construct (context->printer, NULL, 0);
00103
00104 context->printer->buffer->stream = stderr;
00105
00106 context->printer->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_ONCE;
00107
00108 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
00109 context->issue_warnings_are_errors_message = true;
00110 context->warning_as_error_requested = false;
00111 context->abort_on_error = false;
00112 context->internal_error = NULL;
00113 diagnostic_starter (context) = default_diagnostic_starter;
00114 diagnostic_finalizer (context) = default_diagnostic_finalizer;
00115 context->last_module = 0;
00116 context->last_function = NULL;
00117 context->lock = 0;
00118 }
00119
00120 void
00121 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
00122 va_list *args, location_t location,
00123 diagnostic_t kind)
00124 {
00125 diagnostic->message.err_no = errno;
00126 diagnostic->message.args_ptr = args;
00127 diagnostic->message.format_spec = _(gmsgid);
00128 diagnostic->location = location;
00129 diagnostic->kind = kind;
00130 }
00131
00132
00133
00134 char *
00135 diagnostic_build_prefix (diagnostic_info *diagnostic)
00136 {
00137 static const char *const diagnostic_kind_text[] = {
00138 #define DEFINE_DIAGNOSTIC_KIND(K, T) (T),
00139 #include "diagnostic.def"
00140 #undef DEFINE_DIAGNOSTIC_KIND
00141 "must-not-happen"
00142 };
00143 expanded_location s = expand_location (diagnostic->location);
00144 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
00145
00146 return s.file
00147 ? build_message_string ("%s:%d: %s",
00148 s.file, s.line,
00149 _(diagnostic_kind_text[diagnostic->kind]))
00150 : build_message_string ("%s: %s", progname,
00151 _(diagnostic_kind_text[diagnostic->kind]));
00152 }
00153
00154
00155 static bool
00156 diagnostic_count_diagnostic (diagnostic_context *context,
00157 diagnostic_info *diagnostic)
00158 {
00159 diagnostic_t kind = diagnostic->kind;
00160 switch (kind)
00161 {
00162 default:
00163 gcc_unreachable ();
00164
00165 case DK_ICE:
00166 #ifndef ENABLE_CHECKING
00167
00168
00169
00170 if ((diagnostic_kind_count (context, DK_ERROR) > 0
00171 || diagnostic_kind_count (context, DK_SORRY) > 0)
00172 && !context->abort_on_error)
00173 {
00174 expanded_location s = expand_location (diagnostic->location);
00175 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
00176 s.file, s.line);
00177 #ifdef KEY
00178 fnotice (stderr, "GNU front-end error.\n");
00179 exit (RC_GCC_INTERNAL_ERROR);
00180 #endif
00181 exit (FATAL_EXIT_CODE);
00182 }
00183 #endif
00184 if (context->internal_error)
00185 (*context->internal_error) (diagnostic->message.format_spec,
00186 diagnostic->message.args_ptr);
00187
00188
00189 case DK_FATAL: case DK_SORRY:
00190 case DK_ANACHRONISM: case DK_NOTE:
00191 ++diagnostic_kind_count (context, kind);
00192 break;
00193
00194 case DK_WARNING:
00195 if (!diagnostic_report_warnings_p ())
00196 return false;
00197
00198 if (!context->warning_as_error_requested)
00199 {
00200 ++diagnostic_kind_count (context, DK_WARNING);
00201 break;
00202 }
00203 else if (context->issue_warnings_are_errors_message)
00204 {
00205 pp_verbatim (context->printer,
00206 "%s: warnings being treated as errors\n", progname);
00207 context->issue_warnings_are_errors_message = false;
00208 }
00209
00210
00211 case DK_ERROR:
00212 ++diagnostic_kind_count (context, DK_ERROR);
00213 break;
00214 }
00215
00216 return true;
00217 }
00218
00219
00220
00221 static void
00222 diagnostic_action_after_output (diagnostic_context *context,
00223 diagnostic_info *diagnostic)
00224 {
00225 switch (diagnostic->kind)
00226 {
00227 case DK_DEBUG:
00228 case DK_NOTE:
00229 case DK_ANACHRONISM:
00230 case DK_WARNING:
00231 break;
00232
00233 case DK_ERROR:
00234 case DK_SORRY:
00235 if (context->abort_on_error)
00236 real_abort ();
00237 if (flag_fatal_errors)
00238 {
00239 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
00240 #ifdef KEY
00241 fnotice (stderr, "GNU front-end error.\n");
00242 exit (RC_GCC_INTERNAL_ERROR);
00243 #endif
00244 exit (FATAL_EXIT_CODE);
00245 }
00246 break;
00247
00248 case DK_ICE:
00249 if (context->abort_on_error)
00250 real_abort ();
00251
00252 fnotice (stderr, "Please submit a full bug report,\n"
00253 "with preprocessed source if appropriate.\n"
00254 "See %s for instructions.\n", bug_report_url);
00255 #ifdef KEY
00256 fnotice (stderr, "GNU front-end error.\n");
00257 exit (RC_GCC_INTERNAL_ERROR);
00258 #endif
00259 exit (FATAL_EXIT_CODE);
00260
00261 case DK_FATAL:
00262 if (context->abort_on_error)
00263 real_abort ();
00264
00265 fnotice (stderr, "compilation terminated.\n");
00266 #ifdef KEY
00267 fnotice (stderr, "GNU front-end error.\n");
00268 exit (RC_GCC_INTERNAL_ERROR);
00269 #endif
00270 exit (FATAL_EXIT_CODE);
00271
00272 default:
00273 gcc_unreachable ();
00274 }
00275 }
00276
00277
00278
00279 void
00280 diagnostic_report_current_function (diagnostic_context *context)
00281 {
00282 diagnostic_report_current_module (context);
00283 lang_hooks.print_error_function (context, input_filename);
00284 }
00285
00286 void
00287 diagnostic_report_current_module (diagnostic_context *context)
00288 {
00289 struct file_stack *p;
00290
00291 if (pp_needs_newline (context->printer))
00292 {
00293 pp_newline (context->printer);
00294 pp_needs_newline (context->printer) = false;
00295 }
00296
00297 p = input_file_stack;
00298 if (p && diagnostic_last_module_changed (context))
00299 {
00300 expanded_location xloc = expand_location (p->location);
00301 pp_verbatim (context->printer,
00302 "In file included from %s:%d",
00303 xloc.file, xloc.line);
00304 while ((p = p->next) != NULL)
00305 {
00306 xloc = expand_location (p->location);
00307 pp_verbatim (context->printer,
00308 ",\n from %s:%d",
00309 xloc.file, xloc.line);
00310 }
00311 pp_verbatim (context->printer, ":\n");
00312 diagnostic_set_last_module (context);
00313 }
00314 }
00315
00316 static void
00317 default_diagnostic_starter (diagnostic_context *context,
00318 diagnostic_info *diagnostic)
00319 {
00320 diagnostic_report_current_function (context);
00321 pp_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
00322 }
00323
00324 static void
00325 default_diagnostic_finalizer (diagnostic_context *context,
00326 diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
00327 {
00328 pp_destroy_prefix (context->printer);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 void
00338 diagnostic_report_diagnostic (diagnostic_context *context,
00339 diagnostic_info *diagnostic)
00340 {
00341 if (context->lock > 0)
00342 {
00343
00344
00345
00346 if (diagnostic->kind == DK_ICE && context->lock == 1)
00347 pp_flush (context->printer);
00348 else
00349 error_recursion (context);
00350 }
00351
00352 context->lock++;
00353
00354 if (diagnostic_count_diagnostic (context, diagnostic))
00355 {
00356 pp_prepare_to_format (context->printer, &diagnostic->message,
00357 &diagnostic->location);
00358 (*diagnostic_starter (context)) (context, diagnostic);
00359 pp_format_text (context->printer, &diagnostic->message);
00360 (*diagnostic_finalizer (context)) (context, diagnostic);
00361 pp_flush (context->printer);
00362 diagnostic_action_after_output (context, diagnostic);
00363 }
00364
00365 context->lock--;
00366 }
00367
00368
00369
00370
00371
00372
00373 const char *
00374 trim_filename (const char *name)
00375 {
00376 static const char this_file[] = __FILE__;
00377 const char *p = name, *q = this_file;
00378
00379
00380
00381 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
00382 p += 3;
00383
00384 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
00385 q += 3;
00386
00387
00388 while (*p == *q && *p != 0 && *q != 0)
00389 p++, q++;
00390
00391
00392 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
00393 p--;
00394
00395 return p;
00396 }
00397
00398
00399
00400
00401
00402
00403 void
00404 verbatim (const char *gmsgid, ...)
00405 {
00406 text_info text;
00407 va_list ap;
00408
00409 va_start (ap, gmsgid);
00410 text.err_no = errno;
00411 text.args_ptr = ≈
00412 text.format_spec = _(gmsgid);
00413 pp_format_verbatim (global_dc->printer, &text);
00414 pp_flush (global_dc->printer);
00415 va_end (ap);
00416 }
00417
00418
00419
00420 void
00421 inform (const char *gmsgid, ...)
00422 {
00423 diagnostic_info diagnostic;
00424 va_list ap;
00425
00426 va_start (ap, gmsgid);
00427 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_NOTE);
00428 report_diagnostic (&diagnostic);
00429 va_end (ap);
00430 }
00431
00432
00433
00434 void
00435 warning (const char *gmsgid, ...)
00436 {
00437 diagnostic_info diagnostic;
00438 va_list ap;
00439
00440 va_start (ap, gmsgid);
00441 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_WARNING);
00442 report_diagnostic (&diagnostic);
00443 va_end (ap);
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 void
00455 pedwarn (const char *gmsgid, ...)
00456 {
00457 diagnostic_info diagnostic;
00458 va_list ap;
00459
00460 va_start (ap, gmsgid);
00461 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
00462 pedantic_error_kind ());
00463 report_diagnostic (&diagnostic);
00464 va_end (ap);
00465 }
00466
00467
00468
00469 void
00470 error (const char *gmsgid, ...)
00471 {
00472 diagnostic_info diagnostic;
00473 va_list ap;
00474
00475 va_start (ap, gmsgid);
00476 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_ERROR);
00477 report_diagnostic (&diagnostic);
00478 va_end (ap);
00479 }
00480
00481
00482
00483
00484 void
00485 sorry (const char *gmsgid, ...)
00486 {
00487 diagnostic_info diagnostic;
00488 va_list ap;
00489
00490 va_start (ap, gmsgid);
00491 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_SORRY);
00492 report_diagnostic (&diagnostic);
00493 va_end (ap);
00494 }
00495
00496
00497
00498
00499 void
00500 fatal_error (const char *gmsgid, ...)
00501 {
00502 diagnostic_info diagnostic;
00503 va_list ap;
00504
00505 va_start (ap, gmsgid);
00506 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_FATAL);
00507 report_diagnostic (&diagnostic);
00508 va_end (ap);
00509
00510 gcc_unreachable ();
00511 }
00512
00513
00514
00515
00516
00517 void
00518 internal_error (const char *gmsgid, ...)
00519 {
00520 diagnostic_info diagnostic;
00521 va_list ap;
00522
00523 va_start (ap, gmsgid);
00524 diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_ICE);
00525 report_diagnostic (&diagnostic);
00526 va_end (ap);
00527
00528 gcc_unreachable ();
00529 }
00530
00531
00532
00533
00534
00535
00536 void
00537 fnotice (FILE *file, const char *cmsgid, ...)
00538 {
00539 va_list ap;
00540
00541 va_start (ap, cmsgid);
00542 vfprintf (file, _(cmsgid), ap);
00543 va_end (ap);
00544 }
00545
00546
00547
00548
00549
00550
00551 static void
00552 error_recursion (diagnostic_context *context)
00553 {
00554 diagnostic_info diagnostic;
00555
00556 if (context->lock < 3)
00557 pp_flush (context->printer);
00558
00559 fnotice (stderr,
00560 "Internal compiler error: Error reporting routines re-entered.\n");
00561
00562
00563
00564 diagnostic.kind = DK_ICE;
00565 diagnostic_action_after_output (context, &diagnostic);
00566
00567
00568
00569 real_abort ();
00570 }
00571
00572
00573
00574
00575
00576 void
00577 fancy_abort (const char *file, int line, const char *function)
00578 {
00579 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
00580 }
00581
00582
00583
00584
00585 #undef abort
00586 static void
00587 real_abort (void)
00588 {
00589 #ifdef KEY
00590 fnotice (stderr, "GNU front-end error.\n");
00591 exit (RC_GCC_INTERNAL_ERROR);
00592 #endif
00593 abort ();
00594 }