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