libstdc++: Add script to update docs for a new release branch
[official-gcc.git] / gcc / testsuite / gcc.dg / tree-ssa / builtin-sprintf-warn-16.c
blobf975e16f36f7830addbd722d103486d2b888651a
1 /* PR middle-end/80364 - sanitizer detects signed integer overflow
2 in gimple-ssa-sprintf.c
3 { dg-do compile }
4 { dg-options "-O2 -Wall -Wformat-overflow=1 -ftrack-macro-expansion=0" }
5 { dg-require-effective-target int32plus } */
7 typedef __SIZE_TYPE__ size_t;
8 typedef __WCHAR_TYPE__ wchar_t;
10 void sink (void*);
11 void* get_value (void);
13 /* Return a random width as type T. */
14 #define W(T) *(T*)get_value ()
16 /* Return a random precision as type T. */
17 #define P(T) *(T*)get_value ()
19 /* Return a random value as type T. */
20 #define V(T) *(T*)get_value ()
22 extern char buf[1];
24 /* Test convenience macro. */
25 #define T(fmt, ...) \
26 __builtin_sprintf (buf + 1, fmt, __VA_ARGS__); \
27 sink (buf)
29 typedef signed char schar_t;
30 typedef unsigned char uchar_t;
31 typedef signed short sshort_t;
32 typedef unsigned short ushort_t;
33 typedef signed int sint_t;
34 typedef unsigned int uint_t;
35 typedef signed long slong_t;
36 typedef unsigned long ulong_t;
37 typedef signed long long sllong_t;
38 typedef unsigned long long ullong_t;
40 #if __SIZEOF_INT128__
41 typedef __int128_t sint128_t;
42 typedef __uint128_t uint128_t;
43 #else
44 /* When __int128_t is not available, repeat the same tests with long long.
45 This is to avoid having to guard the tests below and to avoid making
46 the dg-warning directives conditional. */
47 typedef signed long long sint128_t;
48 typedef unsigned long long uint128_t;
49 #endif
51 const sint128_t sint128_max
52 = (sint128_t)1 << (sizeof sint128_max * __CHAR_BIT__ - 2);
53 const sint128_t uint128_max = (uint128_t)-1;
55 void test_width_cst (void)
57 T ("%*i", W (schar_t), 1); /* { dg-warning "between 1 and 128 " } */
58 T ("%*i", W (uchar_t), 12); /* { dg-warning "between 2 and 255 " } */
60 T ("%*i", W (sshort_t), 123); /* { dg-warning "between 3 and 32768 " } */
61 T ("%*i", W (ushort_t), 1234); /* { dg-warning "between 4 and 65535 " } */
63 T ("%*i", W (sint_t), 12345); /* { dg-warning "between 5 and 2147483648 " } */
64 T ("%*i", W (uint_t), 123456); /* { dg-warning "between 6 and 2147483648 " } */
66 /* Exercise calls with invalid arguments (to verify there is no ICE). */
67 T ("%*li", W (slong_t), 1234567L); /* { dg-warning "between 7 and 2147483648 " } */
68 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
69 T ("%*li", W (ulong_t), 12345678L); /* { dg-warning "between 8 and 2147483648 " } */
70 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
72 T ("%*lli", W (sllong_t), 123456789LL); /* { dg-warning "between 9 and 2147483648 " } */
73 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
74 T ("%*lli", W (ullong_t), 1234567890LL); /* { dg-warning "between 10 and 2147483648 " } */
75 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
77 T ("%*i", W (sint128_t), 0); /* { dg-warning "between 1 and 2147483648 " } */
78 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
79 T ("%*i", W (uint128_t), 1); /* { dg-warning "between 1 and 2147483648 " } */
80 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
83 extern sint128_t si128;
84 if (si128 < sint128_max / 2 || sint128_max - 8 < si128)
85 si128 = sint128_max / 2;
87 T ("%*i", si128, 0); /* { dg-warning "between 1 and 2147483648 " } */
88 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
90 extern uint128_t ui128;
91 if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128)
92 ui128 = uint128_max / 2;
94 T ("%*i", ui128, 0); /* { dg-warning "between 1 and 2147483648 " } */
95 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
98 T ("%*i", W (float), 2); /* { dg-warning "between 1 and 2147483648 " } */
99 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
100 T ("%*i", W (double), 3); /* { dg-warning "between 1 and 2147483648 " } */
101 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
104 void test_width_var (void)
106 T ("%*i", W (schar_t), V (schar_t)); /* { dg-warning "between 1 and 128 " } */
107 T ("%*i", W (uchar_t), V (uchar_t)); /* { dg-warning "between 1 and 255 " } */
109 T ("%*i", W (sshort_t), V (sshort_t)); /* { dg-warning "between 1 and 32768 " } */
110 T ("%*i", W (ushort_t), V (ushort_t)); /* { dg-warning "between 1 and 65535 " } */
112 T ("%*i", W (sint_t), V (sint_t)); /* { dg-warning "between 1 and 2147483648 " } */
113 T ("%*i", W (uint_t), V (uint_t)); /* { dg-warning "between 1 and 2147483648 " } */
115 /* Exercise calls with invalid arguments (to verify there is no ICE). */
116 T ("%*li", W (slong_t), V (slong_t)); /* { dg-warning "between 1 and 2147483648 " } */
117 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
118 T ("%*li", W (ulong_t), V (ulong_t)); /* { dg-warning "between 1 and 2147483648 " } */
119 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
121 T ("%*lli", W (sllong_t), V (sllong_t)); /* { dg-warning "between 1 and 2147483648 " } */
122 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
123 T ("%*lli", W (ullong_t), V (ullong_t)); /* { dg-warning "between 1 and 2147483648 " } */
124 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
126 T ("%*i", W (float), V (int)); /* { dg-warning "between 1 and 2147483648 " } */
127 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
128 T ("%*i", W (double), V (int)); /* { dg-warning "between 1 and 2147483648 " } */
129 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
132 /* Create an unsigned range with a lower bound greater than 1 and
133 an upper bound in excess of INT_MAX and verify that after conversion
134 to signed int the lower bound isn't used as the minimum output (since
135 the excessive upper bound wraps around zero). Passing the precision
136 as unsigned, without the cast to signed int, is undedined.
137 It's possible to constrain the upper bound on the output more, based
138 on the upper bound of the width here, but not worth the trouble. */
139 unsigned w = W (unsigned);
140 if (w < 5 || (unsigned)-1 - 7 < w)
141 w = 5;
142 int val = V (int);
144 T ("%*u", (int)w, val); /* { dg-warning "between 1 and 2147483648 " } */
148 /* Verify that enums are correctly handled (i.e., that the warning
149 doesn't just test for TREE_CODE(type) == INTEGER_TYPE but instead
150 uses INTEGRAL_TYPE_P() or some equivalent. */
151 enum WidthEnum { e7 = 7, e9 = 9 };
152 enum WidthEnum w = V (enum WidthEnum);
153 if (w < e7 || e9 < w)
154 w = e7;
156 T ("%*hu", w, V (int)); /* { dg-warning "between 7 and 9 " } */
160 void test_precision_cst (void)
162 T ("%.*i", P (schar_t), 1); /* { dg-warning "between 1 and 127 " } */
163 T ("%.*i", P (uchar_t), 12); /* { dg-warning "between 2 and 255 " } */
165 T ("%.*i", P (sshort_t), 123); /* { dg-warning "between 3 and 32767 " } */
166 T ("%.*i", P (ushort_t), 1234); /* { dg-warning "between 4 and 65535 " } */
168 T ("%.*i", P (sint_t), 12345); /* { dg-warning "between 5 and 2147483647 " } */
169 T ("%.*i", P (uint_t), 123456); /* { dg-warning "between 6 and 2147483647 " } */
171 /* Exercise calls with invalid arguments (to verify there is no ICE). */
172 T ("%.*li", P (slong_t), 1234567L); /* { dg-warning "between 7 and 2147483647 " } */
173 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
174 T ("%.*li", P (ulong_t), 12345678L); /* { dg-warning "between 8 and 2147483647 " } */
175 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
177 T ("%.*lli", P (sllong_t), 123456789LL); /* { dg-warning "between 9 and 2147483647 " } */
178 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
179 T ("%.*lli", P (ullong_t), 1234567890LL); /* { dg-warning "between 10 and 2147483647 " } */
180 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
182 T ("%.*i", P (sint128_t), 0); /* { dg-warning "up to 2147483647 " } */
183 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
184 T ("%.*i", P (uint128_t), 1); /* { dg-warning "between 1 and 2147483647 " } */
185 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
188 extern sint128_t si128;
189 if (si128 < sint128_max / 2 || sint128_max - 8 < si128)
190 si128 = sint128_max / 2;
192 T ("%.*i", si128, 0); /* { dg-warning "up to 2147483647 " } */
193 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
195 extern uint128_t ui128;
196 if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128)
197 ui128 = uint128_max / 2;
199 T ("%.*i", ui128, 0); /* { dg-warning "up to 2147483647 " } */
200 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
203 T ("%.*i", P (float), 0); /* { dg-warning "up to 2147483647 " } */
204 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
205 T ("%.*i", P (double), 1); /* { dg-warning "between 1 and 2147483647 " } */
206 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
209 void test_precision_var (void)
211 T ("%.*i", P (schar_t), V (schar_t)); /* { dg-warning "up to 128 " } */
212 T ("%.*i", P (uchar_t), V (uchar_t)); /* { dg-warning "up to 255 " } */
214 T ("%.*i", P (sshort_t), V (sshort_t)); /* { dg-warning "up to 32768 " } */
215 T ("%.*i", P (ushort_t), V (ushort_t)); /* { dg-warning "up to 65535 " } */
217 T ("%.*i", P (sint_t), V (sint_t)); /* { dg-warning "up to 2147483648 " } */
218 T ("%.*i", P (uint_t), V (uint_t)); /* { dg-warning "up to 2147483648 " } */
220 /* Exercise calls with invalid arguments (to verify there is no ICE). */
221 T ("%.*li", P (slong_t), V (slong_t)); /* { dg-warning "up to 2147483648 " } */
222 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
223 T ("%.*li", P (ulong_t), V (ulong_t)); /* { dg-warning "up to 2147483648 " } */
224 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
226 T ("%.*lli", P (sllong_t), V (sllong_t)); /* { dg-warning "up to 2147483648" } */
227 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
228 T ("%.*lli", P (ullong_t), V (ullong_t)); /* { dg-warning "up to 2147483648" } */
229 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
231 T ("%.*i", P (float), V (int)); /* { dg-warning "up to 2147483648 " } */
232 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
233 T ("%.*i", P (double), V (int)); /* { dg-warning "up to 2147483648 " } */
234 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
237 /* Similar to the corresponding width case, create an unsigned range
238 with a lower bound greater than 1 and an upper bound in excess of
239 INT_MAX and verify that after conversion to int the lower bound isn't
240 used as the minimum output (since the excessive upper bound wraps
241 around zero). Passing the precision as unsigned, without a cast to
242 signed int, is undefined. */
243 unsigned p = V (unsigned);
244 if (p < 7 || (unsigned)-1 - 9 < p)
245 p = 7;
247 int val = V (int);
249 T ("%.*u", (int)p, val); /* { dg-warning "up to 2147483647 " } */
253 /* Verify that enums are correctly handled. */
254 enum PrecEnum { e9 = 9, e17 = 17 };
255 enum PrecEnum p = V (enum PrecEnum);
256 if (p < e9 || e17 < p)
257 p = e9;
259 T ("%.*u", p, V (int)); /* { dg-warning "between 9 and 17 " } */