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