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)
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 /* As an extension, glibc includes the "I" flag for decimal integer
97 formats, to output using the locale's digits (e.g. in Arabic).
98 In GCC, we require this to be in the standard place for flags, though
99 glibc allows it also after width or precision.
101 printf ("%Id%Ii%Iu", i, i, u);
102 printf ("%Io", u); /* { dg-warning "flag" "bad use of I flag" } */
103 printf ("%Ix", u); /* { dg-warning "flag" "bad use of I flag" } */
104 printf ("%IX", u); /* { dg-warning "flag" "bad use of I flag" } */
105 printf ("%In", n); /* { dg-warning "flag" "bad use of I flag" } */
106 printf ("%If", d); /* { dg-warning "flag" "bad use of I flag" } */
107 printf ("%IF", d); /* { dg-warning "flag" "bad use of I flag" } */
108 printf ("%Ie", d); /* { dg-warning "flag" "bad use of I flag" } */
109 printf ("%IE", d); /* { dg-warning "flag" "bad use of I flag" } */
110 printf ("%Ig", d); /* { dg-warning "flag" "bad use of I flag" } */
111 printf ("%IG", d); /* { dg-warning "flag" "bad use of I flag" } */
112 printf ("%Ia", d); /* { dg-warning "flag" "bad use of I flag" } */
113 printf ("%IA", d); /* { dg-warning "flag" "bad use of I flag" } */
114 printf ("%Ic", i); /* { dg-warning "flag" "bad use of I flag" } */
115 printf ("%Is", s); /* { dg-warning "flag" "bad use of I flag" } */
116 printf ("%Ip", p); /* { dg-warning "flag" "bad use of I flag" } */
117 printf ("%IC", lc); /* { dg-warning "flag" "bad use of I flag" } */
118 printf ("%IS", ls); /* { dg-warning "flag" "bad use of I flag" } */
119 printf ("%Im"); /* { dg-warning "flag" "bad use of I flag" } */