Small ChangeLog tweak.
[official-gcc.git] / gcc / testsuite / gcc.dg / format / c90-printf-1.c
blobc8652fc225248e3739ea4a7f88f284d907dbce15
1 /* Test for printf formats. Formats using C90 features, including cases
2 where C90 specifies some aspect of the format to be ignored or where
3 the behavior is undefined.
4 */
5 /* Origin: Joseph Myers <jsm28@cam.ac.uk> */
6 /* { dg-do compile } */
7 /* { dg-options "-std=iso9899:1990 -pedantic -Wformat" } */
9 #include "format.h"
11 void
12 foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
13 int *n, short int *hn, long int l, unsigned long int ul,
14 long int *ln, long double ld, wint_t lc, wchar_t *ls, llong ll,
15 ullong ull, unsigned int *un, const int *cn, signed char *ss,
16 unsigned char *us, const signed char *css, unsigned int u1,
17 unsigned int u2)
19 /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.1 (pages 131-134). */
20 /* Basic sanity checks for the different components of a format. */
21 printf ("%d\n", i);
22 printf ("%+d\n", i);
23 printf ("%3d\n", i);
24 printf ("%-3d\n", i);
25 printf ("%.7d\n", i);
26 printf ("%+9.4d\n", i);
27 printf ("%.3ld\n", l);
28 printf ("%*d\n", i1, i);
29 printf ("%.*d\n", i2, i);
30 printf ("%*.*ld\n", i1, i2, l);
31 printf ("%d %lu\n", i, ul);
32 /* GCC has objected to the next one in the past, but it is a valid way
33 of specifying zero precision.
35 printf ("%.e\n", d); /* { dg-bogus "precision" "bogus precision warning" } */
36 /* Bogus use of width. */
37 printf ("%5n\n", n); /* { dg-warning "14:width" "width with %n" } */
38 /* Erroneous, ignored or pointless constructs with precision. */
39 /* Whether negative values for precision may be included in the format
40 string is not entirely clear; presume not, following Clive Feather's
41 proposed resolution to DR#220 against C99. In any case, such a
42 construct should be warned about.
44 printf ("%.-5d\n", i); /* { dg-warning "14:format|precision" "negative precision warning" } */
45 /* { dg-warning "too many arguments for format" "too many arguments" { target *-*-* } .-1 } */
46 printf ("%.-*d\n", i); /* { dg-warning "14:format" "broken %.-*d format" } */
47 /* { dg-warning "too many arguments for format" "too many arguments" { target *-*-* } .-1 } */
48 printf ("%.3c\n", i); /* { dg-warning "15:precision" "precision with %c" } */
49 printf ("%.3p\n", p); /* { dg-warning "15:precision" "precision with %p" } */
50 printf ("%.3n\n", n); /* { dg-warning "15:precision" "precision with %n" } */
51 /* Valid and invalid %% constructions. Some of the warning messages
52 are non-optimal, but they do detect the errorneous nature of the
53 format string.
55 printf ("%%");
56 printf ("%.3%"); /* { dg-warning "14:type" "missing type" } */
57 /* { dg-warning "15:trailing" "bogus %%" { target *-*-* } .-1 } */
58 printf ("%-%"); /* { dg-warning "13:type" "missing type" } */
59 /* { dg-warning "14:trailing" "bogus %%" { target *-*-* } .-1 } */
60 printf ("%-%\n"); /* { dg-warning "13:format" "bogus %%" } */
61 /* { dg-warning "15:format" "bogus %%" { target *-*-* } .-1 } */
62 printf ("%5%\n"); /* { dg-warning "13:format" "bogus %%" } */
63 /* { dg-warning "15:format" "bogus %%" { target *-*-* } .-1 } */
64 printf ("%h%\n"); /* { dg-warning "13:format" "bogus %%" } */
65 /* { dg-warning "15:format" "bogus %%" { target *-*-* } .-1 } */
66 /* Valid and invalid %h, %l, %L constructions. */
67 printf ("%hd", i);
68 printf ("%hi", i);
69 /* Strictly, these parameters should be int or unsigned int according to
70 what unsigned short promotes to. However, GCC ignores sign
71 differences in format checking here, and this is relied on to get the
72 correct checking without print_char_table needing to know whether
73 int and short are the same size.
75 printf ("%ho%hu%hx%hX", u, u, u, u);
76 printf ("%hn", hn);
77 printf (" %hf", d); /* { dg-warning "15:length" "bad use of %h" } */
78 printf (" %he", d); /* { dg-warning "15:length" "bad use of %h" } */
79 printf (" %hE", d); /* { dg-warning "15:length" "bad use of %h" } */
80 printf (" %hg", d); /* { dg-warning "15:length" "bad use of %h" } */
81 printf (" %hG", d); /* { dg-warning "15:length" "bad use of %h" } */
82 printf (" %hc", i); /* { dg-warning "15:length" "bad use of %h" } */
83 printf (" %hs", s); /* { dg-warning "15:length" "bad use of %h" } */
84 printf (" %hp", p); /* { dg-warning "15:length" "bad use of %h" } */
85 printf (" %h"); /* { dg-warning "14:conversion lacks type" "bare %h" } */
86 printf (" %h."); /* { dg-warning "15:conversion" "bogus %h." } */
87 printf (" %ld%li%lo%lu%lx%lX", l, l, ul, ul, ul, ul);
88 printf (" %ln", ln);
89 printf (" %lf", d); /* { dg-warning "15:length|C" "bad use of %l" } */
90 printf (" %le", d); /* { dg-warning "15:length|C" "bad use of %l" } */
91 printf (" %lE", d); /* { dg-warning "15:length|C" "bad use of %l" } */
92 printf (" %lg", d); /* { dg-warning "15:length|C" "bad use of %l" } */
93 printf (" %lG", d); /* { dg-warning "15:length|C" "bad use of %l" } */
94 printf (" %lp", p); /* { dg-warning "15:length|C" "bad use of %l" } */
95 /* These next two were added in C94, but should be objected to in C90.
96 For the first one, GCC has wanted wchar_t instead of the correct C94
97 and C99 wint_t.
99 printf ("%lc", lc); /* { dg-warning "14:length|C" "C90 bad use of %l" } */
100 printf ("%ls", ls); /* { dg-warning "14:length|C" "C90 bad use of %l" } */
101 /* These uses of %L are legitimate, though GCC has wrongly warned for
102 them in the past.
104 printf ("%Le%LE%Lf%Lg%LG", ld, ld, ld, ld, ld);
105 /* These next six are accepted by GCC as referring to long long,
106 but -pedantic correctly warns.
108 printf ("%Ld", ll); /* { dg-warning "14:does not support" "bad use of %L" } */
109 printf ("%Li", ll); /* { dg-warning "14:does not support" "bad use of %L" } */
110 printf ("%Lo", ull); /* { dg-warning "14:does not support" "bad use of %L" } */
111 printf ("%Lu", ull); /* { dg-warning "14:does not support" "bad use of %L" } */
112 printf ("%Lx", ull); /* { dg-warning "14:does not support" "bad use of %L" } */
113 printf ("%LX", ull); /* { dg-warning "14:does not support" "bad use of %L" } */
114 printf ("%Lc", i); /* { dg-warning "14:length" "bad use of %L" } */
115 printf ("%Ls", s); /* { dg-warning "14:length" "bad use of %L" } */
116 printf ("%Lp", p); /* { dg-warning "14:length" "bad use of %L" } */
117 printf ("%Ln", n); /* { dg-warning "14:length" "bad use of %L" } */
118 /* Valid uses of each bare conversion. */
119 printf ("%d%i%o%u%x%X%f%e%E%g%G%c%s%p%n%%", i, i, u, u, u, u, d, d, d, d, d,
120 i, s, p, n);
121 /* Uses of the - flag (valid on all non-%, non-n conversions). */
122 printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, u, u, u, u,
123 d, d, d, d, d, i, s, p);
124 printf ("%-n", n); /* { dg-warning "14:flag" "bad use of %-n" } */
125 /* Uses of the + flag (valid on signed conversions only). */
126 printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d);
127 printf ("%+o", u); /* { dg-warning "14:flag" "bad use of + flag" } */
128 printf ("%+u", u); /* { dg-warning "14:flag" "bad use of + flag" } */
129 printf ("%+x", u); /* { dg-warning "14:flag" "bad use of + flag" } */
130 printf ("%+X", u); /* { dg-warning "14:flag" "bad use of + flag" } */
131 printf ("%+c", i); /* { dg-warning "14:flag" "bad use of + flag" } */
132 printf ("%+s", s); /* { dg-warning "14:flag" "bad use of + flag" } */
133 printf ("%+p", p); /* { dg-warning "14:flag" "bad use of + flag" } */
134 printf ("%+n", n); /* { dg-warning "14:flag" "bad use of + flag" } */
135 /* Uses of the space flag (valid on signed conversions only, and ignored
136 with +).
138 printf ("% +d", i); /* { dg-warning "11:use of both|ignored" "use of space and + flags" } */
139 printf ("%+ d", i); /* { dg-warning "11:use of both|ignored" "use of space and + flags" } */
140 printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d);
141 printf ("% o", u); /* { dg-warning "14:flag" "bad use of space flag" } */
142 printf ("% u", u); /* { dg-warning "14:flag" "bad use of space flag" } */
143 printf ("% x", u); /* { dg-warning "14:flag" "bad use of space flag" } */
144 printf ("% X", u); /* { dg-warning "14:flag" "bad use of space flag" } */
145 printf ("% c", i); /* { dg-warning "14:flag" "bad use of space flag" } */
146 printf ("% s", s); /* { dg-warning "14:flag" "bad use of space flag" } */
147 printf ("% p", p); /* { dg-warning "14:flag" "bad use of space flag" } */
148 printf ("% n", n); /* { dg-warning "14:flag" "bad use of space flag" } */
149 /* Uses of the # flag. */
150 printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, d, d);
151 printf ("%#d", i); /* { dg-warning "14:flag" "bad use of # flag" } */
152 printf ("%#i", i); /* { dg-warning "14:flag" "bad use of # flag" } */
153 printf ("%#u", u); /* { dg-warning "14:flag" "bad use of # flag" } */
154 printf ("%#c", i); /* { dg-warning "14:flag" "bad use of # flag" } */
155 printf ("%#s", s); /* { dg-warning "14:flag" "bad use of # flag" } */
156 printf ("%#p", p); /* { dg-warning "14:flag" "bad use of # flag" } */
157 printf ("%#n", n); /* { dg-warning "14:flag" "bad use of # flag" } */
158 /* Uses of the 0 flag. */
159 printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, u, u, u, u,
160 d, d, d, d, d);
161 printf ("%0c", i); /* { dg-warning "14:flag" "bad use of 0 flag" } */
162 printf ("%0s", s); /* { dg-warning "14:flag" "bad use of 0 flag" } */
163 printf ("%0p", p); /* { dg-warning "14:flag" "bad use of 0 flag" } */
164 printf ("%0n", n); /* { dg-warning "14:flag" "bad use of 0 flag" } */
165 /* 0 flag ignored with precision for certain types, not others. */
166 printf ("%08.5d", i); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
167 printf ("%08.5i", i); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
168 printf ("%08.5o", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
169 printf ("%08.5u", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
170 printf ("%08.5x", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
171 printf ("%08.5X", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
172 printf ("%08.5f%08.5e%08.5E%08.5g%08.5G", d, d, d, d, d);
173 /* 0 flag ignored with - flag. */
174 printf ("%-08d", i); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
175 printf ("%-08i", i); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
176 printf ("%-08o", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
177 printf ("%-08u", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
178 printf ("%-08x", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
179 printf ("%-08X", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
180 printf ("%-08e", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
181 printf ("%-08E", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
182 printf ("%-08f", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
183 printf ("%-08g", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
184 printf ("%-08G", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
185 /* Various tests of bad argument types. */
186 printf ("%d", l); /* { dg-warning "13:format" "bad argument types" } */
187 printf ("%*.*d", l, i2, i); /* { dg-warning "13:field" "bad * argument types" } */
188 printf ("%*.*d", i1, l, i); /* { dg-warning "15:field" "bad * argument types" } */
189 printf ("%ld", i); /* { dg-warning "14:format" "bad argument types" } */
190 printf ("%s", n); /* { dg-warning "13:format" "bad argument types" } */
191 printf ("%p", i); /* { dg-warning "13:format" "bad argument types" } */
192 printf ("%n", p); /* { dg-warning "13:format" "bad argument types" } */
193 /* With -pedantic, we want some further checks for pointer targets:
194 %p should allow only pointers to void (possibly qualified) and
195 to character types (possibly qualified), but not function pointers
196 or pointers to other types. (Whether, in fact, character types are
197 allowed here is unclear; see thread on comp.std.c, July 2000 for
198 discussion of the requirements of rules on identical representation,
199 and of the application of the as if rule with the new va_arg
200 allowances in C99 to printf.) Likewise, we should warn if
201 pointer targets differ in signedness, except in some circumstances
202 for character pointers. (In C99 we should consider warning for
203 char * or unsigned char * being passed to %hhn, even if strictly
204 legitimate by the standard.)
206 printf ("%p", foo); /* { dg-warning "13:format" "bad argument types" } */
207 printf ("%n", un); /* { dg-warning "13:format" "bad argument types" } */
208 printf ("%p", n); /* { dg-warning "13:format" "bad argument types" } */
209 /* Allow character pointers with %p. */
210 printf ("%p%p%p%p", s, ss, us, css);
211 /* %s allows any character type. */
212 printf ("%s%s%s%s", s, ss, us, css);
213 /* Warning for void * arguments for %s is GCC's historical behavior,
214 and seems useful to keep, even if some standard versions might be
215 read to permit it.
217 printf ("%s", p); /* { dg-warning "13:format" "bad argument types" } */
218 /* The historical behavior is to allow signed / unsigned types
219 interchangeably as arguments. For values representable in both types,
220 such usage may be correct. For now preserve the behavior of GCC
221 in such cases.
223 printf ("%d", u);
224 /* Also allow the same for width and precision arguments. In the past,
225 GCC has been inconsistent and allowed unsigned for width but not
226 precision.
228 printf ("%*.*d", u1, u2, i);
229 /* Wrong number of arguments. */
230 printf ("%d%d", i); /* { dg-warning "15:matching" "wrong number of args" } */
231 printf ("%d", i, i); /* { dg-warning "11:arguments" "wrong number of args" } */
232 /* Miscellaneous bogus constructions. */
233 printf (""); /* { dg-warning "11:zero-length" "warning for empty format" } */
234 printf ("\0"); /* { dg-warning "12:embedded" "warning for embedded NUL" } */
235 printf ("%d\0", i); /* { dg-warning "14:embedded" "warning for embedded NUL" } */
236 printf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */
237 printf (NULL); /* { dg-warning "3:null" "null format string warning" } */
238 printf ("%"); /* { dg-warning "12:trailing" "trailing % warning" } */
239 printf ("%++d", i); /* { dg-warning "14:repeated" "repeated flag warning" } */
240 printf ("%n", cn); /* { dg-warning "3:constant" "%n with const" } */
241 printf ((const char *)L"foo"); /* { dg-warning "25:wide" "wide string" } */
242 printf ("%n", (int *)0); /* { dg-warning "3:null" "%n with NULL" } */
243 printf ("%s", (char *)0); /* { dg-warning "3:null" "%s with NULL" } */
244 /* Test for correct column locations within strings with embedded
245 escape sequences. */
246 printf ("\\\a\n \"\t%5n\n", n); /* { dg-warning "25:width" "width with %n" } */
247 printf ("\\a\\n%5n\n", n); /* { dg-warning "20:width" "width with %n" } */