1/* Test for GCC diagnositc formats.  */
2/* Origin: Kaveh Ghazi <ghazi@caip.rutgers.edu> */
3/* { dg-do compile } */
4/* { dg-options "-Wformat" } */
5
6#include "format.h"
7
8#define ATTRIBUTE_DIAG(F) __attribute__ ((__format__ (F, 1, 2))) __attribute__ ((__nonnull__));
9
10/* Magic identifiers must be set before the attribute is used.  */
11
12typedef long long __gcc_host_wide_int__;
13
14typedef struct location_s
15{
16  const char *file;
17  int line;
18} location_t;
19
20union tree_node;
21typedef union tree_node *tree;
22
23extern int diag (const char *, ...) ATTRIBUTE_DIAG(__gcc_diag__);
24extern int tdiag (const char *, ...) ATTRIBUTE_DIAG(__gcc_tdiag__);
25extern int cdiag (const char *, ...) ATTRIBUTE_DIAG(__gcc_cdiag__);
26extern int cxxdiag (const char *, ...) ATTRIBUTE_DIAG(__gcc_cxxdiag__);
27
28void
29foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
30     int *n, short int *hn, long int l, unsigned long int ul,
31     long int *ln, long double ld, wint_t lc, wchar_t *ls, llong ll,
32     ullong ull, unsigned int *un, const int *cn, signed char *ss,
33     unsigned char *us, const signed char *css, unsigned int u1,
34     unsigned int u2, location_t *loc, tree t1, union tree_node *t2,
35     tree *t3, tree t4[])
36{
37  /* Acceptable C90 specifiers, flags and modifiers.  */
38  diag ("%%");
39  tdiag ("%%");
40  cdiag ("%%");
41  cxxdiag ("%%");
42  diag ("%d%i%o%u%x%c%s%p%%", i, i, u, u, u, i, s, p);
43  tdiag ("%d%i%o%u%x%c%s%p%%", i, i, u, u, u, i, s, p);
44  cdiag ("%d%i%o%u%x%c%s%p%%", i, i, u, u, u, i, s, p);
45  cxxdiag ("%d%i%o%u%x%c%s%p%%", i, i, u, u, u, i, s, p);
46  diag ("%qd%qi%qo%qu%qx%qc%qs%qp%<%%%'%>", i, i, u, u, u, i, s, p);
47  tdiag ("%qd%qi%qo%qu%qx%qc%qs%qp%<%%%'%>", i, i, u, u, u, i, s, p);
48  cdiag ("%qd%qi%qo%qu%qx%qc%qs%qp%<%%%'%>", i, i, u, u, u, i, s, p);
49  cxxdiag ("%qd%qi%qo%qu%qx%qc%qs%qp%<%%%'%>", i, i, u, u, u, i, s, p);
50  diag ("%ld%li%lo%lu%lx", l, l, ul, ul, ul);
51  tdiag ("%ld%li%lo%lu%lx", l, l, ul, ul, ul);
52  cdiag ("%ld%li%lo%lu%lx", l, l, ul, ul, ul);
53  cxxdiag ("%ld%li%lo%lu%lx", l, l, ul, ul, ul);
54  diag ("%lld%lli%llo%llu%llx", ll, ll, ull, ull, ull);
55  tdiag ("%lld%lli%llo%llu%llx", ll, ll, ull, ull, ull);
56  cdiag ("%lld%lli%llo%llu%llx", ll, ll, ull, ull, ull);
57  cxxdiag ("%lld%lli%llo%llu%llx", ll, ll, ull, ull, ull);
58  diag ("%wd%wi%wo%wu%wx", ll, ll, ull, ull, ull);
59  tdiag ("%wd%wi%wo%wu%wx", ll, ll, ull, ull, ull);
60  cdiag ("%wd%wi%wo%wu%wx", ll, ll, ull, ull, ull);
61  cxxdiag ("%wd%wi%wo%wu%wx", ll, ll, ull, ull, ull);
62  diag ("%.*s", i, s);
63  tdiag ("%.*s", i, s);
64  cdiag ("%.*s", i, s);
65  cxxdiag ("%.*s", i, s);
66
67  /* Extensions provided in the diagnostic framework.  */
68  diag ("%m");
69  tdiag ("%m");
70  cdiag ("%m");
71  cxxdiag ("%m");
72
73  tdiag ("%D%F%T%V", t1, t1, t1, t1);
74  tdiag ("%+D%+F%+T%+V", t1, t1, t1, t1);
75  tdiag ("%q+D%q+F%q+T%q+V", t1, t1, t1, t1);
76  tdiag ("%D%D%D%D", t1, t2, *t3, t4[5]);
77  cdiag ("%D%F%T%V", t1, t1, t1, t1);
78  cdiag ("%+D%+F%+T%+V", t1, t1, t1, t1);
79  cdiag ("%q+D%q+F%q+T%q+V", t1, t1, t1, t1);
80  cdiag ("%D%D%D%D", t1, t2, *t3, t4[5]);
81  cdiag ("%E", t1);
82  cxxdiag ("%A%D%E%F%T%V", t1, t1, t1, t1, t1, t1);
83  cxxdiag ("%D%D%D%D", t1, t2, *t3, t4[5]);
84  cxxdiag ("%#A%#D%#E%#F%#T%#V", t1, t1, t1, t1, t1, t1);
85  cxxdiag ("%+A%+D%+E%+F%+T%+V", t1, t1, t1, t1, t1, t1);
86  cxxdiag ("%+#A%+#D%+#E%+#F%+#T%+#V", t1, t1, t1, t1, t1, t1);
87  cxxdiag ("%C%L%O%P%Q", i, i, i, i, i);
88
89  tdiag ("%v%qv%#v", i, i, i);
90  cdiag ("%v%qv%#v", i, i, i);
91  cxxdiag ("%v%qv%#v", i, i, i);
92
93  /* Bad stuff with extensions.  */
94  diag ("%m", i); /* { dg-warning "format" "extra arg" } */
95  tdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
96  cdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
97  cxxdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
98  diag ("%#m"); /* { dg-warning "format" "bogus modifier" } */
99  tdiag ("%#m"); /* { dg-warning "format" "bogus modifier" } */
100  cdiag ("%#m"); /* { dg-warning "format" "bogus modifier" } */
101  cxxdiag ("%#m"); /* { dg-warning "format" "bogus modifier" } */
102  diag ("%+m"); /* { dg-warning "format" "bogus modifier" } */
103  tdiag ("%+m"); /* { dg-warning "format" "bogus modifier" } */
104  cdiag ("%+m"); /* { dg-warning "format" "bogus modifier" } */
105  cxxdiag ("%+m"); /* { dg-warning "format" "bogus modifier" } */
106  diag ("%D", t1); /* { dg-warning "format" "bogus tree" } */
107  tdiag ("%A", t1); /* { dg-warning "format" "bogus tree" } */
108  tdiag ("%E", t1);
109  tdiag ("%#D", t1); /* { dg-warning "format" "bogus modifier" } */
110  cdiag ("%A", t1); /* { dg-warning "format" "bogus tree" } */
111  cdiag ("%#D", t1); /* { dg-warning "format" "bogus modifier" } */
112  cdiag ("%+D", t1);
113  cxxdiag ("%C"); /* { dg-warning "format" "missing arg" } */
114  cxxdiag ("%C", l); /* { dg-warning "format" "wrong arg" } */
115  cxxdiag ("%C", i, i); /* { dg-warning "format" "extra arg" } */
116  cxxdiag ("%#C", i); /* { dg-warning "format" "bogus modifier" } */
117  cxxdiag ("%+C", i); /* { dg-warning "format" "bogus modifier" } */
118  tdiag ("%D"); /* { dg-warning "format" "missing arg" } */
119  cdiag ("%D"); /* { dg-warning "format" "missing arg" } */
120  cxxdiag ("%D"); /* { dg-warning "format" "missing arg" } */
121  tdiag ("%D", i); /* { dg-warning "format" "wrong arg" } */
122  cdiag ("%D", i); /* { dg-warning "format" "wrong arg" } */
123  cxxdiag ("%D", i); /* { dg-warning "format" "wrong arg" } */
124  tdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */
125  cdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */
126  cxxdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */
127
128  tdiag ("%V", i); /* { dg-warning "format" "wrong arg" } */
129  cdiag ("%V", i); /* { dg-warning "format" "wrong arg" } */
130  cxxdiag ("%V", i); /* { dg-warning "format" "wrong arg" } */
131
132  tdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
133  cdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
134  cxxdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
135
136  /* Standard specifiers not accepted in the diagnostic framework.  */
137  diag ("%X\n", u); /* { dg-warning "format" "HEX" } */
138  diag ("%f\n", d); /* { dg-warning "format" "float" } */
139  diag ("%e\n", d); /* { dg-warning "format" "float" } */
140  diag ("%E\n", d); /* { dg-warning "format" "float" } */
141  diag ("%g\n", d); /* { dg-warning "format" "float" } */
142  diag ("%G\n", d); /* { dg-warning "format" "float" } */
143  diag ("%n\n", n); /* { dg-warning "format" "counter" } */
144  diag ("%hd\n", i); /* { dg-warning "format" "conversion" } */
145
146  /* Various tests of bad argument types.  */
147  diag ("%-d", i); /* { dg-warning "format" "bad flag" } */
148  tdiag ("%-d", i); /* { dg-warning "format" "bad flag" } */
149  cdiag ("%-d", i); /* { dg-warning "format" "bad flag" } */
150  cxxdiag ("%-d", i); /* { dg-warning "format" "bad flag" } */
151  diag ("% d", i); /* { dg-warning "format" "bad flag" } */
152  tdiag ("% d", i); /* { dg-warning "format" "bad flag" } */
153  cdiag ("% d", i); /* { dg-warning "format" "bad flag" } */
154  cxxdiag ("% d", i); /* { dg-warning "format" "bad flag" } */
155  diag ("%#o", u); /* { dg-warning "format" "bad flag" } */
156  tdiag ("%#o", u); /* { dg-warning "format" "bad flag" } */
157  cdiag ("%#o", u); /* { dg-warning "format" "bad flag" } */
158  cxxdiag ("%#o", u); /* { dg-warning "format" "bad flag" } */
159  diag ("%0d", i); /* { dg-warning "format" "bad flag" } */
160  tdiag ("%0d", i); /* { dg-warning "format" "bad flag" } */
161  cdiag ("%0d", i); /* { dg-warning "format" "bad flag" } */
162  cxxdiag ("%0d", i); /* { dg-warning "format" "bad flag" } */
163  diag ("%08d", i); /* { dg-warning "format" "bad flag" } */
164  tdiag ("%08d", i); /* { dg-warning "format" "bad flag" } */
165  cdiag ("%08d", i); /* { dg-warning "format" "bad flag" } */
166  cxxdiag ("%08d", i); /* { dg-warning "format" "bad flag" } */
167  diag ("%+d\n", i); /* { dg-warning "format" "bad flag" } */
168  tdiag ("%+d\n", i); /* { dg-warning "format" "bad flag" } */
169  cdiag ("%+d\n", i); /* { dg-warning "format" "bad flag" } */
170  cxxdiag ("%+d\n", i); /* { dg-warning "format" "bad flag" } */
171  diag ("%3d\n", i); /* { dg-warning "format" "bad flag" } */
172  tdiag ("%3d\n", i); /* { dg-warning "format" "bad flag" } */
173  cdiag ("%3d\n", i); /* { dg-warning "format" "bad flag" } */
174  cxxdiag ("%3d\n", i); /* { dg-warning "format" "bad flag" } */
175  diag ("%-3d\n", i); /* { dg-warning "format" "bad flag" } */
176  tdiag ("%-3d\n", i); /* { dg-warning "format" "bad flag" } */
177  cdiag ("%-3d\n", i); /* { dg-warning "format" "bad flag" } */
178  cxxdiag ("%-3d\n", i); /* { dg-warning "format" "bad flag" } */
179  diag ("%.7d\n", i); /* { dg-warning "format" "bad flag" } */
180  tdiag ("%.7d\n", i); /* { dg-warning "format" "bad flag" } */
181  cdiag ("%.7d\n", i); /* { dg-warning "format" "bad flag" } */
182  cxxdiag ("%.7d\n", i); /* { dg-warning "format" "bad flag" } */
183  diag ("%+9.4d\n", i); /* { dg-warning "format" "bad flag" } */
184  tdiag ("%+9.4d\n", i); /* { dg-warning "format" "bad flag" } */
185  cdiag ("%+9.4d\n", i); /* { dg-warning "format" "bad flag" } */
186  cxxdiag ("%+9.4d\n", i); /* { dg-warning "format" "bad flag" } */
187  diag ("%.3ld\n", l); /* { dg-warning "format" "bad flag" } */
188  tdiag ("%.3ld\n", l); /* { dg-warning "format" "bad flag" } */
189  cdiag ("%.3ld\n", l); /* { dg-warning "format" "bad flag" } */
190  cxxdiag ("%.3ld\n", l); /* { dg-warning "format" "bad flag" } */
191  diag ("%d %lu\n", i, ul);
192  diag ("%d", l); /* { dg-warning "format" "bad argument types" } */
193  diag ("%wd", l); /* { dg-warning "format" "bad argument types" } */
194  diag ("%d", ll); /* { dg-warning "format" "bad argument types" } */
195  diag ("%*s", i, s); /* { dg-warning "format" "bad * argument types" } */
196  diag ("%*.*s", i, i, s); /* { dg-warning "format" "bad * argument types" } */
197  diag ("%*d\n", i1, i); /* { dg-warning "format" "bad * argument types" } */
198  diag ("%.*d\n", i2, i); /* { dg-warning "format" "bad * argument types" } */
199  diag ("%*.*ld\n", i1, i2, l); /* { dg-warning "format" "bad * argument types" } */
200  diag ("%ld", i); /* { dg-warning "format" "bad argument types" } */
201  diag ("%s", n); /* { dg-warning "format" "bad argument types" } */
202
203  /* Wrong number of arguments.  */
204  diag ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */
205  diag ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */
206  /* Miscellaneous bogus constructions.  */
207  diag (""); /* { dg-warning "zero-length" "warning for empty format" } */
208  diag ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */
209  diag ("%d\0", i); /* { dg-warning "embedded" "warning for embedded NUL" } */
210  diag ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */
211  diag (NULL); /* { dg-warning "null" "null format string warning" } */
212  diag ("%"); /* { dg-warning "trailing" "trailing % warning" } */
213  diag ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */
214  diag ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */
215
216  /* Make sure we still get warnings for regular printf.  */
217  printf ("%d\n", ll); /* { dg-warning "format" "bad argument types" } */
218}
219