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