1 /* Test for format extensions beyond the C standard and X/Open standard.
2 Test for printf formats.
4 /* Origin: Joseph Myers <jsm28@cam.ac.uk> */
5 /* { dg-do compile } */
6 /* { dg-options "-std=gnu99 -Wformat" } */
8 /* %q formats want a "quad"; GCC considers this to be a long long. */
9 typedef long long int quad_t;
10 typedef unsigned long long int u_quad_t;
12 typedef __WCHAR_TYPE__ wchar_t;
13 typedef __WINT_TYPE__ wint_t;
14 typedef __SIZE_TYPE__ size_t;
16 extern int printf (const char *, ...);
19 foo (quad_t q, u_quad_t uq, quad_t *qn, size_t z, size_t *zn, long long int ll,
20 unsigned long long int ull, int i, unsigned int u, double d,
21 char *s, void *p, wchar_t *ls, wint_t lc, int *n, long int l)
23 /* As an extension, GCC allows the BSD length "q" for integer formats.
24 This is largely obsoleted in C99 by %j, %ll and PRId64.
26 printf ("%qd%qi%qo%qu%qx%qX%qn", q, q, uq, uq, uq, uq, qn);
27 printf ("%qf", d); /* { dg-warning "length" "bad use of %q" } */
28 printf ("%qF", d); /* { dg-warning "length" "bad use of %q" } */
29 printf ("%qe", d); /* { dg-warning "length" "bad use of %q" } */
30 printf ("%qE", d); /* { dg-warning "length" "bad use of %q" } */
31 printf ("%qg", d); /* { dg-warning "length" "bad use of %q" } */
32 printf ("%qG", d); /* { dg-warning "length" "bad use of %q" } */
33 printf ("%qa", d); /* { dg-warning "length" "bad use of %q" } */
34 printf ("%qA", d); /* { dg-warning "length" "bad use of %q" } */
35 printf ("%qc", i); /* { dg-warning "length" "bad use of %q" } */
36 printf ("%qs", s); /* { dg-warning "length" "bad use of %q" } */
37 printf ("%qp", p); /* { dg-warning "length" "bad use of %q" } */
38 printf ("%qC", lc); /* { dg-warning "length" "bad use of %q" } */
39 printf ("%qS", ls); /* { dg-warning "length" "bad use of %q" } */
40 /* With a bad length GCC wants some argument, any argument,
41 to devour with the format conversion, as a synchronisation heuristic.
42 This may get improved later.
44 printf ("%qm", i); /* { dg-warning "length" "bad use of %q" } */
45 /* As an extension, GCC allows the length "Z" as a synonym for "z".
46 This was an extension predating C99 which should now be considered
47 deprecated; use the standard "z" instead.
49 printf ("%Zd%Zi%Zo%Zu%Zx%ZX", z, z, z, z, z, z);
51 printf ("%Zf", d); /* { dg-warning "length" "bad use of %Z" } */
52 printf ("%ZF", d); /* { dg-warning "length" "bad use of %Z" } */
53 printf ("%Ze", d); /* { dg-warning "length" "bad use of %Z" } */
54 printf ("%ZE", d); /* { dg-warning "length" "bad use of %Z" } */
55 printf ("%Zg", d); /* { dg-warning "length" "bad use of %Z" } */
56 printf ("%ZG", d); /* { dg-warning "length" "bad use of %Z" } */
57 printf ("%Za", d); /* { dg-warning "length" "bad use of %Z" } */
58 printf ("%ZA", d); /* { dg-warning "length" "bad use of %Z" } */
59 printf ("%Zc", i); /* { dg-warning "length" "bad use of %Z" } */
60 printf ("%Zs", s); /* { dg-warning "length" "bad use of %Z" } */
61 printf ("%Zp", p); /* { dg-warning "length" "bad use of %Z" } */
62 printf ("%ZC", lc); /* { dg-warning "length" "bad use of %Z" } */
63 printf ("%ZS", ls); /* { dg-warning "length" "bad use of %Z" } */
64 printf ("%Zm", i); /* { dg-warning "length" "bad use of %Z" } */
65 /* As an extension, GCC allows the length "L" on integer formats
66 (but not %n) as a synonym for "ll".
67 This should be considered deprecated.
69 printf ("%Ld%Li%Lo%Lu%Lx%LX", ll, ll, ull, ull, ull, ull);
70 /* As an extension, derived from syslog, GCC allows the conversion
71 specifier "m" for formatting strerror(errno). This may be used
72 with width, precision and the "-" flag, the same as %s.
74 printf ("%m%3m%.4m%5.6m");
77 printf ("%*.*m", i, i);
81 printf ("%+m"); /* { dg-warning "flag" "bad %+m" } */
82 printf ("% m"); /* { dg-warning "flag" "bad % m" } */
83 printf ("%#m"); /* { dg-warning "flag" "bad %#m" } */
84 printf ("%0m"); /* { dg-warning "flag" "bad %0m" } */
85 printf ("%'m"); /* { dg-warning "flag" "bad %'m" } */
86 printf ("%hm", i); /* { dg-warning "length" "bad %hm" } */
87 printf ("%hhm", i); /* { dg-warning "length" "bad %hhm" } */
88 printf ("%lm", i); /* { dg-warning "length" "bad %lm" } */
89 printf ("%llm", i); /* { dg-warning "length" "bad %llm" } */
90 printf ("%jm", i); /* { dg-warning "length" "bad %jm" } */
91 printf ("%zm", i); /* { dg-warning "length" "bad %zm" } */
92 printf ("%tm", i); /* { dg-warning "length" "bad %tm" } */
93 printf ("%Lm", i); /* { dg-warning "length" "bad %Lm" } */
94 printf ("%qm", i); /* { dg-warning "length" "bad %qm" } */
95 printf ("%Zm", i); /* { dg-warning "length" "bad %Zm" } */
96 /* It should be OK to mix %m formats with $ operand number formats. */
97 printf ("%2$ld%m%1$d", i, l);
98 /* Likewise, %m formats with width and precision should not have an
99 operand number for the %m itself.
101 printf ("%*2$.*1$m", i, i);
102 printf ("%1$*2$.*1$m", i, i); /* { dg-warning "no argument" "printf %1\$m" } */
103 /* As an extension, glibc includes the "I" flag for decimal integer
104 formats, to output using the locale's digits (e.g. in Arabic).
105 In GCC, we require this to be in the standard place for flags, though
106 glibc allows it also after width or precision.
108 printf ("%Id%Ii%Iu", i, i, u);
109 printf ("%Io", u); /* { dg-warning "flag" "bad use of I flag" } */
110 printf ("%Ix", u); /* { dg-warning "flag" "bad use of I flag" } */
111 printf ("%IX", u); /* { dg-warning "flag" "bad use of I flag" } */
112 printf ("%In", n); /* { dg-warning "flag" "bad use of I flag" } */
113 printf ("%If", d); /* { dg-warning "flag" "bad use of I flag" } */
114 printf ("%IF", d); /* { dg-warning "flag" "bad use of I flag" } */
115 printf ("%Ie", d); /* { dg-warning "flag" "bad use of I flag" } */
116 printf ("%IE", d); /* { dg-warning "flag" "bad use of I flag" } */
117 printf ("%Ig", d); /* { dg-warning "flag" "bad use of I flag" } */
118 printf ("%IG", d); /* { dg-warning "flag" "bad use of I flag" } */
119 printf ("%Ia", d); /* { dg-warning "flag" "bad use of I flag" } */
120 printf ("%IA", d); /* { dg-warning "flag" "bad use of I flag" } */
121 printf ("%Ic", i); /* { dg-warning "flag" "bad use of I flag" } */
122 printf ("%Is", s); /* { dg-warning "flag" "bad use of I flag" } */
123 printf ("%Ip", p); /* { dg-warning "flag" "bad use of I flag" } */
124 printf ("%IC", lc); /* { dg-warning "flag" "bad use of I flag" } */
125 printf ("%IS", ls); /* { dg-warning "flag" "bad use of I flag" } */
126 printf ("%Im"); /* { dg-warning "flag" "bad use of I flag" } */