111
|
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
|
|
16 extern void __emit_string_literal_range (const void *literal, int caret_idx,
|
|
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" } */
|
|
23 6, 6, 7);
|
|
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" } */
|
|
34 4, 3, 6);
|
|
35 /* { dg-begin-multiline-output "" }
|
|
36 __emit_string_literal_range ("01234" "56789",
|
|
37 ~^~~~~~
|
|
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",
|
|
46 4, 3, 6);
|
|
47 /* { dg-begin-multiline-output "" }
|
|
48 __emit_string_literal_range ("01234"
|
|
49 ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
50 "56789",
|
|
51 ~~~
|
|
52 { dg-end-multiline-output "" } */
|
|
53 /* FIXME: why does the above need three trailing spaces? */
|
|
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" } */
|
|
82 4, 3, 7);
|
|
83 /* { dg-begin-multiline-output "" }
|
|
84 __emit_string_literal_range ("01234\x35 789"
|
|
85 ~^~~~~~~
|
|
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" } */
|
|
96 4, 3, 7);
|
|
97 /* { dg-begin-multiline-output "" }
|
|
98 __emit_string_literal_range ("01234\065 789"
|
|
99 ~^~~~~~~
|
|
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" } */
|
|
109 5, 3, 8);
|
|
110 /* { dg-begin-multiline-output "" }
|
|
111 __emit_string_literal_range ("01234" "\x35" "\066" "789",
|
|
112 ~~~~~~^~~~~~~~~~~~~~~~~~
|
|
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" } */
|
|
126 5, 4, 11);
|
|
127 /* { dg-begin-multiline-output "" }
|
|
128 __emit_string_literal_range ("01234\u2174\u2175789",
|
|
129 ~^~~~~~~~~~~~~
|
|
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" } */
|
|
141 5, 4, 11);
|
|
142 /* { dg-begin-multiline-output "" }
|
|
143 __emit_string_literal_range ("01234\U00002174\U00002175789",
|
|
144 ~^~~~~~~~~~~~~~~~~~~~~
|
|
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" } */
|
|
153 6, 4, 7);
|
|
154 /* { dg-begin-multiline-output "" }
|
|
155 __emit_string_literal_range (u8"0123456789",
|
|
156 ~~^~
|
|
157 { dg-end-multiline-output "" } */
|
|
158 }
|
|
159
|
|
160 void
|
|
161 test_u (void)
|
|
162 {
|
|
163 /* Digits 0-9. */
|
|
164 __emit_string_literal_range (u"0123456789", /* { dg-error "unable to read substring location: execution character set != source character set" } */
|
|
165 6, 4, 7);
|
|
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. */
|
|
176 __emit_string_literal_range (U"0123456789", /* { dg-error "unable to read substring location: execution character set != source character set" } */
|
|
177 6, 4, 7);
|
|
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. */
|
|
188 __emit_string_literal_range (L"0123456789", /* { dg-error "unable to read substring location: execution character set != source character set" } */
|
|
189 6, 4, 7);
|
|
190 /* { dg-begin-multiline-output "" }
|
|
191 __emit_string_literal_range (L"0123456789",
|
|
192 ^~~~~~~~~~~~~
|
|
193 { dg-end-multiline-output "" } */
|
|
194 }
|
|
195
|
|
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
|
|
229 void
|
|
230 test_macro (void)
|
|
231 {
|
|
232 #define START "01234" /* { dg-warning "range" } */
|
|
233 __emit_string_literal_range (START
|
|
234 "56789",
|
|
235 4, 3, 6);
|
|
236 /* { dg-begin-multiline-output "" }
|
|
237 #define START "01234"
|
|
238 ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
239 __emit_string_literal_range (START
|
|
240 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
241 "56789",
|
|
242 ~~~
|
|
243 { dg-end-multiline-output "" } */
|
|
244 }
|
|
245
|
|
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")
|
|
253 ^~~~~~~~~~~~~~
|
131
|
254 { dg-end-multiline-output "" { target c } } */
|
|
255 /* { dg-begin-multiline-output "" }
|
|
256 #define RANGE ("0123456789")
|
|
257 ~^~~~~~~~~~~~~
|
|
258 { dg-end-multiline-output "" { target c++ } } */
|
111
|
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
|
|
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 }
|
|
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 }
|
131
|
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 }
|