1 /* Test warnings for common punctuation, quoting, and spelling issues
2    in GCC diagnostics.
3    { dg-do compile }
4    { dg-options "-Wformat -Wformat-diag" } */
5 
6 /* Magic identifiers must be set before the attribute is used.  */
7 
8 typedef long long __gcc_host_wide_int__;
9 
10 typedef struct location_s
11 {
12   const char *file;
13   int line;
14 } location_t;
15 
16 union tree_node;
17 typedef union tree_node *tree;
18 
19 /* Define gimple as a dummy type.  The typedef must be provided for
20    the C test to find the symbol.  */
21 typedef struct gimple gimple;
22 
23 /* Likewise for cgraph_node.  */
24 typedef struct cgraph_node cgraph_node;
25 
26 #define ATTR(...)    __attribute__ ((__VA_ARGS__))
27 #define FORMAT(kind) ATTR (format (__gcc_## kind ##__, 1, 2))
28 
29 /* Raw formatting function like pp_format.  */
30 void diag_raw (const char*, ...) ATTR (format (__gcc_diag_raw__, 1, 2));
31 void cdiag_raw (const char*, ...) ATTR (format (__gcc_cdiag_raw__, 1, 2));
32 void tdiag_raw (const char*, ...) ATTR (format (gcc_tdiag_raw, 1, 2));
33 void cxxdiag_raw (const char*, ...) ATTR (format (gcc_cxxdiag_raw, 1, 2));
34 
35 /* Basic formatting function_format.  */
36 void diag (const char*, ...) FORMAT (diag);
37 
38 /* Diagnostic formatting function like error or warning declared
39    by the C front end.  */
40 void cdiag (const char*, ...) FORMAT (cdiag);
41 
42 /* Diagnostic formatting function like error or warning declared
43    by the middle-end or back-end.  */
44 void tdiag (const char*, ...) FORMAT (tdiag);
45 
46 /* Diagnostic formatting function like error or warning declared
47    by the C++ front-end.  */
48 void cxxdiag (const char*, ...) FORMAT (cxxdiag);
49 
50 
51 /* Verify that functions declared with __gcc_diag_raw__ attribute
52    are not subject to -Wformat-diag.  */
53 
test_diag_raw(tree t,gimple * gc)54 void test_diag_raw (tree t, gimple *gc)
55 {
56   diag_raw ("a  b");
57   diag_raw ("newline\n");
58   diag_raw ("lone period.");
59   diag_raw ("multiple punctuators: !!!");
60   diag_raw ("unbalanced paren (");
61   diag_raw ("keyword alignas and identifier_with_underscores");
62   diag_raw ("disable __builtin_abs with the -fno-builtin-abs option");
63   diag_raw ("who says I can't have no stinkin' contractions? ");
64 
65   cdiag_raw ("__atomic_sync (%qE) == 7???", t);
66   tdiag_raw ("__builtin_abs (%E) < 0!?!", t);
67   cxxdiag_raw ("template <> int f (%E", t);
68 }
69 
70 /* Verify that functions declared with the C front-end __gcc_cdiag__
71    attribute detect invalid whitespace in format strings.  */
72 
test_cdiag_whitespace(tree t,gimple * gc)73 void test_cdiag_whitespace (tree t, gimple *gc)
74 {
75   (void)&t; (void)&gc;
76 
77   /* Verify that strings of leading spaces don't trigger a warning.  */
78   cdiag (" a");
79   cdiag ("  b");
80   cdiag ("   c");
81   cdiag ("%< %>a");
82   cdiag ("%<  %>a");
83   cdiag ("a b");
84   cdiag ("a  b");           /* { dg-warning "unquoted sequence of 2 consecutive space characters" } */
85   cdiag ("a ");             /* { dg-warning "spurious trailing space" } */
86   cdiag ("a  ");            /* { dg-warning "spurious trailing space" } */
87   cdiag ("a%< %>");
88   cdiag ("a%< %>%< %>");
89   cdiag ("a%< %> ");        /* { dg-warning "spurious trailing space" } */
90   cdiag ("a%< %>  %< %>");  /* { dg-warning "unquoted sequence of 2 consecutive space characters" } */
91 
92   /* It's debatable whether the following two formst strings should
93      be diagnosed.  They aren't only because it's simpler that way.  */
94   cdiag ("a %< %>");
95   cdiag ("a%< %> %< %>");
96 
97   /* Exercise other whitespace characters.  */
98   cdiag ("a\fb");           /* { dg-warning "unquoted whitespace character '\\\\x0c'" } */
99   cdiag ("a\nb");           /* { dg-warning "unquoted whitespace character '\\\\x0a'" } */
100   cdiag ("a\rb");           /* { dg-warning "unquoted whitespace character '\\\\x0d'" } */
101   cdiag ("a\vb");           /* { dg-warning "unquoted whitespace character '\\\\x0b'" } */
102 
103   cdiag ("First sentence.  And a next.");
104   cdiag ("First sentence.  not capitalized sentence"); /* { dg-warning "inconsistent capitalization" } */
105 
106 #pragma GCC diagnostic push
107 #pragma GCC diagnostic ignored "-Wformat-diag"
108 
109   /* Verify that the warning can be suppressed.  */
110   cdiag ("\ta\b    c\vb\n");
111 
112 #pragma GCC diagnostic pop
113 }
114 
115 
test_cdiag_control(tree t,gimple * gc)116 void test_cdiag_control (tree t, gimple *gc)
117 {
118   (void)&t; (void)&gc;
119 
120   cdiag ("\1");             /* { dg-warning "unquoted control character '\\\\x01'" } */
121   cdiag ("a\ab");           /* { dg-warning "unquoted control character '\\\\x07'" } */
122   cdiag ("a\bb");           /* { dg-warning "unquoted control character '\\\\x08'" } */
123 }
124 
125 
test_cdiag_punct(tree t,gimple * gc,int i)126 void test_cdiag_punct (tree t, gimple *gc, int i)
127 {
128   (void)&t; (void)&gc;
129 
130   /* Exercise the period.  */
131   cdiag (".abc");           /* { dg-warning "spurious leading punctuation sequence .\.." } */
132   cdiag ("abc;");           /* { dg-warning "spurious trailing punctuation sequence .;." } */
133   /* Verify that sentences that start with an uppercase letter and end
134      in a period are not diagnosed.  */
135   cdiag ("This is a full sentence.");
136   cdiag ("Capitalized sentence (with a parethetical note).");
137   cdiag ("Not a full sentence;");   /* { dg-warning "spurious trailing punctuation sequence .;." } */
138   cdiag ("Neither is this one,");   /* { dg-warning "spurious trailing punctuation sequence .,." } */
139 
140   /* Exercise the ellipsis.  */
141   cdiag ("this message...");
142   cdiag ("...continues here");
143   cdiag ("but...not here"); /* { dg-warning "unquoted sequence of 3 consecutive punctuation characters" } */
144 
145   /* Verify that parenthesized sentences are accepted, even the whole
146      meesage (done in the C++ front end).  */
147   cdiag ("null argument where non-null required (argument %i)", i);
148   cdiag ("null (argument %i) where non-null required", i);
149   cdiag ("(see what comes next)");
150 
151   /* Verify that only a single trailing colon is accepted.  */
152   cdiag ("candidates are:");
153   cdiag ("candidates are::"); /* { dg-warning "spurious trailing punctuation sequence .::." } */
154 
155   /* Exercise C++.  */
156   cdiag ("C++ is cool");
157   cdiag ("this is c++");
158   cdiag ("you can do this in C++ but not in C");
159 
160   /* Also verify that G++ is accepted.  */
161   cdiag ("G++ rocks");
162   cdiag ("this is accepted by g++");
163   cdiag ("valid in G++ (or g++) but not in gcc");
164 
165   /* Exercise parenthetical note followed by a colon, semicolon,
166      or a comma.  */
167   cdiag ("found a bug (here):");
168   cdiag ("because of another bug (over there); fix it");
169 
170   cdiag ("found foo (123): go look at it");
171   cdiag ("missed bar (abc); will try harder next time");
172 
173   cdiag ("expected this (or that), got something else (or who knows what)");
174 
175   /* Exercise parenthetical note with a question mark.  */
176   cdiag ("hmmm (did you really mean that?)");
177   cdiag ("error (did you mean %<foo()%>?)");
178   /* And a question mark after a parenthetical note.  */
179   cdiag ("did you mean this (or that)?");
180 
181   /* But make sure unbalanced parenthese are diagnosed.  */
182   cdiag ("or this or the other)?");   /* { dg-warning "unbalanced punctuation character '\\\)'" } */
183 
184   cdiag ("## Heading");               /* { dg-warning "spurious leading punctuation sequence .##." } */
185   cdiag ("## %s ##", "1");            /* { dg-warning "spurious (leading|trailing) punctuation sequence .##." } */
186 
187   cdiag ("#1 priority");              /* { dg-warning "spurious leading punctuation sequence .#." } */
188   cdiag ("priority #2");
189 
190   /* Quoting.  */
191   cdiag ("\"quoted\"");
192   cdiag ("\"quoted\" string");
193   cdiag ("this is a \"string in quotes\"");
194   cdiag ("\"missing closing quote");  /* { dg-warning "unterminated quote character '\"'" } */
195 
196   /* PR translation/90121 - punctuation character after a space.  */
197   cdiag ("bad version : 1");          /* { dg-warning "space followed by punctuation character ':'" } */
198   cdiag ("problem ; fix it");         /* { dg-warning "space followed by punctuation character ';'" } */
199   cdiag ("End . not.");               /* { dg-warning "space followed by punctuation character '.'" } */
200   cdiag ("it is bad , very bad");     /* { dg-warning "space followed by punctuation character ','" } */
201   cdiag ("say what ?");               /* { dg-warning "space followed by punctuation character '?'" } */
202 
203   /* But these are okay after a space.  But should they be?  */
204   cdiag ("1 / 2");
205   cdiag ("2 + 3");
206   cdiag ("2 - 3");
207 }
208 
test_cdiag_punct_balance(tree t,gimple * gc)209 void test_cdiag_punct_balance (tree t, gimple *gc)
210 {
211   (void)&t; (void)&gc;
212 
213   /* Less-than and greater than.  */
214   cdiag ("a < b");          /* { dg-warning "unbalanced punctuation character '<' in format" } */
215   cdiag ("must be > 0");    /* { dg-warning "unbalanced punctuation character '>' in format" } */
216 
217   cdiag ("f()");            /* { dg-warning "spurious trailing punctuation sequence .\\\(\\\)." } */
218   cdiag ("g(1)");
219   cdiag ("(");              /* { dg-warning "spurious leading punctuation character|unbalanced" } */
220   cdiag ("()");             /* { dg-warning "spurious leading punctuation sequence" } */
221   cdiag (")");              /* { dg-warning "unbalanced punctuation character '\\\)'" } */
222   cdiag ("f()g");           /* { dg-warning "unquoted sequence of 2 consecutive punctuation characters" } */
223   cdiag ("illegal operand (1)");
224 }
225 
226 
test_cdiag_nongraph(tree t,gimple * gc)227 void test_cdiag_nongraph (tree t, gimple *gc)
228 {
229   (void)&t; (void)&gc;
230 
231   cdiag ("a\376b");         /* { dg-warning "unquoted non-graph character '\\\\xfe'" } */
232   cdiag ("a\377b");         /* { dg-warning "unquoted non-graph character '\\\\xff'" } */
233 }
234 
235 
test_cdiag_attribute(tree t,gimple * gc)236 void test_cdiag_attribute (tree t, gimple *gc)
237 {
238   (void)&t; (void)&gc;
239 
240   cdiag ("attribute foo");
241   cdiag ("this is attribute bar");
242   cdiag ("bad __attribute bar");        /* { dg-warning "unquoted attribute" } */
243   cdiag ("__attribute__ (foobar) bad"); /* { dg-warning "unquoted attribute" } */
244   cdiag ("__attribute__ ((foobar))");   /* { dg-warning "unquoted attribute" } */
245   cdiag ("__attribute__ (xxx))");       /* { dg-warning "unquoted attribute" } */
246   /* { dg-warning "unbalanced punctuation character '\\\)'" "xxx" { target *-*-* } .-1 } */
247   cdiag ("__attribute__ ((yyy)))");     /* { dg-warning "unquoted attribute" } */
248   /* { dg-warning "unbalanced punctuation character '\\\)'" "yyy" { target *-*-* } .-1 } */
249   cdiag ("__attribute__ ((zzz)");       /* { dg-warning "unquoted attribute" } */
250   /* { dg-warning "unbalanced punctuation character '\\\('" "zzz" { target *-*-* } .-1 } */
251 
252 #pragma GCC diagnostic push
253 #pragma GCC diagnostic ignored "-Wformat-diag"
254 
255   /* Verify that the warning can be suppressed.  */
256   cdiag ("__attribute__ (((");
257 
258 #pragma GCC diagnostic pop
259 }
260 
test_cdiag_builtin(tree t,gimple * gc)261 void test_cdiag_builtin (tree t, gimple *gc)
262 {
263   (void)&t; (void)&gc;
264 
265   cdiag ("__builtin_abort");    /* { dg-warning "unquoted name of built-in function '__builtin_abort'" } */
266   cdiag ("in __builtin_trap");  /* { dg-warning "unquoted name of built-in function '__builtin_trap'" } */
267   cdiag ("__builtin_xyz bites");/* { dg-warning "unquoted name of built-in function '__builtin_xyz'" } */
268 
269 #pragma GCC diagnostic push
270 #pragma GCC diagnostic ignored "-Wformat-diag"
271 
272   /* Verify that the warning can be suppressed.  */
273   cdiag ("__builtin____with____lots__of__underscores");
274 
275 #pragma GCC diagnostic pop
276 }
277 
278 
test_cdiag_option(tree t,gimple * gc)279 void test_cdiag_option (tree t, gimple *gc)
280 {
281   (void)&t; (void)&gc;
282 
283   cdiag ("%<-Wall%>");
284   cdiag ("use option %<-Wextra%> to enable additinal warnings");
285 
286   cdiag ("-O2 is fast");        /* { dg-warning "unquoted option name '-O2'" } */
287   cdiag ("but -O3 is faster");  /* { dg-warning "unquoted option name '-O3'" } */
288 
289   cdiag ("get --help");         /* { dg-warning "unquoted option name '--help'" } */
290   cdiag ("enable -m32");        /* { dg-warning "unquoted option name '-m32'" } */
291   cdiag ("value is -12");
292   cdiag ("foo-O2");
293   cdiag ("a-W");
294 }
295 
296 
test_cdiag_keyword(tree t,gimple * gc)297 void test_cdiag_keyword (tree t, gimple *gc)
298 {
299   cdiag ("alignasi");
300   cdiag ("malignofer or alignofus");
301   cdiag ("use alignof");        /* { dg-warning "unquoted keyword 'alignof'" } */
302   cdiag ("or _Alignof");        /* { dg-warning " keyword '_Alignof'" } */
303   cdiag ("_Pragma too");        /* { dg-warning " keyword '_Pragma'" } */
304 
305   cdiag ("a #error directive"); /* { dg-warning "unquoted preprocessing directive '#error'" } */
306   cdiag ("#include file");      /* { dg-warning "unquoted preprocessing directive '#include'" } */
307   cdiag ("but #pragma foobar"); /* { dg-warning "unquoted preprocessing directive '#pragma'" } */
308   cdiag ("pragma foobar is okay");
309   cdiag ("or even # pragma is fine");
310 
311   /* Exercise qualifiers.  */
312   cdiag ("const function");
313   cdiag ("const-qualified variable"); /* { dg-warning "unquoted keyword 'const-qualified'" } */
314   /* { dg-message "use '%<const%>-qualified' instead" "const-qualified" { target *-*-* } .-1 } */
315   cdiag ("a const %qD", t);     /* { dg-warning "unquoted keyword 'const'" } */
316   cdiag ("restrict %qE", t);    /* { dg-warning "unquoted keyword 'restrict'" } */
317   cdiag ("volatile %qT", t);    /* { dg-warning "unquoted keyword 'volatile'" } */
318   cdiag ("const %qD and restrict %qE or volatile %qT", t, t, t);
319   /* { dg-warning "unquoted keyword 'const'" "" { target *-*-* } .-1 } */
320   /* { dg-warning "unquoted keyword 'restrict'" "" { target *-*-* } .-2 } */
321   /* { dg-warning "unquoted keyword 'volatile'" "" { target *-*-* } .-3 } */
322 
323   cdiag ("an offsetof here");   /* { dg-warning "unquoted keyword 'offsetof" } */
324   cdiag ("sizeof x");           /* { dg-warning "unquoted keyword 'sizeof" } */
325   cdiag ("have typeof");        /* { dg-warning "unquoted keyword 'typeof" } */
326 
327   /* Words that are not keywords are so are not expected to be quoted.  */
328   cdiag ("break rules");
329   cdiag ("if we continue by default for a short while else do nothing");
330   cdiag ("register a function for unsigned extern to void const reads");
331   cdiag ("or volatile access");
332 }
333 
334 
test_cdiag_operator(tree t,gimple * gc)335 void test_cdiag_operator (tree t, gimple *gc)
336 {
337   cdiag ("x != 0");             /* { dg-warning "unquoted operator '!='" } */
338   cdiag ("logical &&");         /* { dg-warning "unquoted operator '&&" } */
339   cdiag ("+= operator");        /* { dg-warning "unquoted operator '\\\+=" } */
340   cdiag ("a == b");             /* { dg-warning "unquoted operator '=='" } */
341   cdiag ("++a");                /* { dg-warning "unquoted operator '\\\+\\\+'" } */
342   cdiag ("b--");                /* { dg-warning "unquoted operator '--'" } */
343   cdiag ("1 << 2");             /* { dg-warning "unquoted operator '<<'" } */
344   cdiag (">> here <<");         /* { dg-warning "unquoted operator '>>|<<'" } */
345 }
346 
347 
test_cdiag_type_name(tree t,gimple * gc)348 void test_cdiag_type_name (tree t, gimple *gc)
349 {
350   cdiag ("the word character should not be quoted");
351   cdiag ("but char should be"); /* { dg-warning "unquoted keyword 'char'" } */
352 
353   cdiag ("unsigned char should be quoted");     /* { dg-warning "unquoted type name 'unsigned char'" } */
354   cdiag ("but unsigned character is fine");
355 
356   cdiag ("as should int");      /* { dg-warning "unquoted keyword 'int'" } */
357   cdiag ("and signed int");     /* { dg-warning "unquoted type name 'signed int'" } */
358   cdiag ("and also unsigned int");     /* { dg-warning "unquoted type name 'unsigned int'" } */
359   cdiag ("very long thing");
360   cdiag ("use long long here"); /* { dg-warning "unquoted type name 'long long'" } */
361 
362   cdiag ("have a floating type");
363   cdiag ("found float type");   /* { dg-warning "unquoted keyword 'float'" } */
364 
365   cdiag ("wchar_t is wide");    /* { dg-warning "unquoted identifier or keyword 'wchar_t'" } */
366 }
367 
368 
test_cdiag_identifier(tree t,gimple * gc)369 void test_cdiag_identifier (tree t, gimple *gc)
370 {
371   (void)&t; (void)&gc;
372 
373   cdiag ("private _x ident");   /* { dg-warning "unquoted identifier or keyword '_x'" } */
374   cdiag ("and another __y");    /* { dg-warning "unquoted identifier or keyword '__y'" } */
375   cdiag ("ident z_ with trailing underscore");   /* { dg-warning "unquoted identifier or keyword 'z_'" } */
376   cdiag ("v_ variable");        /* { dg-warning "unquoted identifier or keyword 'v_'" } */
377   cdiag ("call foo_bar");       /* { dg-warning "unquoted identifier or keyword 'foo_bar'" } */
378   cdiag ("unqoted x_y ident");  /* { dg-warning "unquoted identifier or keyword 'x_y'" } */
379 
380   cdiag ("size_t type");        /* { dg-warning "unquoted identifier or keyword 'size_t'" } */
381   cdiag ("bigger than INT_MAX");/* { dg-warning "unquoted identifier or keyword 'INT_MAX'" } */
382 
383   cdiag ("quoted ident %<a_b%>");
384   cdiag ("another quoted identifier %<x_%> here");
385 }
386 
387 
test_cdiag_bad_words(tree t,gimple * gc)388 void test_cdiag_bad_words (tree t, gimple *gc)
389 {
390   (void)&t; (void)&gc;
391 
392   cdiag ("aren't you dumb?");  /* { dg-warning "bare apostrophe ''' in format" } */
393   cdiag ("bitfields suck");    /* { dg-warning "misspelled term 'bitfields' in format; use 'bit-fields' instead" } */
394   cdiag ("invalid bitfield");  /* { dg-warning "misspelled term 'bitfield' in format; use 'bit-field' instead" } */
395   cdiag ("bad builtin function");  /* { dg-warning "misspelled term 'builtin function' in format; use 'built-in function' instead" } */
396   cdiag ("bad builtin function");  /* { dg-warning "misspelled term 'builtin function' in format; use 'built-in function' instead" } */
397   cdiag ("builtin function x");    /* { dg-warning "misspelled term 'builtin function' in format; use 'built-in function' instead" } */
398   cdiag ("builtin functions disabled");    /* { dg-warning "misspelled term 'builtin functions' in format; use 'built-in functions' instead" } */
399   cdiag ("enable builtin functions");      /* { dg-warning "misspelled term 'builtin functions' in format; use 'built-in functions' instead" } */
400   cdiag ("you can't do that"); /* { dg-warning "contraction 'can't' in format" } */
401   cdiag ("you can%'t do that");/* { dg-warning "contraction 'can%'t' in format" } */
402   cdiag ("Can%'t touch this.");/* { dg-warning "contraction 'Can%'t' in format" } */
403   cdiag ("can%'");
404   cdiag ("can%' whatever");
405   cdiag ("on the commandline");/* { dg-warning "misspelled term 'commandline' in format; use 'command line' instead" } */
406   cdiag ("command line option");/* { dg-warning "misspelled term 'command line option' in format; use 'command-line option' instead" } */
407   cdiag ("it mustn't be");     /* { dg-warning "contraction 'mustn't' in format" } */
408   cdiag ("isn't that silly?"); /* { dg-warning "bare apostrophe ''' in format" } */
409 
410   cdiag ("can not do this");   /* { dg-warning "misspelled term 'can not' in format; use 'cannot' instead" } */
411   cdiag ("you can not");       /* { dg-warning "misspelled term 'can not' in format; use 'cannot' instead" } */
412 
413   /* See PR target/90157 - aarch64: unnecessary abbreviation in diagnostic */
414   cdiag ("Mising arg.");       /* { dg-warning "misspelled term 'arg' in format; use 'argument' instead" } */
415   cdiag ("2 args: a and b");   /* { dg-warning "misspelled term 'args' in format; use 'arguments' instead" } */
416   cdiag ("arg 1");             /* { dg-warning "misspelled term 'arg' in format; use 'argument' instead" } */
417   cdiag ("Args are wrong.");   /* { dg-warning "misspelled term 'Args' in format; use 'arguments' instead" } */
418   cdiag ("bad arg");           /* { dg-warning "misspelled term 'arg' in format; use 'argument' instead" } */
419   cdiag ("two args");          /* { dg-warning "misspelled term 'args' in format; use 'arguments' instead" } */
420   cdiag ("args 1 and 2");      /* { dg-warning "misspelled term 'args' in format; use 'arguments' instead" } */
421 
422   cdiag ("Reg A");             /* { dg-warning "misspelled term 'Reg' in format; use 'register' instead" } */
423   cdiag ("regs A and B");      /* { dg-warning "misspelled term 'regs' in format; use 'registers' instead" } */
424   cdiag ("no regs");           /* { dg-warning "misspelled term 'regs' in format; use 'registers' instead" } */
425 
426   /* Verify words that end in "arg" and "args" or "reg" and "regs" are
427      not diagnosed.  */
428   cdiag ("gulmarg and balfarg");
429   cdiag ("ademargs or toshargs");
430   cdiag ("talk to Greg");
431   cdiag ("prepreg is a fabric");
432   cdiag ("there are dregs in my wine");
433 }
434 
435 
test_cdiag_directive(tree t,gimple * gc)436 void test_cdiag_directive (tree t, gimple *gc)
437 {
438   (void)&t; (void)&gc;
439 
440   cxxdiag ("%<%s%>", "");     /* { dg-warning "quoted '%s' directive in format" } */
441   /* This was asked to be diagnosed in PR #90158 but there, the \"%s\"
442      is in parenheses which ends up getting diagnosed because of
443      the two consecutive punctuation characters, ( and ".  */
444   cdiag ("\"%s\"", "");       /* { dg-warning "quoted '%s' directive in format" } */
445 
446   /* Make sure quoted paired tokens are not diagnosed.  */
447   cdiag ("%<'%>");
448   cdiag ("%<\"%>");
449   cdiag ("%<<%>");
450   cdiag ("%<>%>");
451   cdiag ("%<(%>");
452   cdiag ("%<)%>");
453   cdiag ("%<[%>");
454   cdiag ("%<]%>");
455 
456   cdiag ("%<'%> %<\"%> %<>%> %<<%> %<)%> %<(%> %<]%> %<[%>");
457 }
458