Mercurial > hg > CbC > CbC_gcc
comparison gcc/substring-locations.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Source locations within string literals. | 1 /* Source locations within string literals. |
2 Copyright (C) 2016-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2016-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #include "system.h" | 21 #include "system.h" |
22 #include "coretypes.h" | 22 #include "coretypes.h" |
23 #include "intl.h" | |
23 #include "diagnostic.h" | 24 #include "diagnostic.h" |
24 #include "cpplib.h" | 25 #include "cpplib.h" |
25 #include "tree.h" | 26 #include "tree.h" |
26 #include "langhooks.h" | 27 #include "langhooks.h" |
27 #include "substring-locations.h" | 28 #include "substring-locations.h" |
28 | 29 #include "gcc-rich-location.h" |
29 /* Emit a warning governed by option OPT, using GMSGID as the format | 30 |
30 string and AP as its arguments. | 31 /* format_string_diagnostic_t's ctor, giving information for use by |
31 | 32 the emit_warning* member functions, as follows: |
32 Attempt to obtain precise location information within a string | 33 |
34 They attempt to obtain precise location information within a string | |
33 literal from FMT_LOC. | 35 literal from FMT_LOC. |
34 | 36 |
35 Case 1: if substring location is available, and is within the range of | 37 Case 1: if substring location is available, and is within the range of |
36 the format string itself, the primary location of the | 38 the format string itself, the primary location of the |
37 diagnostic is the substring range obtained from FMT_LOC, with the | 39 diagnostic is the substring range obtained from FMT_LOC, with the |
43 printf ("hello %i", msg); | 45 printf ("hello %i", msg); |
44 ~^ | 46 ~^ |
45 | 47 |
46 Case 2: if the substring location is available, but is not within | 48 Case 2: if the substring location is available, but is not within |
47 the range of the format string, the primary location is that of the | 49 the range of the format string, the primary location is that of the |
48 format string, and an note is emitted showing the substring location. | 50 format string, and a note is emitted showing the substring location. |
49 | 51 |
50 For example: | 52 For example: |
51 test.c:90:10: warning: problem with '%i' here [-Wformat=] | 53 test.c:90:10: warning: problem with '%i' here [-Wformat=] |
52 printf("hello " INT_FMT " world", msg); | 54 printf("hello " INT_FMT " world", msg); |
53 ^~~~~~~~~~~~~~~~~~~~~~~~~ | 55 ^~~~~~~~~~~~~~~~~~~~~~~~~ |
84 | 86 |
85 test.c:90:10: warning: '%i' here, but arg 2 is "const char *' [-Wformat=] | 87 test.c:90:10: warning: '%i' here, but arg 2 is "const char *' [-Wformat=] |
86 printf(fmt, msg); | 88 printf(fmt, msg); |
87 ^~~ ~~~ | 89 ^~~ ~~~ |
88 | 90 |
91 If non-NULL, then FMT_LABEL will be used to label the location within the | |
92 string for cases 1 and 2; if non-NULL, then PARAM_LABEL will be used to label | |
93 the parameter. For example with case 1: | |
94 | |
95 test.c:90:16: warning: '%s' here but arg 2 has 'long' type [-Wformat=] | |
96 printf ("foo %s bar", long_i + long_j); | |
97 ~^ ~~~~~~~~~~~~~~~ | |
98 | | |
99 int | |
100 | |
101 and with case 2: | |
102 | |
103 test.c:90:10: warning: problem with '%i' here [-Wformat=] | |
104 printf("hello " INT_FMT " world", msg); | |
105 ^~~~~~~~~~~~~~~~~~~~~~~~~ | |
106 test.c:19: note: format string is defined here | |
107 #define INT_FMT "%i" | |
108 ~^ | |
109 | | |
110 int | |
111 | |
89 If CORRECTED_SUBSTRING is non-NULL, use it for cases 1 and 2 to provide | 112 If CORRECTED_SUBSTRING is non-NULL, use it for cases 1 and 2 to provide |
90 a fix-it hint, suggesting that it should replace the text within the | 113 a fix-it hint, suggesting that it should replace the text within the |
91 substring range. For example: | 114 substring range. For example: |
92 | 115 |
93 test.c:90:10: warning: problem with '%i' here [-Wformat=] | 116 test.c:90:10: warning: problem with '%i' here [-Wformat=] |
94 printf ("hello %i", msg); | 117 printf ("hello %i", msg); |
95 ~^ | 118 ~^ |
96 %s | 119 %s |
97 | 120 |
121 */ | |
122 | |
123 format_string_diagnostic_t:: | |
124 format_string_diagnostic_t (const substring_loc &fmt_loc, | |
125 const range_label *fmt_label, | |
126 location_t param_loc, | |
127 const range_label *param_label, | |
128 const char *corrected_substring) | |
129 : m_fmt_loc (fmt_loc), | |
130 m_fmt_label (fmt_label), | |
131 m_param_loc (param_loc), | |
132 m_param_label (param_label), | |
133 m_corrected_substring (corrected_substring) | |
134 { | |
135 } | |
136 | |
137 /* Emit a warning governed by option OPT, using SINGULAR_GMSGID as the | |
138 format string (or if PLURAL_GMSGID is different from SINGULAR_GMSGID, | |
139 using SINGULAR_GMSGID, PLURAL_GMSGID and N as arguments to ngettext) | |
140 and AP as its arguments. | |
141 | |
98 Return true if a warning was emitted, false otherwise. */ | 142 Return true if a warning was emitted, false otherwise. */ |
99 | 143 |
100 ATTRIBUTE_GCC_DIAG (5,0) | 144 bool |
101 bool | 145 format_string_diagnostic_t::emit_warning_n_va (int opt, |
102 format_warning_va (const substring_loc &fmt_loc, | 146 unsigned HOST_WIDE_INT n, |
103 location_t param_loc, | 147 const char *singular_gmsgid, |
104 const char *corrected_substring, | 148 const char *plural_gmsgid, |
105 int opt, const char *gmsgid, va_list *ap) | 149 va_list *ap) const |
106 { | 150 { |
107 bool substring_within_range = false; | 151 bool substring_within_range = false; |
108 location_t primary_loc; | 152 location_t primary_loc; |
109 location_t fmt_substring_loc = UNKNOWN_LOCATION; | 153 location_t fmt_substring_loc = UNKNOWN_LOCATION; |
110 source_range fmt_loc_range | 154 source_range fmt_loc_range |
111 = get_range_from_loc (line_table, fmt_loc.get_fmt_string_loc ()); | 155 = get_range_from_loc (line_table, m_fmt_loc.get_fmt_string_loc ()); |
112 const char *err = fmt_loc.get_location (&fmt_substring_loc); | 156 const char *err = m_fmt_loc.get_location (&fmt_substring_loc); |
113 source_range fmt_substring_range | 157 source_range fmt_substring_range |
114 = get_range_from_loc (line_table, fmt_substring_loc); | 158 = get_range_from_loc (line_table, fmt_substring_loc); |
115 if (err) | 159 if (err) |
116 /* Case 3: unable to get substring location. */ | 160 /* Case 3: unable to get substring location. */ |
117 primary_loc = fmt_loc.get_fmt_string_loc (); | 161 primary_loc = m_fmt_loc.get_fmt_string_loc (); |
118 else | 162 else |
119 { | 163 { |
120 if (fmt_substring_range.m_start >= fmt_loc_range.m_start | 164 if (fmt_substring_range.m_start >= fmt_loc_range.m_start |
121 && fmt_substring_range.m_start <= fmt_loc_range.m_finish | 165 && fmt_substring_range.m_start <= fmt_loc_range.m_finish |
122 && fmt_substring_range.m_finish >= fmt_loc_range.m_start | 166 && fmt_substring_range.m_finish >= fmt_loc_range.m_start |
128 } | 172 } |
129 else | 173 else |
130 /* Case 2. */ | 174 /* Case 2. */ |
131 { | 175 { |
132 substring_within_range = false; | 176 substring_within_range = false; |
133 primary_loc = fmt_loc.get_fmt_string_loc (); | 177 primary_loc = m_fmt_loc.get_fmt_string_loc (); |
134 } | 178 } |
135 } | 179 } |
136 | 180 |
137 rich_location richloc (line_table, primary_loc); | 181 /* Only use fmt_label in the initial warning for case 1. */ |
138 | 182 const range_label *primary_label = NULL; |
139 if (param_loc != UNKNOWN_LOCATION) | 183 if (substring_within_range) |
140 richloc.add_range (param_loc, false); | 184 primary_label = m_fmt_label; |
141 | 185 |
142 if (!err && corrected_substring && substring_within_range) | 186 auto_diagnostic_group d; |
143 richloc.add_fixit_replace (fmt_substring_range, corrected_substring); | 187 gcc_rich_location richloc (primary_loc, primary_label); |
188 | |
189 if (m_param_loc != UNKNOWN_LOCATION) | |
190 richloc.add_range (m_param_loc, SHOW_RANGE_WITHOUT_CARET, m_param_label); | |
191 | |
192 if (!err && m_corrected_substring && substring_within_range) | |
193 richloc.add_fixit_replace (fmt_substring_range, m_corrected_substring); | |
144 | 194 |
145 diagnostic_info diagnostic; | 195 diagnostic_info diagnostic; |
146 diagnostic_set_info (&diagnostic, gmsgid, ap, &richloc, DK_WARNING); | 196 if (singular_gmsgid != plural_gmsgid) |
197 { | |
198 unsigned long gtn; | |
199 | |
200 if (sizeof n <= sizeof gtn) | |
201 gtn = n; | |
202 else | |
203 /* Use the largest number ngettext can handle, otherwise | |
204 preserve the six least significant decimal digits for | |
205 languages where the plural form depends on them. */ | |
206 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU; | |
207 | |
208 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn); | |
209 diagnostic_set_info_translated (&diagnostic, text, ap, &richloc, | |
210 DK_WARNING); | |
211 } | |
212 else | |
213 diagnostic_set_info (&diagnostic, singular_gmsgid, ap, &richloc, | |
214 DK_WARNING); | |
147 diagnostic.option_index = opt; | 215 diagnostic.option_index = opt; |
148 bool warned = diagnostic_report_diagnostic (global_dc, &diagnostic); | 216 bool warned = diagnostic_report_diagnostic (global_dc, &diagnostic); |
149 | 217 |
150 if (!err && fmt_substring_loc && !substring_within_range) | 218 if (!err && fmt_substring_loc && !substring_within_range) |
151 /* Case 2. */ | 219 /* Case 2. */ |
152 if (warned) | 220 if (warned) |
153 { | 221 { |
154 rich_location substring_richloc (line_table, fmt_substring_loc); | 222 /* Use fmt_label in the note for case 2. */ |
155 if (corrected_substring) | 223 rich_location substring_richloc (line_table, fmt_substring_loc, |
224 m_fmt_label); | |
225 if (m_corrected_substring) | |
156 substring_richloc.add_fixit_replace (fmt_substring_range, | 226 substring_richloc.add_fixit_replace (fmt_substring_range, |
157 corrected_substring); | 227 m_corrected_substring); |
158 inform_at_rich_loc (&substring_richloc, | 228 inform (&substring_richloc, |
159 "format string is defined here"); | 229 "format string is defined here"); |
160 } | 230 } |
161 | 231 |
162 return warned; | 232 return warned; |
163 } | 233 } |
164 | 234 |
165 /* Variadic call to format_warning_va. */ | 235 /* Singular-only version of the above. */ |
166 | 236 |
167 bool | 237 bool |
168 format_warning_at_substring (const substring_loc &fmt_loc, | 238 format_string_diagnostic_t::emit_warning_va (int opt, const char *gmsgid, |
169 location_t param_loc, | 239 va_list *ap) const |
170 const char *corrected_substring, | 240 { |
171 int opt, const char *gmsgid, ...) | 241 return emit_warning_n_va (opt, 0, gmsgid, gmsgid, ap); |
242 } | |
243 | |
244 /* Variadic version of the above (singular only). */ | |
245 | |
246 bool | |
247 format_string_diagnostic_t::emit_warning (int opt, const char *gmsgid, | |
248 ...) const | |
172 { | 249 { |
173 va_list ap; | 250 va_list ap; |
174 va_start (ap, gmsgid); | 251 va_start (ap, gmsgid); |
175 bool warned = format_warning_va (fmt_loc, param_loc, corrected_substring, | 252 bool warned = emit_warning_va (opt, gmsgid, &ap); |
176 opt, gmsgid, &ap); | 253 va_end (ap); |
254 | |
255 return warned; | |
256 } | |
257 | |
258 /* Variadic version of the above (singular vs plural). */ | |
259 | |
260 bool | |
261 format_string_diagnostic_t::emit_warning_n (int opt, unsigned HOST_WIDE_INT n, | |
262 const char *singular_gmsgid, | |
263 const char *plural_gmsgid, | |
264 ...) const | |
265 { | |
266 va_list ap; | |
267 va_start (ap, plural_gmsgid); | |
268 bool warned = emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid, | |
269 &ap); | |
177 va_end (ap); | 270 va_end (ap); |
178 | 271 |
179 return warned; | 272 return warned; |
180 } | 273 } |
181 | 274 |