1 /* 78696 - -fprintf-return-value misoptimizes %.Ng where N is greater than 10
2    Test to verify the correctness of ranges of output computed for floating
3    point directives.
4    { dg-do compile }
5    { dg-require-effective-target double64plus }
6    { dg-options "-O2 -Wformat -Wformat-overflow -ftrack-macro-expansion=0" } */
7 
8 typedef __builtin_va_list va_list;
9 
10 char dst[1];
11 
12 extern void sink (int, void*);
13 
14 /* Macro to test either width or precision specified by the asterisk
15    (but not both).  */
16 #define T1(fmt, a)    sink (__builtin_sprintf (dst + 1, fmt, a, x), dst)
17 
18 /* Macro to test both width and precision specified by the asterisk.  */
19 #define T2(fmt, w, p) sink (__builtin_sprintf (dst + 1, fmt, w, p, x), dst)
20 
21 /* Macro to test vsprintf with both width and precision specified by
22    the asterisk.  */
23 #define T(fmt) sink (__builtin_vsprintf (dst + 1, fmt, va), dst)
24 
25 /* Exercise %a.  */
test_a(int w,int p,double x)26 void test_a (int w, int p, double x)
27 {
28   T1 ("%.*a", 0);     /* { dg-warning "between 3 and 10 bytes" } */
29   T1 ("%.*a", 1);     /* { dg-warning "between 3 and 12 bytes" } */
30   T1 ("%.*a", 2);     /* { dg-warning "between 3 and 13 bytes" } */
31   T1 ("%.*a", 99);    /* { dg-warning "between 3 and 110 bytes" } */
32   T1 ("%.*a", 199);   /* { dg-warning "between 3 and 210 bytes" } */
33   T1 ("%.*a", 1099);  /* { dg-warning "between 3 and 1110 bytes" } */
34 
35   T1 ("%*.a", 0);     /* { dg-warning "between 3 and 10 bytes" } */
36   T1 ("%*.a", 1);     /* { dg-warning "between 3 and 10 bytes" } */
37   T1 ("%*.a", 3);     /* { dg-warning "between 3 and 10 bytes" } */
38   T1 ("%*.a", 6);     /* { dg-warning "between 6 and 10 bytes" } */
39   T1 ("%*.a", 7);     /* { dg-warning "between 7 and 10 bytes" } */
40 
41   T1 ("%*.a", w);     /* { dg-warning "writing between 3 and 2147483648 bytes" } */
42   T1 ("%*.0a", w);    /* { dg-warning "writing between 3 and 2147483648 bytes" } */
43   T1 ("%*.1a", w);    /* { dg-warning "writing between 3 and 2147483648 bytes" } */
44   T1 ("%*.2a", w);    /* { dg-warning "writing between 3 and 2147483648 bytes" } */
45 
46   T1 ("%.*a",  p);    /* { dg-warning "writing between 3 and 2147483658 bytes" } */
47   T1 ("%1.*a", p);    /* { dg-warning "writing between 3 and 2147483658 bytes" } */
48   T1 ("%2.*a", p);    /* { dg-warning "writing between 3 and 2147483658 bytes" } */
49   T1 ("%3.*a", p);    /* { dg-warning "writing between 3 and 2147483658 bytes" } */
50 
51   T2 ("%*.*a", w, p); /* { dg-warning "writing between 3 and 2147483658 bytes" } */
52 }
53 
54 /* Exercise %e.  */
test_e(int w,int p,double x)55 void test_e (int w, int p, double x)
56 {
57   T1 ("%.*e", 0);     /* { dg-warning "between 3 and 7 bytes" } */
58   T1 ("%.*e", 1);     /* { dg-warning "between 3 and 9 bytes" } */
59   T1 ("%.*e", 2);     /* { dg-warning "between 3 and 10 bytes" } */
60   T1 ("%.*e", 99);    /* { dg-warning "between 3 and 107 bytes" } */
61   T1 ("%.*e", 199);   /* { dg-warning "between 3 and 207 bytes" } */
62   T1 ("%.*e", 1099);  /* { dg-warning "between 3 and 1107 bytes" } */
63 
64   T1 ("%*.e", 0);     /* { dg-warning "between 3 and 7 bytes" } */
65   T1 ("%*.e", 1);     /* { dg-warning "between 3 and 7 bytes" } */
66   T1 ("%*.e", 1);     /* { dg-warning "between 3 and 7 bytes" } */
67   T1 ("%*.e", 3);     /* { dg-warning "between 3 and 7 bytes" } */
68   T1 ("%*.e", 6);     /* { dg-warning "between 6 and 7 bytes" } */
69   T1 ("%*.e", 7);     /* { dg-warning "writing 7 bytes" } */
70 
71   T1 ("%*.e", w);     /* { dg-warning "writing between 3 and 2147483648 bytes" } */
72   T1 ("%*.0e", w);    /* { dg-warning "writing between 3 and 2147483648 bytes" } */
73   T1 ("%*.1e", w);    /* { dg-warning "writing between 3 and 2147483648 bytes" } */
74   T1 ("%*.2e", w);    /* { dg-warning "writing between 3 and 2147483648 bytes" } */
75 
76   T1 ("%.*e",  p);    /* { dg-warning "writing between 3 and 2147483655 bytes" } */
77   T1 ("%1.*e", p);    /* { dg-warning "writing between 3 and 2147483655 bytes" } */
78   T1 ("%2.*e", p);    /* { dg-warning "writing between 3 and 2147483655 bytes" } */
79   T1 ("%3.*e", p);    /* { dg-warning "writing between 3 and 2147483655 bytes" } */
80 
81   T2 ("%*.*e", w, p); /* { dg-warning "writing between 3 and 2147483655 bytes" } */
82 }
83 
84 /* Exercise %f.  */
test_f(int w,int p,double x)85 void test_f (int w, int p, double x)
86 {
87   T1 ("%.*f", 0);           /* { dg-warning "between 1 and 310 bytes" } */
88   T1 ("%.*f", 1);           /* { dg-warning "between 3 and 312 bytes" } */
89   T1 ("%.*f", 2);           /* { dg-warning "between 3 and 313 bytes" } */
90   T1 ("%.*f", 99);          /* { dg-warning "between 3 and 410 bytes" } */
91   T1 ("%.*f", 199);         /* { dg-warning "between 3 and 510 bytes" } */
92   T1 ("%.*f", 1099);        /* { dg-warning "between 3 and 1410 bytes" } */
93 
94   T2 ("%*.*f", 0, 0);       /* { dg-warning "between 1 and 310 bytes" } */
95   T2 ("%*.*f", 1, 0);       /* { dg-warning "between 1 and 310 bytes" } */
96   T2 ("%*.*f", 2, 0);       /* { dg-warning "between 2 and 310 bytes" } */
97   T2 ("%*.*f", 3, 0);       /* { dg-warning "between 3 and 310 bytes" } */
98   T2 ("%*.*f", 310, 0);     /* { dg-warning "writing 310 bytes" } */
99   T2 ("%*.*f", 311, 0);     /* { dg-warning "writing 311 bytes" } */
100   T2 ("%*.*f", 312, 312);   /* { dg-warning "between 312 and 623 bytes" } */
101   T2 ("%*.*f", 312, 313);   /* { dg-warning "between 312 and 624 bytes" } */
102 
103   T1 ("%*.f", w);           /* { dg-warning "writing between 1 and 2147483648 bytes" } */
104   T1 ("%*.0f", w);          /* { dg-warning "writing between 1 and 2147483648 bytes" } */
105   T1 ("%*.1f", w);          /* { dg-warning "writing between 3 and 2147483648 bytes" } */
106   T1 ("%*.2f", w);          /* { dg-warning "writing between 3 and 2147483648 bytes" } */
107 
108   T1 ("%.*f",  p);          /* { dg-warning "writing between 1 and 2147483958 bytes" } */
109   T1 ("%1.*f", p);          /* { dg-warning "writing between 1 and 2147483958 bytes" } */
110   T1 ("%2.*f", p);          /* { dg-warning "writing between 2 and 2147483958 bytes" } */
111   T1 ("%3.*f", p);          /* { dg-warning "writing between 3 and 2147483958 bytes" } */
112 
113   T2 ("%*.*f", w, p);       /* { dg-warning "writing between 1 and 2147483958 bytes" } */
114 }
115 
116 /* Exercise %g.  The expected output is the lesser of %e and %f.  */
test_g(double x)117 void test_g (double x)
118 {
119   T1 ("%.*g", 0);           /* { dg-warning "between 1 and 7 bytes" } */
120   T1 ("%.*g", 1);           /* { dg-warning "between 1 and 7 bytes" } */
121   T1 ("%.*g", 2);           /* { dg-warning "between 1 and 9 bytes" } */
122   T1 ("%.*g", 99);          /* { dg-warning "between 1 and 106 bytes" } */
123   T1 ("%.*g", 199);         /* { dg-warning "between 1 and 206 bytes" } */
124   T1 ("%.*g", 1099);        /* { dg-warning "between 1 and 310 bytes" } */
125 
126   T2 ("%*.*g", 0, 0);       /* { dg-warning "between 1 and 7 bytes" } */
127   T2 ("%*.*g", 1, 0);       /* { dg-warning "between 1 and 7 bytes" } */
128   T2 ("%*.*g", 2, 0);       /* { dg-warning "between 2 and 7 bytes" } */
129   T2 ("%*.*g", 3, 0);       /* { dg-warning "between 3 and 7 bytes" } */
130   T2 ("%*.*g", 7, 0);       /* { dg-warning "writing 7 bytes" } */
131   T2 ("%*.*g", 310, 0);     /* { dg-warning "writing 310 bytes" } */
132   T2 ("%*.*g", 311, 0);     /* { dg-warning "writing 311 bytes" } */
133   T2 ("%*.*g", 312, 312);   /* { dg-warning "writing 312 bytes" } */
134   T2 ("%*.*g", 312, 313);   /* { dg-warning "writing 312 bytes" } */
135   T2 ("%*.*g", 333, 999);   /* { dg-warning "writing 333 bytes" } */
136 }
137 
138 /* Exercise %a.  */
test_a_va(va_list va)139 void test_a_va (va_list va)
140 {
141   T ("%.0a");       /* { dg-warning "between 3 and 10 bytes" } */
142   T ("%.1a");       /* { dg-warning "between 3 and 12 bytes" } */
143   T ("%.2a");       /* { dg-warning "between 3 and 13 bytes" } */
144   T ("%.99a");      /* { dg-warning "between 3 and 110 bytes" } */
145   T ("%.199a");     /* { dg-warning "between 3 and 210 bytes" } */
146   T ("%.1099a");    /* { dg-warning "between 3 and 1110 bytes" } */
147 
148   T ("%0.a");       /* { dg-warning "between 3 and 10 bytes" } */
149   T ("%1.a");       /* { dg-warning "between 3 and 10 bytes" } */
150   T ("%3.a");       /* { dg-warning "between 3 and 10 bytes" } */
151   T ("%6.a");       /* { dg-warning "between 6 and 10 bytes" } */
152   T ("%7.a");       /* { dg-warning "between 7 and 10 bytes" } */
153 
154   T ("%*.a");       /* { dg-warning "writing between 3 and 2147483648 bytes" } */
155   T ("%*.0a");      /* { dg-warning "writing between 3 and 2147483648 bytes" } */
156   T ("%*.1a");      /* { dg-warning "writing between 3 and 2147483648 bytes" } */
157   T ("%*.2a");      /* { dg-warning "writing between 3 and 2147483648 bytes" } */
158 
159   T ("%.*a");       /* { dg-warning "writing between 3 and 2147483658 bytes" } */
160   T ("%1.*a");      /* { dg-warning "writing between 3 and 2147483658 bytes" } */
161   T ("%2.*a");      /* { dg-warning "writing between 3 and 2147483658 bytes" } */
162   T ("%6.*a");      /* { dg-warning "writing between 6 and 2147483658 bytes" } */
163   T ("%9.*a");      /* { dg-warning "writing between 9 and 2147483658 bytes" } */
164 
165   T ("%*.*a");      /* { dg-warning "writing between 3 and 2147483658 bytes" } */
166 }
167 
168 /* Exercise %e.  */
test_e_va(va_list va)169 void test_e_va (va_list va)
170 {
171   T ("%e");         /* { dg-warning "between 3 and 14 bytes" } */
172   T ("%+e");        /* { dg-warning "between 4 and 14 bytes" } */
173   T ("% e");        /* { dg-warning "between 4 and 14 bytes" } */
174   T ("%#e");        /* { dg-warning "between 3 and 14 bytes" } */
175   T ("%#+e");       /* { dg-warning "between 4 and 14 bytes" } */
176   T ("%# e");       /* { dg-warning "between 4 and 14 bytes" } */
177 
178   T ("%.e");        /* { dg-warning "between 3 and 7 bytes" } */
179   T ("%.0e");       /* { dg-warning "between 3 and 7 bytes" } */
180   T ("%.1e");       /* { dg-warning "between 3 and 9 bytes" } */
181   T ("%.2e");       /* { dg-warning "between 3 and 10 bytes" } */
182   T ("%.99e");      /* { dg-warning "between 3 and 107 bytes" } */
183   T ("%.199e");     /* { dg-warning "between 3 and 207 bytes" } */
184   T ("%.1099e");    /* { dg-warning "between 3 and 1107 bytes" } */
185 
186   T ("%0.e");       /* { dg-warning "between 3 and 7 bytes" } */
187   T ("%1.e");       /* { dg-warning "between 3 and 7 bytes" } */
188   T ("%1.e");       /* { dg-warning "between 3 and 7 bytes" } */
189   T ("%3.e");       /* { dg-warning "between 3 and 7 bytes" } */
190   T ("%6.e");       /* { dg-warning "between 6 and 7 bytes" } */
191   T ("%7.e");       /* { dg-warning "writing 7 bytes" } */
192 
193   T ("%.*e");       /* { dg-warning "writing between 3 and 2147483655 bytes" } */
194   T ("%1.*e");      /* { dg-warning "writing between 3 and 2147483655 bytes" } */
195   T ("%6.*e");      /* { dg-warning "writing between 6 and 2147483655 bytes" } */
196   T ("%9.*e");      /* { dg-warning "writing between 9 and 2147483655 bytes" } */
197 
198   T ("%*.*e");      /* { dg-warning "writing between 3 and 2147483655 bytes" } */
199 }
200 
201 /* Exercise %f.  */
test_f_va(va_list va)202 void test_f_va (va_list va)
203 {
204   T ("%f");         /* { dg-warning "between 3 and 317 bytes" } */
205   T ("%+f");        /* { dg-warning "between 4 and 317 bytes" } */
206   T ("% f");        /* { dg-warning "between 4 and 317 bytes" } */
207   T ("%#f");        /* { dg-warning "between 3 and 317 bytes" } */
208   T ("%+f");        /* { dg-warning "between 4 and 317 bytes" } */
209   T ("% f");        /* { dg-warning "between 4 and 317 bytes" } */
210   T ("%#+f");       /* { dg-warning "between 4 and 317 bytes" } */
211   T ("%# f");       /* { dg-warning "between 4 and 317 bytes" } */
212 
213   T ("%.f");        /* { dg-warning "between 1 and 310 bytes" } */
214   T ("%.0f");       /* { dg-warning "between 1 and 310 bytes" } */
215   T ("%.1f");       /* { dg-warning "between 3 and 312 bytes" } */
216   T ("%.2f");       /* { dg-warning "between 3 and 313 bytes" } */
217   T ("%.99f");      /* { dg-warning "between 3 and 410 bytes" } */
218   T ("%.199f");     /* { dg-warning "between 3 and 510 bytes" } */
219   T ("%.1099f");    /* { dg-warning "between 3 and 1410 bytes" } */
220 
221   T ("%0.0f");      /* { dg-warning "between 1 and 310 bytes" } */
222   T ("%1.0f");      /* { dg-warning "between 1 and 310 bytes" } */
223   T ("%2.0f");      /* { dg-warning "between 2 and 310 bytes" } */
224   T ("%3.0f");      /* { dg-warning "between 3 and 310 bytes" } */
225   T ("%310.0f");    /* { dg-warning "writing 310 bytes" } */
226   T ("%311.0f");    /* { dg-warning "writing 311 bytes" } */
227   T ("%312.312f");  /* { dg-warning "between 312 and 623 bytes" } */
228   T ("%312.313f");  /* { dg-warning "between 312 and 624 bytes" } */
229 
230   T ("%.*f");       /* { dg-warning "writing between 1 and 2147483958 bytes" } */
231   T ("%1.*f");      /* { dg-warning "writing between 1 and 2147483958 bytes" } */
232   T ("%3.*f");      /* { dg-warning "writing between 3 and 2147483958 bytes" } */
233 
234   T ("%*.*f");      /* { dg-warning "writing between 1 and 2147483958 bytes" } */
235 }
236 
237 /* Exercise %g.  The expected output is the lesser of %e and %f.  */
test_g_va(va_list va)238 void test_g_va (va_list va)
239 {
240   T ("%g");         /* { dg-warning "between 1 and 13 bytes" } */
241   T ("%+g");        /* { dg-warning "between 2 and 13 bytes" } */
242   T ("% g");        /* { dg-warning "between 2 and 13 bytes" } */
243 
244   /* The pound flag means the radix character is always present.  */
245   T ("%#g");        /* { dg-warning "between 2 and 13 bytes" } */
246   T ("%#+g");       /* { dg-warning "between 3 and 13 bytes" } */
247   T ("%# g");       /* { dg-warning "between 3 and 13 bytes" } */
248 
249   T ("%.g");        /* { dg-warning "between 1 and 7 bytes" } */
250   T ("%.0g");       /* { dg-warning "between 1 and 7 bytes" } */
251   T ("%.1g");       /* { dg-warning "between 1 and 7 bytes" } */
252   T ("%.2g");       /* { dg-warning "between 1 and 9 bytes" } */
253   T ("%.99g");      /* { dg-warning "between 1 and 106 bytes" } */
254   T ("%.199g");     /* { dg-warning "between 1 and 206 bytes" } */
255   T ("%.1099g");    /* { dg-warning "between 1 and 310 bytes" } */
256 
257   T ("%0.0g");      /* { dg-warning "between 1 and 7 bytes" } */
258   T ("%1.0g");      /* { dg-warning "between 1 and 7 bytes" } */
259   T ("%2.0g");      /* { dg-warning "between 2 and 7 bytes" } */
260   T ("%3.0g");      /* { dg-warning "between 3 and 7 bytes" } */
261   T ("%7.0g");      /* { dg-warning "writing 7 bytes" } */
262   T ("%310.0g");    /* { dg-warning "writing 310 bytes" } */
263   T ("%311.0g");    /* { dg-warning "writing 311 bytes" } */
264   T ("%312.312g");  /* { dg-warning "writing 312 bytes" } */
265   T ("%312.313g");  /* { dg-warning "writing 312 bytes" } */
266   T ("%333.999g");  /* { dg-warning "writing 333 bytes" } */
267 
268   T ("%.*g");       /* { dg-warning "writing between 1 and 310 bytes" } */
269   T ("%1.*g");      /* { dg-warning "writing between 1 and 310 bytes" } */
270   T ("%4.*g");      /* { dg-warning "writing between 4 and 310 bytes" } */
271 
272   T ("%*.*g");      /* { dg-warning "writing between 1 and 2147483648 bytes" } */
273 }
274