Mercurial > hg > CbC > CbC_gcc
annotate gcc/diagnostic.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection |
145 | 2 Copyright (C) 1999-2020 Free Software Foundation, Inc. |
0 | 3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com> |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 | |
22 /* This file implements the language independent aspect of diagnostic | |
23 message module. */ | |
24 | |
25 #include "config.h" | |
26 #include "system.h" | |
27 #include "coretypes.h" | |
28 #include "version.h" | |
111 | 29 #include "demangle.h" |
0 | 30 #include "intl.h" |
111 | 31 #include "backtrace.h" |
0 | 32 #include "diagnostic.h" |
111 | 33 #include "diagnostic-color.h" |
145 | 34 #include "diagnostic-url.h" |
35 #include "diagnostic-metadata.h" | |
36 #include "diagnostic-path.h" | |
111 | 37 #include "edit-context.h" |
38 #include "selftest.h" | |
131 | 39 #include "selftest-diagnostic.h" |
145 | 40 #include "opts.h" |
111 | 41 |
42 #ifdef HAVE_TERMIOS_H | |
43 # include <termios.h> | |
44 #endif | |
45 | |
46 #ifdef GWINSZ_IN_SYS_IOCTL | |
47 # include <sys/ioctl.h> | |
48 #endif | |
0 | 49 |
145 | 50 /* Disable warnings about quoting issues in the pp_xxx calls below |
51 that (intentionally) don't follow GCC diagnostic conventions. */ | |
52 #if __GNUC__ >= 10 | |
53 # pragma GCC diagnostic push | |
54 # pragma GCC diagnostic ignored "-Wformat-diag" | |
55 #endif | |
56 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
57 #define pedantic_warning_kind(DC) \ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
58 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
59 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
60 #define permissive_error_option(DC) ((DC)->opt_permissive) |
0 | 61 |
62 /* Prototypes. */ | |
145 | 63 static bool diagnostic_impl (rich_location *, const diagnostic_metadata *, |
64 int, const char *, | |
65 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0); | |
66 static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *, | |
67 int, unsigned HOST_WIDE_INT, | |
131 | 68 const char *, const char *, va_list *, |
145 | 69 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0); |
0 | 70 |
71 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; | |
72 static void real_abort (void) ATTRIBUTE_NORETURN; | |
73 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
74 /* Name of program invoked, sans directories. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
75 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
76 const char *progname; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
77 |
0 | 78 /* A diagnostic_context surrogate for stderr. */ |
79 static diagnostic_context global_diagnostic_context; | |
80 diagnostic_context *global_dc = &global_diagnostic_context; | |
81 | |
82 /* Return a malloc'd string containing MSG formatted a la printf. The | |
83 caller is responsible for freeing the memory. */ | |
111 | 84 char * |
0 | 85 build_message_string (const char *msg, ...) |
86 { | |
87 char *str; | |
88 va_list ap; | |
89 | |
90 va_start (ap, msg); | |
111 | 91 str = xvasprintf (msg, ap); |
0 | 92 va_end (ap); |
93 | |
94 return str; | |
95 } | |
96 | |
97 /* Same as diagnostic_build_prefix, but only the source FILE is given. */ | |
98 char * | |
111 | 99 file_name_as_prefix (diagnostic_context *context, const char *f) |
0 | 100 { |
111 | 101 const char *locus_cs |
102 = colorize_start (pp_show_color (context->printer), "locus"); | |
103 const char *locus_ce = colorize_stop (pp_show_color (context->printer)); | |
104 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce); | |
0 | 105 } |
106 | |
107 | |
108 | |
111 | 109 /* Return the value of the getenv("COLUMNS") as an integer. If the |
110 value is not set to a positive integer, use ioctl to get the | |
111 terminal width. If it fails, return INT_MAX. */ | |
112 int | |
113 get_terminal_width (void) | |
114 { | |
115 const char * s = getenv ("COLUMNS"); | |
116 if (s != NULL) { | |
117 int n = atoi (s); | |
118 if (n > 0) | |
119 return n; | |
120 } | |
121 | |
122 #ifdef TIOCGWINSZ | |
123 struct winsize w; | |
124 w.ws_col = 0; | |
125 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0) | |
126 return w.ws_col; | |
127 #endif | |
128 | |
129 return INT_MAX; | |
130 } | |
131 | |
132 /* Set caret_max_width to value. */ | |
133 void | |
134 diagnostic_set_caret_max_width (diagnostic_context *context, int value) | |
135 { | |
136 /* One minus to account for the leading empty space. */ | |
137 value = value ? value - 1 | |
138 : (isatty (fileno (pp_buffer (context->printer)->stream)) | |
139 ? get_terminal_width () - 1: INT_MAX); | |
140 | |
141 if (value <= 0) | |
142 value = INT_MAX; | |
143 | |
144 context->caret_max_width = value; | |
145 } | |
146 | |
145 | 147 /* Default implementation of final_cb. */ |
148 | |
149 static void | |
150 default_diagnostic_final_cb (diagnostic_context *context) | |
151 { | |
152 /* Some of the errors may actually have been warnings. */ | |
153 if (diagnostic_kind_count (context, DK_WERROR)) | |
154 { | |
155 /* -Werror was given. */ | |
156 if (context->warning_as_error_requested) | |
157 pp_verbatim (context->printer, | |
158 _("%s: all warnings being treated as errors"), | |
159 progname); | |
160 /* At least one -Werror= was given. */ | |
161 else | |
162 pp_verbatim (context->printer, | |
163 _("%s: some warnings being treated as errors"), | |
164 progname); | |
165 pp_newline_and_flush (context->printer); | |
166 } | |
167 } | |
168 | |
0 | 169 /* Initialize the diagnostic message outputting machinery. */ |
170 void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
171 diagnostic_initialize (diagnostic_context *context, int n_opts) |
0 | 172 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
173 int i; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
174 |
0 | 175 /* Allocate a basic pretty-printer. Clients will replace this a |
176 much more elaborated pretty-printer if they wish. */ | |
177 context->printer = XNEW (pretty_printer); | |
111 | 178 new (context->printer) pretty_printer (); |
0 | 179 |
180 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); | |
181 context->warning_as_error_requested = false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
182 context->n_opts = n_opts; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
183 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
184 for (i = 0; i < n_opts; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
185 context->classify_diagnostic[i] = DK_UNSPECIFIED; |
111 | 186 context->show_caret = false; |
187 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer)); | |
188 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) | |
189 context->caret_chars[i] = '^'; | |
145 | 190 context->show_cwe = false; |
191 context->path_format = DPF_NONE; | |
192 context->show_path_depths = false; | |
0 | 193 context->show_option_requested = false; |
194 context->abort_on_error = false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
195 context->show_column = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
196 context->pedantic_errors = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
197 context->permissive = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
198 context->opt_permissive = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
199 context->fatal_errors = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
200 context->dc_inhibit_warnings = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
201 context->dc_warn_system_headers = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
202 context->max_errors = 0; |
0 | 203 context->internal_error = NULL; |
204 diagnostic_starter (context) = default_diagnostic_starter; | |
111 | 205 context->start_span = default_diagnostic_start_span_fn; |
0 | 206 diagnostic_finalizer (context) = default_diagnostic_finalizer; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
207 context->option_enabled = NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
208 context->option_state = NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
209 context->option_name = NULL; |
145 | 210 context->get_option_url = NULL; |
111 | 211 context->last_location = UNKNOWN_LOCATION; |
0 | 212 context->last_module = 0; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
213 context->x_data = NULL; |
0 | 214 context->lock = 0; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
215 context->inhibit_notes_p = false; |
111 | 216 context->colorize_source_p = false; |
131 | 217 context->show_labels_p = false; |
218 context->show_line_numbers_p = false; | |
219 context->min_margin_width = 0; | |
111 | 220 context->show_ruler_p = false; |
221 context->parseable_fixits_p = false; | |
222 context->edit_context_ptr = NULL; | |
131 | 223 context->diagnostic_group_nesting_depth = 0; |
224 context->diagnostic_group_emission_count = 0; | |
225 context->begin_group_cb = NULL; | |
226 context->end_group_cb = NULL; | |
145 | 227 context->final_cb = default_diagnostic_final_cb; |
111 | 228 } |
229 | |
230 /* Maybe initialize the color support. We require clients to do this | |
231 explicitly, since most clients don't want color. When called | |
232 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */ | |
233 | |
234 void | |
235 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */) | |
236 { | |
237 /* value == -1 is the default value. */ | |
238 if (value < 0) | |
239 { | |
240 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to | |
241 -fdiagnostics-color=auto if GCC_COLORS is in the environment, | |
242 otherwise default to -fdiagnostics-color=never, for other | |
243 values default to that | |
244 -fdiagnostics-color={never,auto,always}. */ | |
245 if (DIAGNOSTICS_COLOR_DEFAULT == -1) | |
246 { | |
247 if (!getenv ("GCC_COLORS")) | |
248 return; | |
249 value = DIAGNOSTICS_COLOR_AUTO; | |
250 } | |
251 else | |
252 value = DIAGNOSTICS_COLOR_DEFAULT; | |
253 } | |
254 pp_show_color (context->printer) | |
255 = colorize_init ((diagnostic_color_rule_t) value); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
256 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
257 |
145 | 258 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */ |
259 | |
260 void | |
261 diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */) | |
262 { | |
263 if (value < 0) | |
264 value = DIAGNOSTICS_COLOR_DEFAULT; | |
265 | |
266 context->printer->show_urls | |
267 = diagnostic_urls_enabled_p ((diagnostic_url_rule_t) value); | |
268 } | |
269 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
270 /* Do any cleaning up required after the last diagnostic is emitted. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
271 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
272 void |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
273 diagnostic_finish (diagnostic_context *context) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
274 { |
145 | 275 if (context->final_cb) |
276 context->final_cb (context); | |
111 | 277 |
278 diagnostic_file_cache_fini (); | |
279 | |
280 XDELETEVEC (context->classify_diagnostic); | |
281 context->classify_diagnostic = NULL; | |
282 | |
283 /* diagnostic_initialize allocates context->printer using XNEW | |
284 and placement-new. */ | |
285 context->printer->~pretty_printer (); | |
286 XDELETE (context->printer); | |
287 context->printer = NULL; | |
288 | |
289 if (context->edit_context_ptr) | |
290 { | |
291 delete context->edit_context_ptr; | |
292 context->edit_context_ptr = NULL; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
293 } |
0 | 294 } |
295 | |
296 /* Initialize DIAGNOSTIC, where the message MSG has already been | |
297 translated. */ | |
298 void | |
299 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, | |
111 | 300 va_list *args, rich_location *richloc, |
0 | 301 diagnostic_t kind) |
302 { | |
111 | 303 gcc_assert (richloc); |
0 | 304 diagnostic->message.err_no = errno; |
305 diagnostic->message.args_ptr = args; | |
306 diagnostic->message.format_spec = msg; | |
111 | 307 diagnostic->message.m_richloc = richloc; |
308 diagnostic->richloc = richloc; | |
145 | 309 diagnostic->metadata = NULL; |
0 | 310 diagnostic->kind = kind; |
311 diagnostic->option_index = 0; | |
312 } | |
313 | |
314 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been | |
315 translated. */ | |
316 void | |
317 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, | |
111 | 318 va_list *args, rich_location *richloc, |
0 | 319 diagnostic_t kind) |
320 { | |
111 | 321 gcc_assert (richloc); |
322 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind); | |
323 } | |
324 | |
325 static const char *const diagnostic_kind_color[] = { | |
326 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C), | |
327 #include "diagnostic.def" | |
328 #undef DEFINE_DIAGNOSTIC_KIND | |
329 NULL | |
330 }; | |
331 | |
332 /* Get a color name for diagnostics of type KIND | |
333 Result could be NULL. */ | |
334 | |
335 const char * | |
336 diagnostic_get_color_for_kind (diagnostic_t kind) | |
337 { | |
338 return diagnostic_kind_color[kind]; | |
0 | 339 } |
340 | |
131 | 341 /* Return a formatted line and column ':%line:%column'. Elided if |
342 zero. The result is a statically allocated buffer. */ | |
343 | |
344 static const char * | |
345 maybe_line_and_column (int line, int col) | |
346 { | |
347 static char result[32]; | |
348 | |
349 if (line) | |
350 { | |
351 size_t l = snprintf (result, sizeof (result), | |
352 col ? ":%d:%d" : ":%d", line, col); | |
353 gcc_checking_assert (l < sizeof (result)); | |
354 } | |
355 else | |
356 result[0] = 0; | |
357 return result; | |
358 } | |
359 | |
111 | 360 /* Return a malloc'd string describing a location e.g. "foo.c:42:10". |
361 The caller is responsible for freeing the memory. */ | |
362 | |
363 static char * | |
364 diagnostic_get_location_text (diagnostic_context *context, | |
365 expanded_location s) | |
366 { | |
367 pretty_printer *pp = context->printer; | |
368 const char *locus_cs = colorize_start (pp_show_color (pp), "locus"); | |
369 const char *locus_ce = colorize_stop (pp_show_color (pp)); | |
131 | 370 const char *file = s.file ? s.file : progname; |
371 int line = strcmp (file, N_("<built-in>")) ? s.line : 0; | |
372 int col = context->show_column ? s.column : 0; | |
111 | 373 |
131 | 374 const char *line_col = maybe_line_and_column (line, col); |
375 return build_message_string ("%s%s%s:%s", locus_cs, file, | |
376 line_col, locus_ce); | |
111 | 377 } |
378 | |
379 /* Return a malloc'd string describing a location and the severity of the | |
380 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for | |
381 freeing the memory. */ | |
0 | 382 char * |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
383 diagnostic_build_prefix (diagnostic_context *context, |
111 | 384 const diagnostic_info *diagnostic) |
0 | 385 { |
386 static const char *const diagnostic_kind_text[] = { | |
111 | 387 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T), |
0 | 388 #include "diagnostic.def" |
389 #undef DEFINE_DIAGNOSTIC_KIND | |
390 "must-not-happen" | |
391 }; | |
392 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); | |
393 | |
111 | 394 const char *text = _(diagnostic_kind_text[diagnostic->kind]); |
395 const char *text_cs = "", *text_ce = ""; | |
396 pretty_printer *pp = context->printer; | |
397 | |
398 if (diagnostic_kind_color[diagnostic->kind]) | |
399 { | |
400 text_cs = colorize_start (pp_show_color (pp), | |
401 diagnostic_kind_color[diagnostic->kind]); | |
402 text_ce = colorize_stop (pp_show_color (pp)); | |
403 } | |
404 | |
405 expanded_location s = diagnostic_expand_location (diagnostic); | |
406 char *location_text = diagnostic_get_location_text (context, s); | |
407 | |
408 char *result = build_message_string ("%s %s%s%s", location_text, | |
409 text_cs, text, text_ce); | |
410 free (location_text); | |
411 return result; | |
412 } | |
413 | |
414 /* Functions at which to stop the backtrace print. It's not | |
415 particularly helpful to print the callers of these functions. */ | |
416 | |
417 static const char * const bt_stop[] = | |
418 { | |
419 "main", | |
420 "toplev::main", | |
421 "execute_one_pass", | |
422 "compile_file", | |
423 }; | |
424 | |
425 /* A callback function passed to the backtrace_full function. */ | |
426 | |
427 static int | |
428 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, | |
429 const char *function) | |
430 { | |
431 int *pcount = (int *) data; | |
432 | |
433 /* If we don't have any useful information, don't print | |
434 anything. */ | |
435 if (filename == NULL && function == NULL) | |
436 return 0; | |
437 | |
438 /* Skip functions in diagnostic.c. */ | |
439 if (*pcount == 0 | |
440 && filename != NULL | |
441 && strcmp (lbasename (filename), "diagnostic.c") == 0) | |
442 return 0; | |
443 | |
444 /* Print up to 20 functions. We could make this a --param, but | |
445 since this is only for debugging just use a constant for now. */ | |
446 if (*pcount >= 20) | |
447 { | |
448 /* Returning a non-zero value stops the backtrace. */ | |
449 return 1; | |
450 } | |
451 ++*pcount; | |
452 | |
453 char *alc = NULL; | |
454 if (function != NULL) | |
455 { | |
456 char *str = cplus_demangle_v3 (function, | |
457 (DMGL_VERBOSE | DMGL_ANSI | |
458 | DMGL_GNU_V3 | DMGL_PARAMS)); | |
459 if (str != NULL) | |
460 { | |
461 alc = str; | |
462 function = str; | |
463 } | |
464 | |
465 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i) | |
466 { | |
467 size_t len = strlen (bt_stop[i]); | |
468 if (strncmp (function, bt_stop[i], len) == 0 | |
469 && (function[len] == '\0' || function[len] == '(')) | |
470 { | |
471 if (alc != NULL) | |
472 free (alc); | |
473 /* Returning a non-zero value stops the backtrace. */ | |
474 return 1; | |
475 } | |
476 } | |
477 } | |
478 | |
479 fprintf (stderr, "0x%lx %s\n\t%s:%d\n", | |
480 (unsigned long) pc, | |
481 function == NULL ? "???" : function, | |
482 filename == NULL ? "???" : filename, | |
483 lineno); | |
484 | |
485 if (alc != NULL) | |
486 free (alc); | |
487 | |
488 return 0; | |
489 } | |
490 | |
491 /* A callback function passed to the backtrace_full function. This is | |
492 called if backtrace_full has an error. */ | |
493 | |
494 static void | |
495 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum) | |
496 { | |
497 if (errnum < 0) | |
498 { | |
499 /* This means that no debug info was available. Just quietly | |
500 skip printing backtrace info. */ | |
501 return; | |
502 } | |
503 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ", | |
504 errnum == 0 ? "" : xstrerror (errnum)); | |
505 } | |
506 | |
507 /* Check if we've met the maximum error limit, and if so fatally exit | |
508 with a message. CONTEXT is the context to check, and FLUSH | |
509 indicates whether a diagnostic_finish call is needed. */ | |
510 | |
511 void | |
512 diagnostic_check_max_errors (diagnostic_context *context, bool flush) | |
513 { | |
514 if (!context->max_errors) | |
515 return; | |
516 | |
517 int count = (diagnostic_kind_count (context, DK_ERROR) | |
518 + diagnostic_kind_count (context, DK_SORRY) | |
519 + diagnostic_kind_count (context, DK_WERROR)); | |
520 | |
521 if (count >= context->max_errors) | |
522 { | |
523 fnotice (stderr, | |
524 "compilation terminated due to -fmax-errors=%u.\n", | |
525 context->max_errors); | |
526 if (flush) | |
527 diagnostic_finish (context); | |
528 exit (FATAL_EXIT_CODE); | |
529 } | |
0 | 530 } |
531 | |
532 /* Take any action which is expected to happen after the diagnostic | |
533 is written out. This function does not always return. */ | |
111 | 534 void |
0 | 535 diagnostic_action_after_output (diagnostic_context *context, |
111 | 536 diagnostic_t diag_kind) |
0 | 537 { |
111 | 538 switch (diag_kind) |
0 | 539 { |
540 case DK_DEBUG: | |
541 case DK_NOTE: | |
542 case DK_ANACHRONISM: | |
543 case DK_WARNING: | |
544 break; | |
545 | |
546 case DK_ERROR: | |
547 case DK_SORRY: | |
548 if (context->abort_on_error) | |
549 real_abort (); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
550 if (context->fatal_errors) |
0 | 551 { |
552 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n"); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
553 diagnostic_finish (context); |
0 | 554 exit (FATAL_EXIT_CODE); |
555 } | |
556 break; | |
557 | |
558 case DK_ICE: | |
111 | 559 case DK_ICE_NOBT: |
560 { | |
561 struct backtrace_state *state = NULL; | |
562 if (diag_kind == DK_ICE) | |
563 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL); | |
564 int count = 0; | |
565 if (state != NULL) | |
566 backtrace_full (state, 2, bt_callback, bt_err_callback, | |
567 (void *) &count); | |
0 | 568 |
111 | 569 if (context->abort_on_error) |
570 real_abort (); | |
571 | |
572 fnotice (stderr, "Please submit a full bug report,\n" | |
573 "with preprocessed source if appropriate.\n"); | |
574 if (count > 0) | |
575 fnotice (stderr, | |
576 ("Please include the complete backtrace " | |
577 "with any bug report.\n")); | |
578 fnotice (stderr, "See %s for instructions.\n", bug_report_url); | |
579 | |
580 exit (ICE_EXIT_CODE); | |
581 } | |
0 | 582 |
583 case DK_FATAL: | |
584 if (context->abort_on_error) | |
585 real_abort (); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
586 diagnostic_finish (context); |
0 | 587 fnotice (stderr, "compilation terminated.\n"); |
588 exit (FATAL_EXIT_CODE); | |
589 | |
590 default: | |
591 gcc_unreachable (); | |
592 } | |
593 } | |
594 | |
111 | 595 /* True if the last module or file in which a diagnostic was reported is |
596 different from the current one. */ | |
597 | |
598 static bool | |
599 last_module_changed_p (diagnostic_context *context, | |
600 const line_map_ordinary *map) | |
601 { | |
602 return context->last_module != map; | |
603 } | |
604 | |
605 /* Remember the current module or file as being the last one in which we | |
606 report a diagnostic. */ | |
607 | |
608 static void | |
609 set_last_module (diagnostic_context *context, const line_map_ordinary *map) | |
610 { | |
611 context->last_module = map; | |
612 } | |
613 | |
0 | 614 void |
111 | 615 diagnostic_report_current_module (diagnostic_context *context, location_t where) |
0 | 616 { |
111 | 617 const line_map_ordinary *map = NULL; |
0 | 618 |
619 if (pp_needs_newline (context->printer)) | |
620 { | |
621 pp_newline (context->printer); | |
622 pp_needs_newline (context->printer) = false; | |
623 } | |
624 | |
111 | 625 if (where <= BUILTINS_LOCATION) |
0 | 626 return; |
627 | |
111 | 628 linemap_resolve_location (line_table, where, |
629 LRK_MACRO_DEFINITION_LOCATION, | |
630 &map); | |
631 | |
632 if (map && last_module_changed_p (context, map)) | |
0 | 633 { |
111 | 634 set_last_module (context, map); |
0 | 635 if (! MAIN_FILE_P (map)) |
636 { | |
131 | 637 bool first = true; |
638 do | |
0 | 639 { |
131 | 640 where = linemap_included_from (map); |
641 map = linemap_included_from_linemap (line_table, map); | |
642 const char *line_col | |
643 = maybe_line_and_column (SOURCE_LINE (map, where), | |
644 first && context->show_column | |
645 ? SOURCE_COLUMN (map, where) : 0); | |
646 static const char *const msgs[] = | |
647 { | |
648 N_("In file included from"), | |
649 N_(" from"), | |
650 }; | |
651 unsigned index = !first; | |
652 pp_verbatim (context->printer, "%s%s %r%s%s%R", | |
653 first ? "" : ",\n", _(msgs[index]), | |
654 "locus", LINEMAP_FILE (map), line_col); | |
655 first = false; | |
0 | 656 } |
131 | 657 while (! MAIN_FILE_P (map)); |
0 | 658 pp_verbatim (context->printer, ":"); |
659 pp_newline (context->printer); | |
660 } | |
661 } | |
662 } | |
663 | |
145 | 664 /* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths, |
665 print the path. */ | |
666 | |
667 void | |
668 diagnostic_show_any_path (diagnostic_context *context, | |
669 diagnostic_info *diagnostic) | |
670 { | |
671 const diagnostic_path *path = diagnostic->richloc->get_path (); | |
672 if (!path) | |
673 return; | |
674 | |
675 if (context->print_path) | |
676 context->print_path (context, path); | |
677 } | |
678 | |
679 /* Return true if the events in this path involve more than one | |
680 function, or false if it is purely intraprocedural. */ | |
681 | |
682 bool | |
683 diagnostic_path::interprocedural_p () const | |
684 { | |
685 const unsigned num = num_events (); | |
686 for (unsigned i = 0; i < num; i++) | |
687 { | |
688 if (get_event (i).get_fndecl () != get_event (0).get_fndecl ()) | |
689 return true; | |
690 if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ()) | |
691 return true; | |
692 } | |
693 return false; | |
694 } | |
695 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
696 void |
0 | 697 default_diagnostic_starter (diagnostic_context *context, |
698 diagnostic_info *diagnostic) | |
699 { | |
111 | 700 diagnostic_report_current_module (context, diagnostic_location (diagnostic)); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
701 pp_set_prefix (context->printer, diagnostic_build_prefix (context, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
702 diagnostic)); |
0 | 703 } |
704 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
705 void |
111 | 706 default_diagnostic_start_span_fn (diagnostic_context *context, |
707 expanded_location exploc) | |
708 { | |
131 | 709 char *text = diagnostic_get_location_text (context, exploc); |
710 pp_string (context->printer, text); | |
711 free (text); | |
111 | 712 pp_newline (context->printer); |
713 } | |
714 | |
715 void | |
0 | 716 default_diagnostic_finalizer (diagnostic_context *context, |
145 | 717 diagnostic_info *diagnostic, |
718 diagnostic_t) | |
0 | 719 { |
145 | 720 char *saved_prefix = pp_take_prefix (context->printer); |
721 pp_set_prefix (context->printer, NULL); | |
722 pp_newline (context->printer); | |
111 | 723 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind); |
145 | 724 pp_set_prefix (context->printer, saved_prefix); |
111 | 725 pp_flush (context->printer); |
0 | 726 } |
727 | |
728 /* Interface to specify diagnostic kind overrides. Returns the | |
729 previous setting, or DK_UNSPECIFIED if the parameters are out of | |
111 | 730 range. If OPTION_INDEX is zero, the new setting is for all the |
731 diagnostics. */ | |
0 | 732 diagnostic_t |
733 diagnostic_classify_diagnostic (diagnostic_context *context, | |
734 int option_index, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
735 diagnostic_t new_kind, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
736 location_t where) |
0 | 737 { |
738 diagnostic_t old_kind; | |
739 | |
111 | 740 if (option_index < 0 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
741 || option_index >= context->n_opts |
0 | 742 || new_kind >= DK_LAST_DIAGNOSTIC_KIND) |
743 return DK_UNSPECIFIED; | |
744 | |
745 old_kind = context->classify_diagnostic[option_index]; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
746 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
747 /* Handle pragmas separately, since we need to keep track of *where* |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
748 the pragmas were. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
749 if (where != UNKNOWN_LOCATION) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
750 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
751 int i; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
752 |
111 | 753 /* Record the command-line status, so we can reset it back on DK_POP. */ |
754 if (old_kind == DK_UNSPECIFIED) | |
755 { | |
756 old_kind = !context->option_enabled (option_index, | |
145 | 757 context->lang_mask, |
111 | 758 context->option_state) |
759 ? DK_IGNORED : (context->warning_as_error_requested | |
760 ? DK_ERROR : DK_WARNING); | |
761 context->classify_diagnostic[option_index] = old_kind; | |
762 } | |
763 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
764 for (i = context->n_classification_history - 1; i >= 0; i --) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
765 if (context->classification_history[i].option == option_index) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
766 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
767 old_kind = context->classification_history[i].kind; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
768 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
769 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
770 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
771 i = context->n_classification_history; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
772 context->classification_history = |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
773 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
774 * sizeof (diagnostic_classification_change_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
775 context->classification_history[i].location = where; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
776 context->classification_history[i].option = option_index; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
777 context->classification_history[i].kind = new_kind; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
778 context->n_classification_history ++; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
779 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
780 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
781 context->classify_diagnostic[option_index] = new_kind; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
782 |
0 | 783 return old_kind; |
784 } | |
785 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
786 /* Save all diagnostic classifications in a stack. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
787 void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
788 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
789 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
790 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
791 context->push_list[context->n_push ++] = context->n_classification_history; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
792 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
793 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
794 /* Restore the topmost classification set off the stack. If the stack |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
795 is empty, revert to the state based on command line parameters. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
796 void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
797 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
798 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
799 int jump_to; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
800 int i; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
801 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
802 if (context->n_push) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
803 jump_to = context->push_list [-- context->n_push]; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
804 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
805 jump_to = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
806 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
807 i = context->n_classification_history; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
808 context->classification_history = |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
809 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
810 * sizeof (diagnostic_classification_change_t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
811 context->classification_history[i].location = where; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
812 context->classification_history[i].option = jump_to; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
813 context->classification_history[i].kind = DK_POP; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
814 context->n_classification_history ++; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
815 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
816 |
111 | 817 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the |
818 escaping rules for -fdiagnostics-parseable-fixits. */ | |
819 | |
820 static void | |
821 print_escaped_string (pretty_printer *pp, const char *text) | |
822 { | |
823 gcc_assert (pp); | |
824 gcc_assert (text); | |
825 | |
826 pp_character (pp, '"'); | |
827 for (const char *ch = text; *ch; ch++) | |
828 { | |
829 switch (*ch) | |
830 { | |
831 case '\\': | |
832 /* Escape backslash as two backslashes. */ | |
833 pp_string (pp, "\\\\"); | |
834 break; | |
835 case '\t': | |
836 /* Escape tab as "\t". */ | |
837 pp_string (pp, "\\t"); | |
838 break; | |
839 case '\n': | |
840 /* Escape newline as "\n". */ | |
841 pp_string (pp, "\\n"); | |
842 break; | |
843 case '"': | |
844 /* Escape doublequotes as \". */ | |
845 pp_string (pp, "\\\""); | |
846 break; | |
847 default: | |
848 if (ISPRINT (*ch)) | |
849 pp_character (pp, *ch); | |
850 else | |
851 /* Use octal for non-printable chars. */ | |
852 { | |
853 unsigned char c = (*ch & 0xff); | |
854 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007); | |
855 } | |
856 break; | |
857 } | |
858 } | |
859 pp_character (pp, '"'); | |
860 } | |
861 | |
862 /* Implementation of -fdiagnostics-parseable-fixits. Print a | |
863 machine-parseable version of all fixits in RICHLOC to PP. */ | |
864 | |
865 static void | |
866 print_parseable_fixits (pretty_printer *pp, rich_location *richloc) | |
867 { | |
868 gcc_assert (pp); | |
869 gcc_assert (richloc); | |
870 | |
145 | 871 char *saved_prefix = pp_take_prefix (pp); |
872 pp_set_prefix (pp, NULL); | |
873 | |
111 | 874 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++) |
875 { | |
876 const fixit_hint *hint = richloc->get_fixit_hint (i); | |
145 | 877 location_t start_loc = hint->get_start_loc (); |
111 | 878 expanded_location start_exploc = expand_location (start_loc); |
879 pp_string (pp, "fix-it:"); | |
880 print_escaped_string (pp, start_exploc.file); | |
881 /* For compatibility with clang, print as a half-open range. */ | |
145 | 882 location_t next_loc = hint->get_next_loc (); |
111 | 883 expanded_location next_exploc = expand_location (next_loc); |
884 pp_printf (pp, ":{%i:%i-%i:%i}:", | |
885 start_exploc.line, start_exploc.column, | |
886 next_exploc.line, next_exploc.column); | |
887 print_escaped_string (pp, hint->get_string ()); | |
888 pp_newline (pp); | |
889 } | |
145 | 890 |
891 pp_set_prefix (pp, saved_prefix); | |
111 | 892 } |
893 | |
894 /* Update the diag_class of DIAGNOSTIC based on its location | |
895 relative to any | |
896 #pragma GCC diagnostic | |
897 directives recorded within CONTEXT. | |
898 | |
899 Return the new diag_class of DIAGNOSTIC if it was updated, or | |
900 DK_UNSPECIFIED otherwise. */ | |
901 | |
902 static diagnostic_t | |
903 update_effective_level_from_pragmas (diagnostic_context *context, | |
904 diagnostic_info *diagnostic) | |
905 { | |
906 diagnostic_t diag_class = DK_UNSPECIFIED; | |
907 | |
908 if (context->n_classification_history > 0) | |
909 { | |
910 location_t location = diagnostic_location (diagnostic); | |
911 | |
912 /* FIXME: Stupid search. Optimize later. */ | |
913 for (int i = context->n_classification_history - 1; i >= 0; i --) | |
914 { | |
915 if (linemap_location_before_p | |
916 (line_table, | |
917 context->classification_history[i].location, | |
918 location)) | |
919 { | |
920 if (context->classification_history[i].kind == (int) DK_POP) | |
921 { | |
922 i = context->classification_history[i].option; | |
923 continue; | |
924 } | |
925 int option = context->classification_history[i].option; | |
926 /* The option 0 is for all the diagnostics. */ | |
927 if (option == 0 || option == diagnostic->option_index) | |
928 { | |
929 diag_class = context->classification_history[i].kind; | |
930 if (diag_class != DK_UNSPECIFIED) | |
931 diagnostic->kind = diag_class; | |
932 break; | |
933 } | |
934 } | |
935 } | |
936 } | |
937 | |
938 return diag_class; | |
939 } | |
940 | |
145 | 941 /* Generate a URL string describing CWE. The caller is responsible for |
942 freeing the string. */ | |
943 | |
944 static char * | |
945 get_cwe_url (int cwe) | |
946 { | |
947 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe); | |
948 } | |
949 | |
950 /* If DIAGNOSTIC has a CWE identifier, print it. | |
951 | |
952 For example, if the diagnostic metadata associates it with CWE-119, | |
953 " [CWE-119]" will be printed, suitably colorized, and with a URL of a | |
954 description of the security issue. */ | |
955 | |
956 static void | |
957 print_any_cwe (diagnostic_context *context, | |
958 const diagnostic_info *diagnostic) | |
959 { | |
960 if (diagnostic->metadata == NULL) | |
961 return; | |
962 | |
963 int cwe = diagnostic->metadata->get_cwe (); | |
964 if (cwe) | |
965 { | |
966 pretty_printer *pp = context->printer; | |
967 char *saved_prefix = pp_take_prefix (context->printer); | |
968 pp_string (pp, " ["); | |
969 pp_string (pp, colorize_start (pp_show_color (pp), | |
970 diagnostic_kind_color[diagnostic->kind])); | |
971 char *cwe_url = get_cwe_url (cwe); | |
972 pp_begin_url (pp, cwe_url); | |
973 free (cwe_url); | |
974 pp_printf (pp, "CWE-%i", cwe); | |
975 pp_set_prefix (context->printer, saved_prefix); | |
976 pp_end_url (pp); | |
977 pp_string (pp, colorize_stop (pp_show_color (pp))); | |
978 pp_character (pp, ']'); | |
979 } | |
980 } | |
981 | |
111 | 982 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's |
983 printer, e.g. " [-Werror=uninitialized]". | |
984 Subroutine of diagnostic_report_diagnostic. */ | |
985 | |
986 static void | |
987 print_option_information (diagnostic_context *context, | |
988 const diagnostic_info *diagnostic, | |
989 diagnostic_t orig_diag_kind) | |
990 { | |
991 char *option_text; | |
992 | |
993 option_text = context->option_name (context, diagnostic->option_index, | |
994 orig_diag_kind, diagnostic->kind); | |
995 | |
996 if (option_text) | |
997 { | |
145 | 998 char *option_url = NULL; |
999 if (context->get_option_url) | |
1000 option_url = context->get_option_url (context, | |
1001 diagnostic->option_index); | |
111 | 1002 pretty_printer *pp = context->printer; |
1003 pp_string (pp, " ["); | |
1004 pp_string (pp, colorize_start (pp_show_color (pp), | |
1005 diagnostic_kind_color[diagnostic->kind])); | |
145 | 1006 if (option_url) |
1007 pp_begin_url (pp, option_url); | |
111 | 1008 pp_string (pp, option_text); |
145 | 1009 if (option_url) |
1010 { | |
1011 pp_end_url (pp); | |
1012 free (option_url); | |
1013 } | |
111 | 1014 pp_string (pp, colorize_stop (pp_show_color (pp))); |
1015 pp_character (pp, ']'); | |
1016 free (option_text); | |
1017 } | |
1018 } | |
1019 | |
0 | 1020 /* Report a diagnostic message (an error or a warning) as specified by |
1021 DC. This function is *the* subroutine in terms of which front-ends | |
1022 should implement their specific diagnostic handling modules. The | |
1023 front-end independent format specifiers are exactly those described | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1024 in the documentation of output_format. |
0 | 1025 Return true if a diagnostic was printed, false otherwise. */ |
1026 | |
1027 bool | |
1028 diagnostic_report_diagnostic (diagnostic_context *context, | |
1029 diagnostic_info *diagnostic) | |
1030 { | |
111 | 1031 location_t location = diagnostic_location (diagnostic); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1032 diagnostic_t orig_diag_kind = diagnostic->kind; |
0 | 1033 |
1034 /* Give preference to being able to inhibit warnings, before they | |
1035 get reclassified to something else. */ | |
1036 if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1037 && !diagnostic_report_warnings_p (context, location)) |
0 | 1038 return false; |
1039 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1040 if (diagnostic->kind == DK_PEDWARN) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1041 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1042 diagnostic->kind = pedantic_warning_kind (context); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1043 /* We do this to avoid giving the message for -pedantic-errors. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1044 orig_diag_kind = diagnostic->kind; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1045 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1046 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1047 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1048 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1049 |
0 | 1050 if (context->lock > 0) |
1051 { | |
1052 /* If we're reporting an ICE in the middle of some other error, | |
1053 try to flush out the previous error, then let this one | |
1054 through. Don't do this more than once. */ | |
111 | 1055 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) |
1056 && context->lock == 1) | |
1057 pp_newline_and_flush (context->printer); | |
0 | 1058 else |
1059 error_recursion (context); | |
1060 } | |
1061 | |
1062 /* If the user requested that warnings be treated as errors, so be | |
1063 it. Note that we do this before the next block so that | |
1064 individual warnings can be overridden back to warnings with | |
1065 -Wno-error=*. */ | |
1066 if (context->warning_as_error_requested | |
1067 && diagnostic->kind == DK_WARNING) | |
111 | 1068 diagnostic->kind = DK_ERROR; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1069 |
111 | 1070 if (diagnostic->option_index |
1071 && diagnostic->option_index != permissive_error_option (context)) | |
0 | 1072 { |
1073 /* This tests if the user provided the appropriate -Wfoo or | |
1074 -Wno-foo option. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1075 if (! context->option_enabled (diagnostic->option_index, |
145 | 1076 context->lang_mask, |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1077 context->option_state)) |
0 | 1078 return false; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1079 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1080 /* This tests for #pragma diagnostic changes. */ |
111 | 1081 diagnostic_t diag_class |
1082 = update_effective_level_from_pragmas (context, diagnostic); | |
1083 | |
0 | 1084 /* This tests if the user provided the appropriate -Werror=foo |
1085 option. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1086 if (diag_class == DK_UNSPECIFIED |
111 | 1087 && (context->classify_diagnostic[diagnostic->option_index] |
1088 != DK_UNSPECIFIED)) | |
1089 diagnostic->kind | |
1090 = context->classify_diagnostic[diagnostic->option_index]; | |
1091 | |
0 | 1092 /* This allows for future extensions, like temporarily disabling |
1093 warnings for ranges of source code. */ | |
1094 if (diagnostic->kind == DK_IGNORED) | |
1095 return false; | |
1096 } | |
1097 | |
111 | 1098 if (diagnostic->kind != DK_NOTE) |
1099 diagnostic_check_max_errors (context); | |
0 | 1100 |
1101 context->lock++; | |
1102 | |
111 | 1103 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) |
0 | 1104 { |
1105 /* When not checking, ICEs are converted to fatal errors when an | |
1106 error has already occurred. This is counteracted by | |
1107 abort_on_error. */ | |
111 | 1108 if (!CHECKING_P |
1109 && (diagnostic_kind_count (context, DK_ERROR) > 0 | |
1110 || diagnostic_kind_count (context, DK_SORRY) > 0) | |
0 | 1111 && !context->abort_on_error) |
1112 { | |
111 | 1113 expanded_location s |
1114 = expand_location (diagnostic_location (diagnostic)); | |
0 | 1115 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", |
1116 s.file, s.line); | |
1117 exit (ICE_EXIT_CODE); | |
1118 } | |
1119 if (context->internal_error) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1120 (*context->internal_error) (context, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1121 diagnostic->message.format_spec, |
0 | 1122 diagnostic->message.args_ptr); |
1123 } | |
111 | 1124 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING) |
1125 ++diagnostic_kind_count (context, DK_WERROR); | |
1126 else | |
1127 ++diagnostic_kind_count (context, diagnostic->kind); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1128 |
131 | 1129 /* Is this the initial diagnostic within the stack of groups? */ |
1130 if (context->diagnostic_group_emission_count == 0) | |
1131 { | |
1132 if (context->begin_group_cb) | |
1133 context->begin_group_cb (context); | |
1134 } | |
1135 context->diagnostic_group_emission_count++; | |
1136 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1137 diagnostic->message.x_data = &diagnostic->x_data; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1138 diagnostic->x_data = NULL; |
0 | 1139 pp_format (context->printer, &diagnostic->message); |
1140 (*diagnostic_starter (context)) (context, diagnostic); | |
1141 pp_output_formatted_text (context->printer); | |
145 | 1142 if (context->show_cwe) |
1143 print_any_cwe (context, diagnostic); | |
111 | 1144 if (context->show_option_requested) |
1145 print_option_information (context, diagnostic, orig_diag_kind); | |
145 | 1146 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind); |
111 | 1147 if (context->parseable_fixits_p) |
1148 { | |
1149 print_parseable_fixits (context->printer, diagnostic->richloc); | |
1150 pp_flush (context->printer); | |
1151 } | |
1152 diagnostic_action_after_output (context, diagnostic->kind); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1153 diagnostic->x_data = NULL; |
0 | 1154 |
111 | 1155 if (context->edit_context_ptr) |
1156 if (diagnostic->richloc->fixits_can_be_auto_applied_p ()) | |
1157 context->edit_context_ptr->add_fixits (diagnostic->richloc); | |
1158 | |
0 | 1159 context->lock--; |
1160 | |
145 | 1161 diagnostic_show_any_path (context, diagnostic); |
1162 | |
0 | 1163 return true; |
1164 } | |
1165 | |
145 | 1166 /* Get the number of digits in the decimal representation of VALUE. */ |
1167 | |
1168 int | |
1169 num_digits (int value) | |
1170 { | |
1171 /* Perhaps simpler to use log10 for this, but doing it this way avoids | |
1172 using floating point. */ | |
1173 gcc_assert (value >= 0); | |
1174 | |
1175 if (value == 0) | |
1176 return 1; | |
1177 | |
1178 int digits = 0; | |
1179 while (value > 0) | |
1180 { | |
1181 digits++; | |
1182 value /= 10; | |
1183 } | |
1184 return digits; | |
1185 } | |
1186 | |
0 | 1187 /* Given a partial pathname as input, return another pathname that |
1188 shares no directory elements with the pathname of __FILE__. This | |
1189 is used by fancy_abort() to print `Internal compiler error in expr.c' | |
1190 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */ | |
1191 | |
1192 const char * | |
1193 trim_filename (const char *name) | |
1194 { | |
1195 static const char this_file[] = __FILE__; | |
1196 const char *p = name, *q = this_file; | |
1197 | |
1198 /* First skip any "../" in each filename. This allows us to give a proper | |
1199 reference to a file in a subdirectory. */ | |
1200 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2])) | |
1201 p += 3; | |
1202 | |
1203 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2])) | |
1204 q += 3; | |
1205 | |
1206 /* Now skip any parts the two filenames have in common. */ | |
1207 while (*p == *q && *p != 0 && *q != 0) | |
1208 p++, q++; | |
1209 | |
1210 /* Now go backwards until the previous directory separator. */ | |
1211 while (p > name && !IS_DIR_SEPARATOR (p[-1])) | |
1212 p--; | |
1213 | |
1214 return p; | |
1215 } | |
1216 | |
1217 /* Standard error reporting routines in increasing order of severity. | |
1218 All of these take arguments like printf. */ | |
1219 | |
1220 /* Text to be emitted verbatim to the error message stream; this | |
1221 produces no prefix and disables line-wrapping. Use rarely. */ | |
1222 void | |
1223 verbatim (const char *gmsgid, ...) | |
1224 { | |
1225 text_info text; | |
1226 va_list ap; | |
1227 | |
1228 va_start (ap, gmsgid); | |
1229 text.err_no = errno; | |
1230 text.args_ptr = ≈ | |
1231 text.format_spec = _(gmsgid); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1232 text.x_data = NULL; |
0 | 1233 pp_format_verbatim (global_dc->printer, &text); |
111 | 1234 pp_newline_and_flush (global_dc->printer); |
1235 va_end (ap); | |
1236 } | |
1237 | |
1238 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */ | |
1239 void | |
1240 diagnostic_append_note (diagnostic_context *context, | |
1241 location_t location, | |
1242 const char * gmsgid, ...) | |
1243 { | |
1244 diagnostic_info diagnostic; | |
1245 va_list ap; | |
1246 rich_location richloc (line_table, location); | |
1247 | |
1248 va_start (ap, gmsgid); | |
1249 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); | |
1250 if (context->inhibit_notes_p) | |
1251 { | |
1252 va_end (ap); | |
1253 return; | |
1254 } | |
131 | 1255 char *saved_prefix = pp_take_prefix (context->printer); |
111 | 1256 pp_set_prefix (context->printer, |
1257 diagnostic_build_prefix (context, &diagnostic)); | |
1258 pp_format (context->printer, &diagnostic.message); | |
1259 pp_output_formatted_text (context->printer); | |
1260 pp_destroy_prefix (context->printer); | |
1261 pp_set_prefix (context->printer, saved_prefix); | |
145 | 1262 pp_newline (context->printer); |
111 | 1263 diagnostic_show_locus (context, &richloc, DK_NOTE); |
0 | 1264 va_end (ap); |
1265 } | |
1266 | |
131 | 1267 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn, |
1268 permerror, error, error_at, error_at, sorry, fatal_error, internal_error, | |
1269 and internal_error_no_backtrace, as documented and defined below. */ | |
111 | 1270 static bool |
145 | 1271 diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata, |
1272 int opt, const char *gmsgid, | |
111 | 1273 va_list *ap, diagnostic_t kind) |
1274 { | |
1275 diagnostic_info diagnostic; | |
1276 if (kind == DK_PERMERROR) | |
1277 { | |
1278 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, | |
1279 permissive_error_kind (global_dc)); | |
1280 diagnostic.option_index = permissive_error_option (global_dc); | |
1281 } | |
1282 else | |
1283 { | |
1284 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind); | |
1285 if (kind == DK_WARNING || kind == DK_PEDWARN) | |
1286 diagnostic.option_index = opt; | |
1287 } | |
145 | 1288 diagnostic.metadata = metadata; |
111 | 1289 return diagnostic_report_diagnostic (global_dc, &diagnostic); |
1290 } | |
1291 | |
1292 /* Implement inform_n, warning_n, and error_n, as documented and | |
1293 defined below. */ | |
1294 static bool | |
145 | 1295 diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata, |
1296 int opt, unsigned HOST_WIDE_INT n, | |
111 | 1297 const char *singular_gmsgid, |
1298 const char *plural_gmsgid, | |
1299 va_list *ap, diagnostic_t kind) | |
1300 { | |
131 | 1301 diagnostic_info diagnostic; |
1302 unsigned long gtn; | |
1303 | |
1304 if (sizeof n <= sizeof gtn) | |
1305 gtn = n; | |
1306 else | |
1307 /* Use the largest number ngettext can handle, otherwise | |
1308 preserve the six least significant decimal digits for | |
1309 languages where the plural form depends on them. */ | |
1310 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU; | |
1311 | |
1312 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn); | |
1313 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind); | |
1314 if (kind == DK_WARNING) | |
1315 diagnostic.option_index = opt; | |
145 | 1316 diagnostic.metadata = metadata; |
131 | 1317 return diagnostic_report_diagnostic (global_dc, &diagnostic); |
111 | 1318 } |
1319 | |
1320 /* Wrapper around diagnostic_impl taking a variable argument list. */ | |
1321 | |
0 | 1322 bool |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1323 emit_diagnostic (diagnostic_t kind, location_t location, int opt, |
0 | 1324 const char *gmsgid, ...) |
1325 { | |
131 | 1326 auto_diagnostic_group d; |
0 | 1327 va_list ap; |
1328 va_start (ap, gmsgid); | |
111 | 1329 rich_location richloc (line_table, location); |
145 | 1330 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind); |
1331 va_end (ap); | |
1332 return ret; | |
1333 } | |
1334 | |
1335 /* As above, but for rich_location *. */ | |
1336 | |
1337 bool | |
1338 emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt, | |
1339 const char *gmsgid, ...) | |
1340 { | |
1341 auto_diagnostic_group d; | |
1342 va_list ap; | |
1343 va_start (ap, gmsgid); | |
1344 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind); | |
0 | 1345 va_end (ap); |
111 | 1346 return ret; |
1347 } | |
0 | 1348 |
111 | 1349 /* Wrapper around diagnostic_impl taking a va_list parameter. */ |
1350 | |
1351 bool | |
1352 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt, | |
1353 const char *gmsgid, va_list *ap) | |
1354 { | |
1355 rich_location richloc (line_table, location); | |
145 | 1356 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind); |
0 | 1357 } |
1358 | |
1359 /* An informative note at LOCATION. Use this for additional details on an error | |
1360 message. */ | |
1361 void | |
1362 inform (location_t location, const char *gmsgid, ...) | |
1363 { | |
131 | 1364 auto_diagnostic_group d; |
0 | 1365 va_list ap; |
111 | 1366 va_start (ap, gmsgid); |
1367 rich_location richloc (line_table, location); | |
145 | 1368 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE); |
111 | 1369 va_end (ap); |
1370 } | |
0 | 1371 |
131 | 1372 /* Same as "inform" above, but at RICHLOC. */ |
111 | 1373 void |
131 | 1374 inform (rich_location *richloc, const char *gmsgid, ...) |
111 | 1375 { |
131 | 1376 gcc_assert (richloc); |
1377 | |
1378 auto_diagnostic_group d; | |
111 | 1379 va_list ap; |
0 | 1380 va_start (ap, gmsgid); |
145 | 1381 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE); |
0 | 1382 va_end (ap); |
1383 } | |
1384 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1385 /* An informative note at LOCATION. Use this for additional details on an |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1386 error message. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1387 void |
131 | 1388 inform_n (location_t location, unsigned HOST_WIDE_INT n, |
1389 const char *singular_gmsgid, const char *plural_gmsgid, ...) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1390 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1391 va_list ap; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1392 va_start (ap, plural_gmsgid); |
131 | 1393 auto_diagnostic_group d; |
1394 rich_location richloc (line_table, location); | |
145 | 1395 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid, |
111 | 1396 &ap, DK_NOTE); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1397 va_end (ap); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1398 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1399 |
0 | 1400 /* A warning at INPUT_LOCATION. Use this for code which is correct according |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1401 to the relevant language specification but is likely to be buggy anyway. |
0 | 1402 Returns true if the warning was printed, false if it was inhibited. */ |
1403 bool | |
1404 warning (int opt, const char *gmsgid, ...) | |
1405 { | |
131 | 1406 auto_diagnostic_group d; |
0 | 1407 va_list ap; |
1408 va_start (ap, gmsgid); | |
111 | 1409 rich_location richloc (line_table, input_location); |
145 | 1410 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING); |
0 | 1411 va_end (ap); |
111 | 1412 return ret; |
0 | 1413 } |
1414 | |
1415 /* A warning at LOCATION. Use this for code which is correct according to the | |
1416 relevant language specification but is likely to be buggy anyway. | |
1417 Returns true if the warning was printed, false if it was inhibited. */ | |
1418 | |
1419 bool | |
1420 warning_at (location_t location, int opt, const char *gmsgid, ...) | |
1421 { | |
131 | 1422 auto_diagnostic_group d; |
0 | 1423 va_list ap; |
111 | 1424 va_start (ap, gmsgid); |
1425 rich_location richloc (line_table, location); | |
145 | 1426 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING); |
111 | 1427 va_end (ap); |
1428 return ret; | |
1429 } | |
0 | 1430 |
131 | 1431 /* Same as "warning at" above, but using RICHLOC. */ |
111 | 1432 |
1433 bool | |
131 | 1434 warning_at (rich_location *richloc, int opt, const char *gmsgid, ...) |
111 | 1435 { |
131 | 1436 gcc_assert (richloc); |
1437 | |
1438 auto_diagnostic_group d; | |
111 | 1439 va_list ap; |
0 | 1440 va_start (ap, gmsgid); |
145 | 1441 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING); |
1442 va_end (ap); | |
1443 return ret; | |
1444 } | |
1445 | |
1446 /* Same as "warning at" above, but using METADATA. */ | |
1447 | |
1448 bool | |
1449 warning_meta (rich_location *richloc, | |
1450 const diagnostic_metadata &metadata, | |
1451 int opt, const char *gmsgid, ...) | |
1452 { | |
1453 gcc_assert (richloc); | |
1454 | |
1455 auto_diagnostic_group d; | |
1456 va_list ap; | |
1457 va_start (ap, gmsgid); | |
1458 bool ret | |
1459 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap, | |
1460 DK_WARNING); | |
111 | 1461 va_end (ap); |
1462 return ret; | |
1463 } | |
1464 | |
131 | 1465 /* Same as warning_n plural variant below, but using RICHLOC. */ |
111 | 1466 |
1467 bool | |
131 | 1468 warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n, |
1469 const char *singular_gmsgid, const char *plural_gmsgid, ...) | |
111 | 1470 { |
131 | 1471 gcc_assert (richloc); |
1472 | |
1473 auto_diagnostic_group d; | |
111 | 1474 va_list ap; |
1475 va_start (ap, plural_gmsgid); | |
145 | 1476 bool ret = diagnostic_n_impl (richloc, NULL, opt, n, |
131 | 1477 singular_gmsgid, plural_gmsgid, |
1478 &ap, DK_WARNING); | |
0 | 1479 va_end (ap); |
111 | 1480 return ret; |
1481 } | |
1482 | |
1483 /* A warning at LOCATION. Use this for code which is correct according to the | |
1484 relevant language specification but is likely to be buggy anyway. | |
1485 Returns true if the warning was printed, false if it was inhibited. */ | |
1486 | |
1487 bool | |
131 | 1488 warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n, |
1489 const char *singular_gmsgid, const char *plural_gmsgid, ...) | |
111 | 1490 { |
131 | 1491 auto_diagnostic_group d; |
111 | 1492 va_list ap; |
1493 va_start (ap, plural_gmsgid); | |
131 | 1494 rich_location richloc (line_table, location); |
145 | 1495 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n, |
111 | 1496 singular_gmsgid, plural_gmsgid, |
1497 &ap, DK_WARNING); | |
1498 va_end (ap); | |
1499 return ret; | |
0 | 1500 } |
1501 | |
1502 /* A "pedantic" warning at LOCATION: issues a warning unless | |
1503 -pedantic-errors was given on the command line, in which case it | |
1504 issues an error. Use this for diagnostics required by the relevant | |
1505 language standard, if you have chosen not to make them errors. | |
1506 | |
1507 Note that these diagnostics are issued independent of the setting | |
111 | 1508 of the -Wpedantic command-line switch. To get a warning enabled |
0 | 1509 only with that switch, use either "if (pedantic) pedwarn |
111 | 1510 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a |
1511 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)". | |
0 | 1512 |
1513 Returns true if the warning was printed, false if it was inhibited. */ | |
1514 | |
1515 bool | |
1516 pedwarn (location_t location, int opt, const char *gmsgid, ...) | |
1517 { | |
131 | 1518 auto_diagnostic_group d; |
0 | 1519 va_list ap; |
1520 va_start (ap, gmsgid); | |
111 | 1521 rich_location richloc (line_table, location); |
145 | 1522 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN); |
0 | 1523 va_end (ap); |
111 | 1524 return ret; |
1525 } | |
1526 | |
131 | 1527 /* Same as pedwarn above, but using RICHLOC. */ |
111 | 1528 |
1529 bool | |
131 | 1530 pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...) |
111 | 1531 { |
131 | 1532 gcc_assert (richloc); |
1533 | |
1534 auto_diagnostic_group d; | |
111 | 1535 va_list ap; |
1536 va_start (ap, gmsgid); | |
145 | 1537 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN); |
111 | 1538 va_end (ap); |
1539 return ret; | |
0 | 1540 } |
1541 | |
1542 /* A "permissive" error at LOCATION: issues an error unless | |
1543 -fpermissive was given on the command line, in which case it issues | |
1544 a warning. Use this for things that really should be errors but we | |
1545 want to support legacy code. | |
1546 | |
1547 Returns true if the warning was printed, false if it was inhibited. */ | |
1548 | |
1549 bool | |
1550 permerror (location_t location, const char *gmsgid, ...) | |
1551 { | |
131 | 1552 auto_diagnostic_group d; |
0 | 1553 va_list ap; |
1554 va_start (ap, gmsgid); | |
111 | 1555 rich_location richloc (line_table, location); |
145 | 1556 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR); |
0 | 1557 va_end (ap); |
111 | 1558 return ret; |
1559 } | |
1560 | |
131 | 1561 /* Same as "permerror" above, but at RICHLOC. */ |
111 | 1562 |
1563 bool | |
131 | 1564 permerror (rich_location *richloc, const char *gmsgid, ...) |
111 | 1565 { |
131 | 1566 gcc_assert (richloc); |
1567 | |
1568 auto_diagnostic_group d; | |
111 | 1569 va_list ap; |
1570 va_start (ap, gmsgid); | |
145 | 1571 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR); |
111 | 1572 va_end (ap); |
1573 return ret; | |
0 | 1574 } |
1575 | |
1576 /* A hard error: the code is definitely ill-formed, and an object file | |
1577 will not be produced. */ | |
1578 void | |
1579 error (const char *gmsgid, ...) | |
1580 { | |
131 | 1581 auto_diagnostic_group d; |
0 | 1582 va_list ap; |
1583 va_start (ap, gmsgid); | |
111 | 1584 rich_location richloc (line_table, input_location); |
145 | 1585 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR); |
0 | 1586 va_end (ap); |
1587 } | |
1588 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1589 /* A hard error: the code is definitely ill-formed, and an object file |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1590 will not be produced. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1591 void |
131 | 1592 error_n (location_t location, unsigned HOST_WIDE_INT n, |
1593 const char *singular_gmsgid, const char *plural_gmsgid, ...) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1594 { |
131 | 1595 auto_diagnostic_group d; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1596 va_list ap; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1597 va_start (ap, plural_gmsgid); |
131 | 1598 rich_location richloc (line_table, location); |
145 | 1599 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid, |
111 | 1600 &ap, DK_ERROR); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1601 va_end (ap); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1602 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1603 |
111 | 1604 /* Same as above, but use location LOC instead of input_location. */ |
0 | 1605 void |
1606 error_at (location_t loc, const char *gmsgid, ...) | |
1607 { | |
131 | 1608 auto_diagnostic_group d; |
0 | 1609 va_list ap; |
111 | 1610 va_start (ap, gmsgid); |
1611 rich_location richloc (line_table, loc); | |
145 | 1612 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR); |
111 | 1613 va_end (ap); |
1614 } | |
0 | 1615 |
111 | 1616 /* Same as above, but use RICH_LOC. */ |
1617 | |
1618 void | |
131 | 1619 error_at (rich_location *richloc, const char *gmsgid, ...) |
111 | 1620 { |
131 | 1621 gcc_assert (richloc); |
1622 | |
1623 auto_diagnostic_group d; | |
111 | 1624 va_list ap; |
0 | 1625 va_start (ap, gmsgid); |
145 | 1626 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR); |
0 | 1627 va_end (ap); |
1628 } | |
1629 | |
1630 /* "Sorry, not implemented." Use for a language feature which is | |
1631 required by the relevant specification but not implemented by GCC. | |
1632 An object file will not be produced. */ | |
1633 void | |
1634 sorry (const char *gmsgid, ...) | |
1635 { | |
131 | 1636 auto_diagnostic_group d; |
0 | 1637 va_list ap; |
1638 va_start (ap, gmsgid); | |
111 | 1639 rich_location richloc (line_table, input_location); |
145 | 1640 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY); |
0 | 1641 va_end (ap); |
1642 } | |
1643 | |
131 | 1644 /* Same as above, but use location LOC instead of input_location. */ |
1645 void | |
1646 sorry_at (location_t loc, const char *gmsgid, ...) | |
1647 { | |
1648 auto_diagnostic_group d; | |
1649 va_list ap; | |
1650 va_start (ap, gmsgid); | |
1651 rich_location richloc (line_table, loc); | |
145 | 1652 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY); |
131 | 1653 va_end (ap); |
1654 } | |
1655 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1656 /* Return true if an error or a "sorry" has been seen. Various |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1657 processing is disabled after errors. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1658 bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1659 seen_error (void) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1660 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1661 return errorcount || sorrycount; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1662 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1663 |
0 | 1664 /* An error which is severe enough that we make no attempt to |
1665 continue. Do not use this for internal consistency checks; that's | |
1666 internal_error. Use of this function should be rare. */ | |
1667 void | |
111 | 1668 fatal_error (location_t loc, const char *gmsgid, ...) |
0 | 1669 { |
131 | 1670 auto_diagnostic_group d; |
0 | 1671 va_list ap; |
1672 va_start (ap, gmsgid); | |
111 | 1673 rich_location richloc (line_table, loc); |
145 | 1674 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL); |
0 | 1675 va_end (ap); |
1676 | |
1677 gcc_unreachable (); | |
1678 } | |
1679 | |
1680 /* An internal consistency check has failed. We make no attempt to | |
1681 continue. Note that unless there is debugging value to be had from | |
1682 a more specific message, or some other good reason, you should use | |
1683 abort () instead of calling this function directly. */ | |
1684 void | |
1685 internal_error (const char *gmsgid, ...) | |
1686 { | |
131 | 1687 auto_diagnostic_group d; |
0 | 1688 va_list ap; |
111 | 1689 va_start (ap, gmsgid); |
1690 rich_location richloc (line_table, input_location); | |
145 | 1691 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE); |
111 | 1692 va_end (ap); |
1693 | |
1694 gcc_unreachable (); | |
1695 } | |
0 | 1696 |
111 | 1697 /* Like internal_error, but no backtrace will be printed. Used when |
1698 the internal error does not happen at the current location, but happened | |
1699 somewhere else. */ | |
1700 void | |
1701 internal_error_no_backtrace (const char *gmsgid, ...) | |
1702 { | |
131 | 1703 auto_diagnostic_group d; |
111 | 1704 va_list ap; |
0 | 1705 va_start (ap, gmsgid); |
111 | 1706 rich_location richloc (line_table, input_location); |
145 | 1707 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT); |
0 | 1708 va_end (ap); |
1709 | |
1710 gcc_unreachable (); | |
1711 } | |
1712 | |
1713 /* Special case error functions. Most are implemented in terms of the | |
1714 above, or should be. */ | |
1715 | |
1716 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it | |
1717 runs its second argument through gettext. */ | |
1718 void | |
1719 fnotice (FILE *file, const char *cmsgid, ...) | |
1720 { | |
1721 va_list ap; | |
1722 | |
1723 va_start (ap, cmsgid); | |
1724 vfprintf (file, _(cmsgid), ap); | |
1725 va_end (ap); | |
1726 } | |
1727 | |
1728 /* Inform the user that an error occurred while trying to report some | |
1729 other error. This indicates catastrophic internal inconsistencies, | |
1730 so give up now. But do try to flush out the previous error. | |
1731 This mustn't use internal_error, that will cause infinite recursion. */ | |
1732 | |
1733 static void | |
1734 error_recursion (diagnostic_context *context) | |
1735 { | |
1736 if (context->lock < 3) | |
111 | 1737 pp_newline_and_flush (context->printer); |
0 | 1738 |
1739 fnotice (stderr, | |
1740 "Internal compiler error: Error reporting routines re-entered.\n"); | |
1741 | |
1742 /* Call diagnostic_action_after_output to get the "please submit a bug | |
111 | 1743 report" message. */ |
1744 diagnostic_action_after_output (context, DK_ICE); | |
0 | 1745 |
1746 /* Do not use gcc_unreachable here; that goes through internal_error | |
1747 and therefore would cause infinite recursion. */ | |
1748 real_abort (); | |
1749 } | |
1750 | |
1751 /* Report an internal compiler error in a friendly manner. This is | |
1752 the function that gets called upon use of abort() in the source | |
1753 code generally, thanks to a special macro. */ | |
1754 | |
1755 void | |
1756 fancy_abort (const char *file, int line, const char *function) | |
1757 { | |
1758 internal_error ("in %s, at %s:%d", function, trim_filename (file), line); | |
1759 } | |
1760 | |
131 | 1761 /* class auto_diagnostic_group. */ |
1762 | |
1763 /* Constructor: "push" this group into global_dc. */ | |
1764 | |
1765 auto_diagnostic_group::auto_diagnostic_group () | |
1766 { | |
1767 global_dc->diagnostic_group_nesting_depth++; | |
1768 } | |
1769 | |
1770 /* Destructor: "pop" this group from global_dc. */ | |
1771 | |
1772 auto_diagnostic_group::~auto_diagnostic_group () | |
1773 { | |
1774 if (--global_dc->diagnostic_group_nesting_depth == 0) | |
1775 { | |
1776 /* Handle the case where we've popped the final diagnostic group. | |
1777 If any diagnostics were emitted, give the context a chance | |
1778 to do something. */ | |
1779 if (global_dc->diagnostic_group_emission_count > 0) | |
1780 { | |
1781 if (global_dc->end_group_cb) | |
1782 global_dc->end_group_cb (global_dc); | |
1783 } | |
1784 global_dc->diagnostic_group_emission_count = 0; | |
1785 } | |
1786 } | |
1787 | |
145 | 1788 /* Implementation of diagnostic_path::num_events vfunc for |
1789 simple_diagnostic_path: simply get the number of events in the vec. */ | |
1790 | |
1791 unsigned | |
1792 simple_diagnostic_path::num_events () const | |
1793 { | |
1794 return m_events.length (); | |
1795 } | |
1796 | |
1797 /* Implementation of diagnostic_path::get_event vfunc for | |
1798 simple_diagnostic_path: simply return the event in the vec. */ | |
1799 | |
1800 const diagnostic_event & | |
1801 simple_diagnostic_path::get_event (int idx) const | |
1802 { | |
1803 return *m_events[idx]; | |
1804 } | |
1805 | |
1806 /* Add an event to this path at LOC within function FNDECL at | |
1807 stack depth DEPTH. | |
1808 | |
1809 Use m_context's printer to format FMT, as the text of the new | |
1810 event. | |
1811 | |
1812 Return the id of the new event. */ | |
1813 | |
1814 diagnostic_event_id_t | |
1815 simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth, | |
1816 const char *fmt, ...) | |
1817 { | |
1818 pretty_printer *pp = m_event_pp; | |
1819 pp_clear_output_area (pp); | |
1820 | |
1821 text_info ti; | |
1822 rich_location rich_loc (line_table, UNKNOWN_LOCATION); | |
1823 | |
1824 va_list ap; | |
1825 | |
1826 va_start (ap, fmt); | |
1827 | |
1828 ti.format_spec = _(fmt); | |
1829 ti.args_ptr = ≈ | |
1830 ti.err_no = 0; | |
1831 ti.x_data = NULL; | |
1832 ti.m_richloc = &rich_loc; | |
1833 | |
1834 pp_format (pp, &ti); | |
1835 pp_output_formatted_text (pp); | |
1836 | |
1837 va_end (ap); | |
1838 | |
1839 simple_diagnostic_event *new_event | |
1840 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp)); | |
1841 m_events.safe_push (new_event); | |
1842 | |
1843 pp_clear_output_area (pp); | |
1844 | |
1845 return diagnostic_event_id_t (m_events.length () - 1); | |
1846 } | |
1847 | |
1848 /* struct simple_diagnostic_event. */ | |
1849 | |
1850 /* simple_diagnostic_event's ctor. */ | |
1851 | |
1852 simple_diagnostic_event::simple_diagnostic_event (location_t loc, | |
1853 tree fndecl, | |
1854 int depth, | |
1855 const char *desc) | |
1856 : m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc)) | |
1857 { | |
1858 } | |
1859 | |
1860 /* simple_diagnostic_event's dtor. */ | |
1861 | |
1862 simple_diagnostic_event::~simple_diagnostic_event () | |
1863 { | |
1864 free (m_desc); | |
1865 } | |
1866 | |
1867 /* Print PATH by emitting a dummy "note" associated with it. */ | |
1868 | |
1869 DEBUG_FUNCTION | |
1870 void debug (diagnostic_path *path) | |
1871 { | |
1872 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1873 richloc.set_path (path); | |
1874 inform (&richloc, "debug path"); | |
1875 } | |
1876 | |
0 | 1877 /* Really call the system 'abort'. This has to go right at the end of |
1878 this file, so that there are no functions after it that call abort | |
1879 and get the system abort instead of our macro. */ | |
1880 #undef abort | |
1881 static void | |
1882 real_abort (void) | |
1883 { | |
1884 abort (); | |
1885 } | |
111 | 1886 |
1887 #if CHECKING_P | |
1888 | |
1889 namespace selftest { | |
1890 | |
1891 /* Helper function for test_print_escaped_string. */ | |
1892 | |
1893 static void | |
1894 assert_print_escaped_string (const location &loc, const char *expected_output, | |
1895 const char *input) | |
1896 { | |
1897 pretty_printer pp; | |
1898 print_escaped_string (&pp, input); | |
1899 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp)); | |
1900 } | |
1901 | |
1902 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \ | |
1903 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT) | |
1904 | |
1905 /* Tests of print_escaped_string. */ | |
1906 | |
1907 static void | |
1908 test_print_escaped_string () | |
1909 { | |
1910 /* Empty string. */ | |
1911 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", ""); | |
1912 | |
1913 /* Non-empty string. */ | |
1914 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world"); | |
1915 | |
1916 /* Various things that need to be escaped: */ | |
1917 /* Backslash. */ | |
1918 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"", | |
1919 "before\\after"); | |
1920 /* Tab. */ | |
1921 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"", | |
1922 "before\tafter"); | |
1923 /* Newline. */ | |
1924 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"", | |
1925 "before\nafter"); | |
1926 /* Double quote. */ | |
1927 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"", | |
1928 "before\"after"); | |
1929 | |
1930 /* Non-printable characters: BEL: '\a': 0x07 */ | |
1931 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"", | |
1932 "before\aafter"); | |
1933 /* Non-printable characters: vertical tab: '\v': 0x0b */ | |
1934 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"", | |
1935 "before\vafter"); | |
1936 } | |
1937 | |
1938 /* Tests of print_parseable_fixits. */ | |
1939 | |
1940 /* Verify that print_parseable_fixits emits the empty string if there | |
1941 are no fixits. */ | |
1942 | |
1943 static void | |
1944 test_print_parseable_fixits_none () | |
1945 { | |
1946 pretty_printer pp; | |
1947 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1948 | |
1949 print_parseable_fixits (&pp, &richloc); | |
1950 ASSERT_STREQ ("", pp_formatted_text (&pp)); | |
1951 } | |
1952 | |
1953 /* Verify that print_parseable_fixits does the right thing if there | |
1954 is an insertion fixit hint. */ | |
1955 | |
1956 static void | |
1957 test_print_parseable_fixits_insert () | |
1958 { | |
1959 pretty_printer pp; | |
1960 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1961 | |
1962 linemap_add (line_table, LC_ENTER, false, "test.c", 0); | |
1963 linemap_line_start (line_table, 5, 100); | |
1964 linemap_add (line_table, LC_LEAVE, false, NULL, 0); | |
1965 location_t where = linemap_position_for_column (line_table, 10); | |
1966 richloc.add_fixit_insert_before (where, "added content"); | |
1967 | |
1968 print_parseable_fixits (&pp, &richloc); | |
1969 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n", | |
1970 pp_formatted_text (&pp)); | |
1971 } | |
1972 | |
1973 /* Verify that print_parseable_fixits does the right thing if there | |
1974 is an removal fixit hint. */ | |
1975 | |
1976 static void | |
1977 test_print_parseable_fixits_remove () | |
1978 { | |
1979 pretty_printer pp; | |
1980 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
1981 | |
1982 linemap_add (line_table, LC_ENTER, false, "test.c", 0); | |
1983 linemap_line_start (line_table, 5, 100); | |
1984 linemap_add (line_table, LC_LEAVE, false, NULL, 0); | |
1985 source_range where; | |
1986 where.m_start = linemap_position_for_column (line_table, 10); | |
1987 where.m_finish = linemap_position_for_column (line_table, 20); | |
1988 richloc.add_fixit_remove (where); | |
1989 | |
1990 print_parseable_fixits (&pp, &richloc); | |
1991 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n", | |
1992 pp_formatted_text (&pp)); | |
1993 } | |
1994 | |
1995 /* Verify that print_parseable_fixits does the right thing if there | |
1996 is an replacement fixit hint. */ | |
1997 | |
1998 static void | |
1999 test_print_parseable_fixits_replace () | |
2000 { | |
2001 pretty_printer pp; | |
2002 rich_location richloc (line_table, UNKNOWN_LOCATION); | |
2003 | |
2004 linemap_add (line_table, LC_ENTER, false, "test.c", 0); | |
2005 linemap_line_start (line_table, 5, 100); | |
2006 linemap_add (line_table, LC_LEAVE, false, NULL, 0); | |
2007 source_range where; | |
2008 where.m_start = linemap_position_for_column (line_table, 10); | |
2009 where.m_finish = linemap_position_for_column (line_table, 20); | |
2010 richloc.add_fixit_replace (where, "replacement"); | |
2011 | |
2012 print_parseable_fixits (&pp, &richloc); | |
2013 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n", | |
2014 pp_formatted_text (&pp)); | |
2015 } | |
2016 | |
131 | 2017 /* Verify that |
2018 diagnostic_get_location_text (..., SHOW_COLUMN) | |
2019 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with | |
2020 colorization disabled. */ | |
2021 | |
2022 static void | |
2023 assert_location_text (const char *expected_loc_text, | |
2024 const char *filename, int line, int column, | |
2025 bool show_column) | |
2026 { | |
2027 test_diagnostic_context dc; | |
2028 dc.show_column = show_column; | |
2029 | |
2030 expanded_location xloc; | |
2031 xloc.file = filename; | |
2032 xloc.line = line; | |
2033 xloc.column = column; | |
2034 xloc.data = NULL; | |
2035 xloc.sysp = false; | |
2036 | |
2037 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc); | |
2038 ASSERT_STREQ (expected_loc_text, actual_loc_text); | |
2039 free (actual_loc_text); | |
2040 } | |
2041 | |
2042 /* Verify that diagnostic_get_location_text works as expected. */ | |
2043 | |
2044 static void | |
2045 test_diagnostic_get_location_text () | |
2046 { | |
2047 const char *old_progname = progname; | |
2048 progname = "PROGNAME"; | |
2049 assert_location_text ("PROGNAME:", NULL, 0, 0, true); | |
2050 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true); | |
2051 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true); | |
2052 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true); | |
2053 assert_location_text ("foo.c:", "foo.c", 0, 10, true); | |
2054 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false); | |
2055 assert_location_text ("foo.c:", "foo.c", 0, 10, false); | |
2056 | |
2057 maybe_line_and_column (INT_MAX, INT_MAX); | |
2058 maybe_line_and_column (INT_MIN, INT_MIN); | |
2059 | |
2060 progname = old_progname; | |
2061 } | |
2062 | |
145 | 2063 /* Selftest for num_digits. */ |
2064 | |
2065 static void | |
2066 test_num_digits () | |
2067 { | |
2068 ASSERT_EQ (1, num_digits (0)); | |
2069 ASSERT_EQ (1, num_digits (9)); | |
2070 ASSERT_EQ (2, num_digits (10)); | |
2071 ASSERT_EQ (2, num_digits (99)); | |
2072 ASSERT_EQ (3, num_digits (100)); | |
2073 ASSERT_EQ (3, num_digits (999)); | |
2074 ASSERT_EQ (4, num_digits (1000)); | |
2075 ASSERT_EQ (4, num_digits (9999)); | |
2076 ASSERT_EQ (5, num_digits (10000)); | |
2077 ASSERT_EQ (5, num_digits (99999)); | |
2078 ASSERT_EQ (6, num_digits (100000)); | |
2079 ASSERT_EQ (6, num_digits (999999)); | |
2080 ASSERT_EQ (7, num_digits (1000000)); | |
2081 ASSERT_EQ (7, num_digits (9999999)); | |
2082 ASSERT_EQ (8, num_digits (10000000)); | |
2083 ASSERT_EQ (8, num_digits (99999999)); | |
2084 } | |
2085 | |
111 | 2086 /* Run all of the selftests within this file. */ |
2087 | |
2088 void | |
2089 diagnostic_c_tests () | |
2090 { | |
2091 test_print_escaped_string (); | |
2092 test_print_parseable_fixits_none (); | |
2093 test_print_parseable_fixits_insert (); | |
2094 test_print_parseable_fixits_remove (); | |
2095 test_print_parseable_fixits_replace (); | |
131 | 2096 test_diagnostic_get_location_text (); |
145 | 2097 test_num_digits (); |
2098 | |
111 | 2099 } |
2100 | |
2101 } // namespace selftest | |
2102 | |
2103 #endif /* #if CHECKING_P */ | |
145 | 2104 |
2105 #if __GNUC__ >= 10 | |
2106 # pragma GCC diagnostic pop | |
2107 #endif |