]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
Move string concatenation for C into the parser.
[thirdparty/gcc.git] / gcc / testsuite / gcc.dg / plugin / diagnostic-test-string-literals-1.c
CommitLineData
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 16extern void __emit_string_literal_range (const void *literal, int caret_idx,
88fa5555
DM
17 int start_idx, int end_idx);
18
19void
20test_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
30void
31test_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
41void
42test_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
75void
76test_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
89void
90test_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
103void
104test_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
116void
117test_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
133void
134test_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
148void
149test_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
160void
161test_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
172void
173test_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
184void
185test_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
196void
197test_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
208void
209test_raw_string_multiline (void)
210{
211 __emit_string_literal_range (R"foo(
212hello
213world
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
229void
230test_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
246void
247test_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
269void
270test_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
283void
284test_backslash_continued_logical_lines (void)
285{
286 __emit_string_literal_range ("\
28701234\
28856789", 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
309void
310pr87652 (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
346void 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}