1 |
689 |
jeremybenn |
/* Test for X/Open format extensions, as found in the
|
2 |
|
|
Single Unix Specification and in Austin Group draft 7.
|
3 |
|
|
*/
|
4 |
|
|
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
5 |
|
|
/* { dg-do compile } */
|
6 |
|
|
/* { dg-options "-std=gnu99 -Wformat" } */
|
7 |
|
|
|
8 |
|
|
#include "format.h"
|
9 |
|
|
|
10 |
|
|
void
|
11 |
|
|
foo (int i, unsigned int u, wint_t lc, wchar_t *ls, int *ip, double d,
|
12 |
|
|
char *s, void *p, int *n, long int l, int i2, float *fp, long int *lp,
|
13 |
|
|
va_list va)
|
14 |
|
|
{
|
15 |
|
|
/* The conversion specifiers C and S, for both printf and scanf,
|
16 |
|
|
are X/Open extensions.
|
17 |
|
|
*/
|
18 |
|
|
printf ("%C", lc);
|
19 |
|
|
printf ("%3C", lc);
|
20 |
|
|
printf ("%.3C", lc); /* { dg-warning "precision" "precision with %C" } */
|
21 |
|
|
printf ("%hC", lc); /* { dg-warning "length" "bad %hC" } */
|
22 |
|
|
printf ("%hhC", lc); /* { dg-warning "length" "bad %hhC" } */
|
23 |
|
|
printf ("%lC", lc); /* { dg-warning "length" "bad %lC" } */
|
24 |
|
|
printf ("%llC", lc); /* { dg-warning "length" "bad %llC" } */
|
25 |
|
|
printf ("%jC", lc); /* { dg-warning "length" "bad %jC" } */
|
26 |
|
|
printf ("%zC", lc); /* { dg-warning "length" "bad %zC" } */
|
27 |
|
|
printf ("%tC", lc); /* { dg-warning "length" "bad %tC" } */
|
28 |
|
|
printf ("%LC", lc); /* { dg-warning "length" "bad %LC" } */
|
29 |
|
|
printf ("%-C", lc);
|
30 |
|
|
printf ("%+C", lc); /* { dg-warning "flag" "bad %+C" } */
|
31 |
|
|
printf ("% C", lc); /* { dg-warning "flag" "bad % C" } */
|
32 |
|
|
printf ("%#C", lc); /* { dg-warning "flag" "bad %#C" } */
|
33 |
|
|
printf ("%0C", lc); /* { dg-warning "flag" "bad %0C" } */
|
34 |
|
|
printf ("%'C", lc); /* { dg-warning "flag" "bad %'C" } */
|
35 |
|
|
printf ("%S", ls);
|
36 |
|
|
printf ("%3S", ls);
|
37 |
|
|
printf ("%.3S", ls);
|
38 |
|
|
printf ("%hS", ls); /* { dg-warning "length" "bad %hS" } */
|
39 |
|
|
printf ("%hhS", ls); /* { dg-warning "length" "bad %hhS" } */
|
40 |
|
|
printf ("%lS", ls); /* { dg-warning "length" "bad %lS" } */
|
41 |
|
|
printf ("%llS", ls); /* { dg-warning "length" "bad %llS" } */
|
42 |
|
|
printf ("%jS", ls); /* { dg-warning "length" "bad %jS" } */
|
43 |
|
|
printf ("%zS", ls); /* { dg-warning "length" "bad %zS" } */
|
44 |
|
|
printf ("%tS", ls); /* { dg-warning "length" "bad %tS" } */
|
45 |
|
|
printf ("%LS", ls); /* { dg-warning "length" "bad %LS" } */
|
46 |
|
|
printf ("%-S", ls);
|
47 |
|
|
printf ("%+S", ls); /* { dg-warning "flag" "bad %+S" } */
|
48 |
|
|
printf ("% S", ls); /* { dg-warning "flag" "bad % S" } */
|
49 |
|
|
printf ("%#S", ls); /* { dg-warning "flag" "bad %#S" } */
|
50 |
|
|
printf ("%0S", ls); /* { dg-warning "flag" "bad %0S" } */
|
51 |
|
|
printf ("%'S", ls); /* { dg-warning "flag" "bad %'S" } */
|
52 |
|
|
scanf ("%C", ls);
|
53 |
|
|
scanf ("%S", ls);
|
54 |
|
|
scanf ("%*C%*S");
|
55 |
|
|
scanf ("%2C%3S", ls, ls);
|
56 |
|
|
scanf ("%hC", ls); /* { dg-warning "length" "bad %hC" } */
|
57 |
|
|
scanf ("%hhC", ls); /* { dg-warning "length" "bad %hhC" } */
|
58 |
|
|
scanf ("%lC", ls); /* { dg-warning "length" "bad %lC" } */
|
59 |
|
|
scanf ("%llC", ls); /* { dg-warning "length" "bad %llC" } */
|
60 |
|
|
scanf ("%jC", ls); /* { dg-warning "length" "bad %jC" } */
|
61 |
|
|
scanf ("%zC", ls); /* { dg-warning "length" "bad %zC" } */
|
62 |
|
|
scanf ("%tC", ls); /* { dg-warning "length" "bad %tC" } */
|
63 |
|
|
scanf ("%LC", ls); /* { dg-warning "length" "bad %LC" } */
|
64 |
|
|
scanf ("%hS", ls); /* { dg-warning "length" "bad %hS" } */
|
65 |
|
|
scanf ("%hhS", ls); /* { dg-warning "length" "bad %hhS" } */
|
66 |
|
|
scanf ("%lS", ls); /* { dg-warning "length" "bad %lS" } */
|
67 |
|
|
scanf ("%llS", ls); /* { dg-warning "length" "bad %llS" } */
|
68 |
|
|
scanf ("%jS", ls); /* { dg-warning "length" "bad %jS" } */
|
69 |
|
|
scanf ("%zS", ls); /* { dg-warning "length" "bad %zS" } */
|
70 |
|
|
scanf ("%tS", ls); /* { dg-warning "length" "bad %tS" } */
|
71 |
|
|
scanf ("%LS", ls); /* { dg-warning "length" "bad %LS" } */
|
72 |
|
|
/* In C99 mode (even with extensions), %aS is a floating point
|
73 |
|
|
format followed by an S.
|
74 |
|
|
*/
|
75 |
|
|
scanf ("%aS", fp);
|
76 |
|
|
/* The printf flag character ' is an X/Open extension. */
|
77 |
|
|
printf ("%'d%'i%'u%'f%'F%'g%'G", i, i, u, d, d, d, d);
|
78 |
|
|
printf ("%'o", u); /* { dg-warning "flag" "bad use of ' flag" } */
|
79 |
|
|
printf ("%'x", u); /* { dg-warning "flag" "bad use of ' flag" } */
|
80 |
|
|
printf ("%'X", u); /* { dg-warning "flag" "bad use of ' flag" } */
|
81 |
|
|
printf ("%'e", d); /* { dg-warning "flag" "bad use of ' flag" } */
|
82 |
|
|
printf ("%'E", d); /* { dg-warning "flag" "bad use of ' flag" } */
|
83 |
|
|
printf ("%'a", d); /* { dg-warning "flag" "bad use of ' flag" } */
|
84 |
|
|
printf ("%'A", d); /* { dg-warning "flag" "bad use of ' flag" } */
|
85 |
|
|
printf ("%'c", i); /* { dg-warning "flag" "bad use of ' flag" } */
|
86 |
|
|
printf ("%'s", s); /* { dg-warning "flag" "bad use of ' flag" } */
|
87 |
|
|
printf ("%'p", p); /* { dg-warning "flag" "bad use of ' flag" } */
|
88 |
|
|
printf ("%'n", n); /* { dg-warning "flag" "bad use of ' flag" } */
|
89 |
|
|
/* The use of operand number $ formats is an X/Open extension. */
|
90 |
|
|
scanf ("%1$d", ip);
|
91 |
|
|
printf ("%1$d", i);
|
92 |
|
|
printf ("%1$d", l); /* { dg-warning "arg 2|argument 2" "mismatched args with $ format" } */
|
93 |
|
|
printf ("%3$*2$.*1$ld", i2, i, l);
|
94 |
|
|
printf ("%4$ld%7$ld%5$d%6$d%3$d%1$d%2$d", i, i, i, l, i, i, l);
|
95 |
|
|
scanf ("%4$ld%7$ld%5$d%6$d%3$d%1$d%2$d", ip, ip, ip, lp, ip, ip, lp);
|
96 |
|
|
printf ("%1$d%d", i, i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
|
97 |
|
|
printf ("%%%1$d%%%2$d", i, i);
|
98 |
|
|
printf ("%d%2$d", i); /* { dg-warning "used after format" "mixing $ and non-$ formats" } */
|
99 |
|
|
printf ("%1$*d", i, i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
|
100 |
|
|
printf ("%*1$d", i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
|
101 |
|
|
scanf ("%1$d%d", ip, ip); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
|
102 |
|
|
scanf ("%*f%%%1$d%%%2$d", ip, ip);
|
103 |
|
|
printf ("%2$d", i); /* { dg-warning "operand" "$ number too large" } */
|
104 |
|
|
printf ("%0$d", i); /* { dg-warning "operand" "$ number too small" } */
|
105 |
|
|
printf ("%3$d%1$d", i, i, i); /* { dg-warning "before used" "unused $ operand" } */
|
106 |
|
|
printf ("%2$d%1$d", i, i, i); /* { dg-warning "unused" "unused $ operand" } */
|
107 |
|
|
vprintf ("%3$d%1$d", va); /* { dg-warning "before used" "unused $ operand" } */
|
108 |
|
|
/* With scanf formats, gaps in the used arguments are allowed only if the
|
109 |
|
|
arguments are all pointers. In such a case, should only give the lesser
|
110 |
|
|
warning about unused arguments rather than the more serious one about
|
111 |
|
|
argument gaps. */
|
112 |
|
|
scanf ("%3$d%1$d", ip, ip, ip); /* { dg-bogus "before used" "unused $ scanf pointer operand" } */
|
113 |
|
|
/* { dg-warning "unused" "unused $ scanf pointer operand" { target *-*-* } 112 } */
|
114 |
|
|
/* If there are non-pointer arguments unused at the end, this is also OK. */
|
115 |
|
|
scanf ("%3$d%1$d", ip, ip, ip, i); /* { dg-bogus "before used" "unused $ scanf pointer operand" } */
|
116 |
|
|
/* { dg-warning "unused" "unused $ scanf pointer operand" { target *-*-* } 115 } */
|
117 |
|
|
scanf ("%3$d%1$d", ip, i, ip); /* { dg-warning "before used" "unused $ scanf non-pointer operand" } */
|
118 |
|
|
/* Can't check the arguments in the vscanf case, so should suppose the
|
119 |
|
|
lesser problem. */
|
120 |
|
|
vscanf ("%3$d%1$d", va); /* { dg-bogus "before used" "unused $ scanf pointer operand" } */
|
121 |
|
|
/* { dg-warning "unused" "unused $ scanf pointer operand" { target *-*-* } 120 } */
|
122 |
|
|
scanf ("%2$*d%1$d", ip, ip); /* { dg-warning "operand" "operand number with suppression" } */
|
123 |
|
|
printf ("%1$d%1$d", i);
|
124 |
|
|
scanf ("%1$d%1$d", ip); /* { dg-warning "more than once" "multiple use of scanf argument" } */
|
125 |
|
|
}
|