2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / testsuite / gcc.dg / format / c90-printf-1.c
blobe4c18f76862d3e8091910bbf1f77140bcd3dcacc
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 "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 "format|precision" "negative precision warning" } */
45 printf ("%.-*d\n", i); /* { dg-warning "format" "broken %.-*d format" } */
46 printf ("%.3c\n", i); /* { dg-warning "precision" "precision with %c" } */
47 printf ("%.3p\n", p); /* { dg-warning "precision" "precision with %p" } */
48 printf ("%.3n\n", n); /* { dg-warning "precision" "precision with %n" } */
49 /* Valid and invalid %% constructions. Some of the warning messages
50 are non-optimal, but they do detect the errorneous nature of the
51 format string.
53 printf ("%%");
54 printf ("%.3%"); /* { dg-warning "format" "bogus %%" } */
55 printf ("%-%"); /* { dg-warning "format" "bogus %%" } */
56 printf ("%-%\n"); /* { dg-warning "format" "bogus %%" } */
57 printf ("%5%\n"); /* { dg-warning "format" "bogus %%" } */
58 printf ("%h%\n"); /* { dg-warning "format" "bogus %%" } */
59 /* Valid and invalid %h, %l, %L constructions. */
60 printf ("%hd", i);
61 printf ("%hi", i);
62 /* Strictly, these parameters should be int or unsigned int according to
63 what unsigned short promotes to. However, GCC ignores sign
64 differences in format checking here, and this is relied on to get the
65 correct checking without print_char_table needing to know whether
66 int and short are the same size.
68 printf ("%ho%hu%hx%hX", u, u, u, u);
69 printf ("%hn", hn);
70 printf ("%hf", d); /* { dg-warning "length" "bad use of %h" } */
71 printf ("%he", d); /* { dg-warning "length" "bad use of %h" } */
72 printf ("%hE", d); /* { dg-warning "length" "bad use of %h" } */
73 printf ("%hg", d); /* { dg-warning "length" "bad use of %h" } */
74 printf ("%hG", d); /* { dg-warning "length" "bad use of %h" } */
75 printf ("%hc", i); /* { dg-warning "length" "bad use of %h" } */
76 printf ("%hs", s); /* { dg-warning "length" "bad use of %h" } */
77 printf ("%hp", p); /* { dg-warning "length" "bad use of %h" } */
78 printf ("%h"); /* { dg-warning "conversion lacks type" "bare %h" } */
79 printf ("%h."); /* { dg-warning "conversion" "bogus %h." } */
80 printf ("%ld%li%lo%lu%lx%lX", l, l, ul, ul, ul, ul);
81 printf ("%ln", ln);
82 printf ("%lf", d); /* { dg-warning "length|C" "bad use of %l" } */
83 printf ("%le", d); /* { dg-warning "length|C" "bad use of %l" } */
84 printf ("%lE", d); /* { dg-warning "length|C" "bad use of %l" } */
85 printf ("%lg", d); /* { dg-warning "length|C" "bad use of %l" } */
86 printf ("%lG", d); /* { dg-warning "length|C" "bad use of %l" } */
87 printf ("%lp", p); /* { dg-warning "length|C" "bad use of %l" } */
88 /* These next two were added in C94, but should be objected to in C90.
89 For the first one, GCC has wanted wchar_t instead of the correct C94
90 and C99 wint_t.
92 printf ("%lc", lc); /* { dg-warning "length|C" "C90 bad use of %l" } */
93 printf ("%ls", ls); /* { dg-warning "length|C" "C90 bad use of %l" } */
94 /* These uses of %L are legitimate, though GCC has wrongly warned for
95 them in the past.
97 printf ("%Le%LE%Lf%Lg%LG", ld, ld, ld, ld, ld);
98 /* These next six are accepted by GCC as referring to long long,
99 but -pedantic correctly warns.
101 printf ("%Ld", ll); /* { dg-warning "does not support" "bad use of %L" } */
102 printf ("%Li", ll); /* { dg-warning "does not support" "bad use of %L" } */
103 printf ("%Lo", ull); /* { dg-warning "does not support" "bad use of %L" } */
104 printf ("%Lu", ull); /* { dg-warning "does not support" "bad use of %L" } */
105 printf ("%Lx", ull); /* { dg-warning "does not support" "bad use of %L" } */
106 printf ("%LX", ull); /* { dg-warning "does not support" "bad use of %L" } */
107 printf ("%Lc", i); /* { dg-warning "length" "bad use of %L" } */
108 printf ("%Ls", s); /* { dg-warning "length" "bad use of %L" } */
109 printf ("%Lp", p); /* { dg-warning "length" "bad use of %L" } */
110 printf ("%Ln", n); /* { dg-warning "length" "bad use of %L" } */
111 /* Valid uses of each bare conversion. */
112 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,
113 i, s, p, n);
114 /* Uses of the - flag (valid on all non-%, non-n conversions). */
115 printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, u, u, u, u,
116 d, d, d, d, d, i, s, p);
117 printf ("%-n", n); /* { dg-warning "flag" "bad use of %-n" } */
118 /* Uses of the + flag (valid on signed conversions only). */
119 printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d);
120 printf ("%+o", u); /* { dg-warning "flag" "bad use of + flag" } */
121 printf ("%+u", u); /* { dg-warning "flag" "bad use of + flag" } */
122 printf ("%+x", u); /* { dg-warning "flag" "bad use of + flag" } */
123 printf ("%+X", u); /* { dg-warning "flag" "bad use of + flag" } */
124 printf ("%+c", i); /* { dg-warning "flag" "bad use of + flag" } */
125 printf ("%+s", s); /* { dg-warning "flag" "bad use of + flag" } */
126 printf ("%+p", p); /* { dg-warning "flag" "bad use of + flag" } */
127 printf ("%+n", n); /* { dg-warning "flag" "bad use of + flag" } */
128 /* Uses of the space flag (valid on signed conversions only, and ignored
129 with +).
131 printf ("% +d", i); /* { dg-warning "use of both|ignored" "use of space and + flags" } */
132 printf ("%+ d", i); /* { dg-warning "use of both|ignored" "use of space and + flags" } */
133 printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d);
134 printf ("% o", u); /* { dg-warning "flag" "bad use of space flag" } */
135 printf ("% u", u); /* { dg-warning "flag" "bad use of space flag" } */
136 printf ("% x", u); /* { dg-warning "flag" "bad use of space flag" } */
137 printf ("% X", u); /* { dg-warning "flag" "bad use of space flag" } */
138 printf ("% c", i); /* { dg-warning "flag" "bad use of space flag" } */
139 printf ("% s", s); /* { dg-warning "flag" "bad use of space flag" } */
140 printf ("% p", p); /* { dg-warning "flag" "bad use of space flag" } */
141 printf ("% n", n); /* { dg-warning "flag" "bad use of space flag" } */
142 /* Uses of the # flag. */
143 printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, d, d);
144 printf ("%#d", i); /* { dg-warning "flag" "bad use of # flag" } */
145 printf ("%#i", i); /* { dg-warning "flag" "bad use of # flag" } */
146 printf ("%#u", u); /* { dg-warning "flag" "bad use of # flag" } */
147 printf ("%#c", i); /* { dg-warning "flag" "bad use of # flag" } */
148 printf ("%#s", s); /* { dg-warning "flag" "bad use of # flag" } */
149 printf ("%#p", p); /* { dg-warning "flag" "bad use of # flag" } */
150 printf ("%#n", n); /* { dg-warning "flag" "bad use of # flag" } */
151 /* Uses of the 0 flag. */
152 printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, u, u, u, u,
153 d, d, d, d, d);
154 printf ("%0c", i); /* { dg-warning "flag" "bad use of 0 flag" } */
155 printf ("%0s", s); /* { dg-warning "flag" "bad use of 0 flag" } */
156 printf ("%0p", p); /* { dg-warning "flag" "bad use of 0 flag" } */
157 printf ("%0n", n); /* { dg-warning "flag" "bad use of 0 flag" } */
158 /* 0 flag ignored with precision for certain types, not others. */
159 printf ("%08.5d", i); /* { dg-warning "ignored" "0 flag ignored with precision" } */
160 printf ("%08.5i", i); /* { dg-warning "ignored" "0 flag ignored with precision" } */
161 printf ("%08.5o", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */
162 printf ("%08.5u", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */
163 printf ("%08.5x", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */
164 printf ("%08.5X", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */
165 printf ("%08.5f%08.5e%08.5E%08.5g%08.5G", d, d, d, d, d);
166 /* 0 flag ignored with - flag. */
167 printf ("%-08d", i); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
168 printf ("%-08i", i); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
169 printf ("%-08o", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
170 printf ("%-08u", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
171 printf ("%-08x", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
172 printf ("%-08X", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
173 printf ("%-08e", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
174 printf ("%-08E", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
175 printf ("%-08f", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
176 printf ("%-08g", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
177 printf ("%-08G", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
178 /* Various tests of bad argument types. */
179 printf ("%d", l); /* { dg-warning "format" "bad argument types" } */
180 printf ("%*.*d", l, i2, i); /* { dg-warning "field" "bad * argument types" } */
181 printf ("%*.*d", i1, l, i); /* { dg-warning "field" "bad * argument types" } */
182 printf ("%ld", i); /* { dg-warning "format" "bad argument types" } */
183 printf ("%s", n); /* { dg-warning "format" "bad argument types" } */
184 printf ("%p", i); /* { dg-warning "format" "bad argument types" } */
185 printf ("%n", p); /* { dg-warning "format" "bad argument types" } */
186 /* With -pedantic, we want some further checks for pointer targets:
187 %p should allow only pointers to void (possibly qualified) and
188 to character types (possibly qualified), but not function pointers
189 or pointers to other types. (Whether, in fact, character types are
190 allowed here is unclear; see thread on comp.std.c, July 2000 for
191 discussion of the requirements of rules on identical representation,
192 and of the application of the as if rule with the new va_arg
193 allowances in C99 to printf.) Likewise, we should warn if
194 pointer targets differ in signedness, except in some circumstances
195 for character pointers. (In C99 we should consider warning for
196 char * or unsigned char * being passed to %hhn, even if strictly
197 legitimate by the standard.)
199 printf ("%p", foo); /* { dg-warning "format" "bad argument types" } */
200 printf ("%n", un); /* { dg-warning "format" "bad argument types" } */
201 printf ("%p", n); /* { dg-warning "format" "bad argument types" } */
202 /* Allow character pointers with %p. */
203 printf ("%p%p%p%p", s, ss, us, css);
204 /* %s allows any character type. */
205 printf ("%s%s%s%s", s, ss, us, css);
206 /* Warning for void * arguments for %s is GCC's historical behavior,
207 and seems useful to keep, even if some standard versions might be
208 read to permit it.
210 printf ("%s", p); /* { dg-warning "format" "bad argument types" } */
211 /* The historical behavior is to allow signed / unsigned types
212 interchangably as arguments. For values representable in both types,
213 such usage may be correct. For now preserve the behavior of GCC
214 in such cases.
216 printf ("%d", u);
217 /* Also allow the same for width and precision arguments. In the past,
218 GCC has been inconsistent and allowed unsigned for width but not
219 precision.
221 printf ("%*.*d", u1, u2, i);
222 /* Wrong number of arguments. */
223 printf ("%d%d", i); /* { dg-warning "arguments" "wrong number of args" } */
224 printf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */
225 /* Miscellaneous bogus constructions. */
226 printf (""); /* { dg-warning "zero-length" "warning for empty format" } */
227 printf ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */
228 printf ("%d\0", i); /* { dg-warning "embedded" "warning for embedded NUL" } */
229 printf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */
230 printf (NULL); /* { dg-warning "null" "null format string warning" } */
231 printf ("%"); /* { dg-warning "trailing" "trailing % warning" } */
232 printf ("%++d", i); /* { dg-warning "repeated" "repeated flag warning" } */
233 printf ("%n", cn); /* { dg-warning "constant" "%n with const" } */
234 printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */
235 printf ("%n", (int *)0); /* { dg-warning "null" "%n with NULL" } */
236 printf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */