]>
Commit | Line | Data |
---|---|---|
88fa5555 DM |
1 | /* { dg-do compile } */ |
2 | /* { dg-options "-O -fdiagnostics-show-caret" } */ | |
3 | ||
4 | /* This is a collection of unittests for ranges within string literals, | |
5 | using diagnostic_plugin_test_string_literals, which handles | |
6 | "__emit_string_literal_range" by generating a warning at the given | |
7 | subset of a string literal. | |
8 | ||
9 | The indices are 0-based. It's easiest to verify things using string | |
10 | literals that are runs of 0-based digits (to avoid having to count | |
11 | characters). | |
12 | ||
13 | LITERAL is a const void * to allow testing the various kinds of wide | |
14 | string literal, rather than just const char *. */ | |
15 | ||
65e736c0 | 16 | extern void __emit_string_literal_range (const void *literal, int caret_idx, |
88fa5555 DM |
17 | int start_idx, int end_idx); |
18 | ||
19 | void | |
20 | test_simple_string_literal (void) | |
21 | { | |
22 | __emit_string_literal_range ("0123456789", /* { dg-warning "range" } */ | |
65e736c0 | 23 | 6, 6, 7); |
88fa5555 DM |
24 | /* { dg-begin-multiline-output "" } |
25 | __emit_string_literal_range ("0123456789", | |
26 | ^~ | |
27 | { dg-end-multiline-output "" } */ | |
28 | } | |
29 | ||
30 | void | |
31 | test_concatenated_string_literal (void) | |
32 | { | |
33 | __emit_string_literal_range ("01234" "56789", /* { dg-warning "range" } */ | |
65e736c0 | 34 | 4, 3, 6); |
88fa5555 DM |
35 | /* { dg-begin-multiline-output "" } |
36 | __emit_string_literal_range ("01234" "56789", | |
65e736c0 | 37 | ~^~~~~~ |
88fa5555 DM |
38 | { dg-end-multiline-output "" } */ |
39 | } | |
40 | ||
41 | void | |
42 | test_multiline_string_literal (void) | |
43 | { | |
44 | __emit_string_literal_range ("01234" /* { dg-warning "range" } */ | |
45 | "56789", | |
65e736c0 | 46 | 4, 3, 6); |
88fa5555 DM |
47 | /* { dg-begin-multiline-output "" } |
48 | __emit_string_literal_range ("01234" | |
65e736c0 | 49 | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
88fa5555 | 50 | "56789", |
65e736c0 | 51 | ~~~ |
88fa5555 | 52 | { dg-end-multiline-output "" } */ |
65e736c0 | 53 | /* FIXME: why does the above need three trailing spaces? */ |
88fa5555 DM |
54 | } |
55 | ||
56 | /* Tests of various unicode encodings. | |
57 | ||
58 | Digits 0 through 9 are unicode code points: | |
59 | U+0030 DIGIT ZERO | |
60 | ... | |
61 | U+0039 DIGIT NINE | |
62 | However, these are not always valid as UCN (see the comment in | |
63 | libcpp/charset.c:_cpp_valid_ucn). | |
64 | ||
65 | Hence we need to test UCN using an alternative unicode | |
66 | representation of numbers; let's use Roman numerals, | |
67 | (though these start at one, not zero): | |
68 | U+2170 SMALL ROMAN NUMERAL ONE | |
69 | ... | |
70 | U+2174 SMALL ROMAN NUMERAL FIVE ("v") | |
71 | U+2175 SMALL ROMAN NUMERAL SIX ("vi") | |
72 | ... | |
73 | U+2178 SMALL ROMAN NUMERAL NINE. */ | |
74 | ||
75 | void | |
76 | test_hex (void) | |
77 | { | |
78 | /* Digits 0-9, expressing digit 5 in ASCII as "\x35" | |
79 | and with a space in place of digit 6, to terminate the escaped | |
80 | hex code. */ | |
81 | __emit_string_literal_range ("01234\x35 789", /* { dg-warning "range" } */ | |
65e736c0 | 82 | 4, 3, 7); |
88fa5555 DM |
83 | /* { dg-begin-multiline-output "" } |
84 | __emit_string_literal_range ("01234\x35 789" | |
65e736c0 | 85 | ~^~~~~~~ |
88fa5555 DM |
86 | { dg-end-multiline-output "" } */ |
87 | } | |
88 | ||
89 | void | |
90 | test_oct (void) | |
91 | { | |
92 | /* Digits 0-9, expressing digit 5 in ASCII as "\065" | |
93 | and with a space in place of digit 6, to terminate the escaped | |
94 | octal code. */ | |
95 | __emit_string_literal_range ("01234\065 789", /* { dg-warning "range" } */ | |
65e736c0 | 96 | 4, 3, 7); |
88fa5555 DM |
97 | /* { dg-begin-multiline-output "" } |
98 | __emit_string_literal_range ("01234\065 789" | |
65e736c0 | 99 | ~^~~~~~~ |
88fa5555 DM |
100 | { dg-end-multiline-output "" } */ |
101 | } | |
102 | ||
103 | void | |
104 | test_multiple (void) | |
105 | { | |
106 | /* Digits 0-9, expressing digit 5 in ASCII as hex "\x35" | |
107 | digit 6 in ASCII as octal "\066", concatenating multiple strings. */ | |
108 | __emit_string_literal_range ("01234" "\x35" "\066" "789", /* { dg-warning "range" } */ | |
65e736c0 | 109 | 5, 3, 8); |
88fa5555 DM |
110 | /* { dg-begin-multiline-output "" } |
111 | __emit_string_literal_range ("01234" "\x35" "\066" "789", | |
65e736c0 | 112 | ~~~~~~^~~~~~~~~~~~~~~~~~ |
88fa5555 DM |
113 | { dg-end-multiline-output "" } */ |
114 | } | |
115 | ||
116 | void | |
117 | test_ucn4 (void) | |
118 | { | |
119 | /* Digits 0-9, expressing digits 5 and 6 as Roman numerals expressed | |
120 | as UCN 4. | |
121 | The resulting string is encoded as UTF-8. Most of the digits are 1 byte | |
122 | each, but digits 5 and 6 are encoded with 3 bytes each. | |
123 | Hence to underline digits 4-7 we need to underling using bytes 4-11 in | |
124 | the UTF-8 encoding. */ | |
125 | __emit_string_literal_range ("01234\u2174\u2175789", /* { dg-warning "range" } */ | |
65e736c0 | 126 | 5, 4, 11); |
88fa5555 DM |
127 | /* { dg-begin-multiline-output "" } |
128 | __emit_string_literal_range ("01234\u2174\u2175789", | |
65e736c0 | 129 | ~^~~~~~~~~~~~~ |
88fa5555 DM |
130 | { dg-end-multiline-output "" } */ |
131 | } | |
132 | ||
133 | void | |
134 | test_ucn8 (void) | |
135 | { | |
136 | /* Digits 0-9, expressing digits 5 and 6 as Roman numerals as UCN 8. | |
137 | The resulting string is the same as as in test_ucn4 above, and hence | |
138 | has the same UTF-8 encoding, and so we again need to underline bytes | |
139 | 4-11 in the UTF-8 encoding in order to underline digits 4-7. */ | |
140 | __emit_string_literal_range ("01234\U00002174\U00002175789", /* { dg-warning "range" } */ | |
65e736c0 | 141 | 5, 4, 11); |
88fa5555 DM |
142 | /* { dg-begin-multiline-output "" } |
143 | __emit_string_literal_range ("01234\U00002174\U00002175789", | |
65e736c0 | 144 | ~^~~~~~~~~~~~~~~~~~~~~ |
88fa5555 DM |
145 | { dg-end-multiline-output "" } */ |
146 | } | |
147 | ||
148 | void | |
149 | test_u8 (void) | |
150 | { | |
151 | /* Digits 0-9. */ | |
152 | __emit_string_literal_range (u8"0123456789", /* { dg-warning "range" } */ | |
65e736c0 | 153 | 6, 4, 7); |
88fa5555 DM |
154 | /* { dg-begin-multiline-output "" } |
155 | __emit_string_literal_range (u8"0123456789", | |
65e736c0 | 156 | ~~^~ |
88fa5555 DM |
157 | { dg-end-multiline-output "" } */ |
158 | } | |
159 | ||
160 | void | |
161 | test_u (void) | |
162 | { | |
163 | /* Digits 0-9. */ | |
65e736c0 DM |
164 | __emit_string_literal_range (u"0123456789", /* { dg-error "unable to read substring location: execution character set != source character set" } */ |
165 | 6, 4, 7); | |
88fa5555 DM |
166 | /* { dg-begin-multiline-output "" } |
167 | __emit_string_literal_range (u"0123456789", | |
168 | ^~~~~~~~~~~~~ | |
169 | { dg-end-multiline-output "" } */ | |
170 | } | |
171 | ||
172 | void | |
173 | test_U (void) | |
174 | { | |
175 | /* Digits 0-9. */ | |
65e736c0 DM |
176 | __emit_string_literal_range (U"0123456789", /* { dg-error "unable to read substring location: execution character set != source character set" } */ |
177 | 6, 4, 7); | |
88fa5555 DM |
178 | /* { dg-begin-multiline-output "" } |
179 | __emit_string_literal_range (U"0123456789", | |
180 | ^~~~~~~~~~~~~ | |
181 | { dg-end-multiline-output "" } */ | |
182 | } | |
183 | ||
184 | void | |
185 | test_L (void) | |
186 | { | |
187 | /* Digits 0-9. */ | |
65e736c0 DM |
188 | __emit_string_literal_range (L"0123456789", /* { dg-error "unable to read substring location: execution character set != source character set" } */ |
189 | 6, 4, 7); | |
88fa5555 DM |
190 | /* { dg-begin-multiline-output "" } |
191 | __emit_string_literal_range (L"0123456789", | |
192 | ^~~~~~~~~~~~~ | |
193 | { dg-end-multiline-output "" } */ | |
194 | } | |
195 | ||
b8f56412 DM |
196 | void |
197 | test_raw_string_one_liner (void) | |
198 | { | |
199 | /* Digits 0-9. */ | |
200 | __emit_string_literal_range (R"foo(0123456789)foo", /* { dg-warning "range" } */ | |
201 | 6, 4, 7); | |
202 | /* { dg-begin-multiline-output "" } | |
203 | __emit_string_literal_range (R"foo(0123456789)foo", | |
204 | ~~^~ | |
205 | { dg-end-multiline-output "" } */ | |
206 | } | |
207 | ||
208 | void | |
209 | test_raw_string_multiline (void) | |
210 | { | |
211 | __emit_string_literal_range (R"foo( | |
212 | hello | |
213 | world | |
214 | )foo", | |
215 | 6, 4, 7); | |
216 | /* { dg-error "unable to read substring location: range endpoints are on different lines" "" { target *-*-* } .-5 } */ | |
217 | /* { dg-begin-multiline-output "" } | |
218 | __emit_string_literal_range (R"foo( | |
219 | ^~~~~~ | |
220 | hello | |
221 | ~~~~~ | |
222 | world | |
223 | ~~~~~ | |
224 | )foo", | |
225 | ~~~~~ | |
226 | { dg-end-multiline-output "" } */ | |
227 | } | |
228 | ||
88fa5555 DM |
229 | void |
230 | test_macro (void) | |
231 | { | |
232 | #define START "01234" /* { dg-warning "range" } */ | |
233 | __emit_string_literal_range (START | |
234 | "56789", | |
65e736c0 | 235 | 4, 3, 6); |
88fa5555 DM |
236 | /* { dg-begin-multiline-output "" } |
237 | #define START "01234" | |
65e736c0 | 238 | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
88fa5555 DM |
239 | __emit_string_literal_range (START |
240 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
241 | "56789", | |
242 | ~~~ | |
243 | { dg-end-multiline-output "" } */ | |
244 | } | |
bbd6fcf3 | 245 | |
67b5d0b2 DM |
246 | void |
247 | test_multitoken_macro (void) | |
248 | { | |
249 | #define RANGE ("0123456789") /* { dg-error "unable to read substring location: macro expansion" } */ | |
250 | __emit_string_literal_range (RANGE, 4, 3, 6); | |
251 | /* { dg-begin-multiline-output "" } | |
252 | #define RANGE ("0123456789") | |
7f204c0f | 253 | ^~~~~~~~~~~~~~ |
0d48e877 DM |
254 | { dg-end-multiline-output "" { target c } } */ |
255 | /* { dg-begin-multiline-output "" } | |
256 | #define RANGE ("0123456789") | |
257 | ~^~~~~~~~~~~~~ | |
258 | { dg-end-multiline-output "" { target c++ } } */ | |
67b5d0b2 DM |
259 | /* { dg-begin-multiline-output "" } |
260 | __emit_string_literal_range (RANGE, 4, 3, 6); | |
261 | ^~~~~ | |
262 | { dg-end-multiline-output "" } */ | |
263 | #undef RANGE | |
264 | } | |
265 | ||
bbd6fcf3 DM |
266 | /* Verify that the location of the closing quote is used |
267 | for the location of the null terminating character. */ | |
268 | ||
269 | void | |
270 | test_terminator_location (void) | |
271 | { | |
272 | __emit_string_literal_range ("0123456789", /* { dg-warning "range" } */ | |
273 | 10, 10, 10); | |
274 | /* { dg-begin-multiline-output "" } | |
275 | __emit_string_literal_range ("0123456789", | |
276 | ^ | |
277 | { dg-end-multiline-output "" } */ | |
278 | } | |
470a60b2 DM |
279 | |
280 | /* Verify that we fail gracefully when a string literal token is split | |
281 | across multiple physical lines. */ | |
282 | ||
283 | void | |
284 | test_backslash_continued_logical_lines (void) | |
285 | { | |
286 | __emit_string_literal_range ("\ | |
287 | 01234\ | |
288 | 56789", 6, 6, 7); | |
289 | /* { dg-error "unable to read substring location: range endpoints are on different lines" "" { target *-*-* } .-3 } */ | |
290 | /* { dg-begin-multiline-output "" } | |
291 | __emit_string_literal_range ("\ | |
292 | ^~ | |
293 | 01234\ | |
294 | ~~~~~~ | |
295 | 56789", 6, 6, 7); | |
296 | ~~~~~~ | |
297 | { dg-end-multiline-output "" } */ | |
298 | } | |
05d57d65 DM |
299 | |
300 | /* Reproducer for PR 87652; this is whitespace-sensitive. */ | |
301 | ||
302 | #include "pr87562-a.h" | |
303 | ||
304 | ||
305 | ||
306 | ||
307 | #include "pr87562-b.h" | |
308 | ||
309 | void | |
310 | pr87652 (const char *stem, int counter) | |
311 | { | |
312 | char label[100]; | |
313 | ASM_GENERATE_INTERNAL_LABEL (label, stem, counter); | |
314 | ||
315 | /* This warning is actually in "pr87562-a.h". */ | |
316 | /* { dg-warning "39: range" "" { target *-*-* } 5 } */ | |
317 | /* { dg-begin-multiline-output "" } | |
318 | __emit_string_literal_range ("*.%s%u", 2, 2, 3); \ | |
319 | ^~ | |
320 | { dg-end-multiline-output "" } */ | |
321 | } | |
3d0a5393 DM |
322 | |
323 | /* Reproducer for PR 87721. */ | |
324 | ||
325 | # define OFFSET __builtin_strlen (__FILE__) + __builtin_strlen(":%5d: ") | |
326 | ||
327 | # define DBG_ERROR(format, caret_idx, start_idx, end_idx) \ | |
328 | do { \ | |
329 | __emit_string_literal_range(__FILE__":%5d: " format, \ | |
330 | OFFSET + caret_idx, \ | |
331 | OFFSET + start_idx, \ | |
332 | OFFSET + end_idx); \ | |
333 | } while (0) | |
334 | ||
471c5330 JM |
335 | /* { dg-error "unable to read substring location: unable to read source line" "" { target c } 329 } */ |
336 | /* { dg-error "unable to read substring location: failed to get ordinary maps" "" { target c++ } 329 } */ | |
3d0a5393 DM |
337 | /* { dg-begin-multiline-output "" } |
338 | __emit_string_literal_range(__FILE__":%5d: " format, \ | |
339 | ^~~~~~~~ | |
340 | { dg-end-multiline-output "" { target c } } */ | |
341 | /* { dg-begin-multiline-output "" } | |
342 | __emit_string_literal_range(__FILE__":%5d: " format, \ | |
343 | ^ | |
344 | { dg-end-multiline-output "" { target c++ } } */ | |
345 | ||
346 | void pr87721 (void) { | |
347 | DBG_ERROR("Bad password, expected [%s], got [%s].", 24, 24, 25); /* { dg-message "in expansion of macro 'DBG_ERROR'" } */ | |
348 | /* { dg-begin-multiline-output "" } | |
349 | DBG_ERROR("Bad password, expected [%s], got [%s].", 24, 24, 25); | |
350 | ^~~~~~~~~ | |
351 | { dg-end-multiline-output "" } */ | |
352 | } |