111
|
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 } */
|
|
6
|
|
7 typedef __SIZE_TYPE__ size_t;
|
|
8 typedef __WCHAR_TYPE__ wchar_t;
|
|
9
|
|
10 void sink (void*);
|
|
11 void* get_value (void);
|
|
12
|
|
13 /* Return a random width as type T. */
|
|
14 #define W(T) *(T*)get_value ()
|
|
15
|
|
16 /* Return a random precision as type T. */
|
|
17 #define P(T) *(T*)get_value ()
|
|
18
|
|
19 /* Return a random value as type T. */
|
|
20 #define V(T) *(T*)get_value ()
|
|
21
|
|
22 extern char buf[1];
|
|
23
|
|
24 /* Test convenience macro. */
|
|
25 #define T(fmt, ...) \
|
|
26 __builtin_sprintf (buf + 1, fmt, __VA_ARGS__); \
|
|
27 sink (buf)
|
|
28
|
|
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;
|
|
39
|
|
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
|
|
50
|
|
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;
|
|
54
|
|
55 void test_width_cst (void)
|
|
56 {
|
|
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 " } */
|
|
59
|
|
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 " } */
|
|
62
|
|
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 " } */
|
|
65
|
|
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 } */
|
|
71
|
|
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 } */
|
|
76
|
|
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 } */
|
|
81
|
|
82 {
|
|
83 extern sint128_t si128;
|
|
84 if (si128 < sint128_max / 2 || sint128_max - 8 < si128)
|
|
85 si128 = sint128_max / 2;
|
|
86
|
|
87 T ("%*i", si128, 0); /* { dg-warning "between 1 and 2147483648 " } */
|
|
88 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
89
|
|
90 extern uint128_t ui128;
|
|
91 if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128)
|
|
92 ui128 = uint128_max / 2;
|
|
93
|
|
94 T ("%*i", ui128, 0); /* { dg-warning "between 1 and 2147483648 " } */
|
|
95 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
96 }
|
|
97
|
|
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 } */
|
|
102 }
|
|
103
|
|
104 void test_width_var (void)
|
|
105 {
|
|
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 " } */
|
|
108
|
|
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 " } */
|
|
111
|
|
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 " } */
|
|
114
|
|
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 } */
|
|
120
|
|
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 } */
|
|
125
|
|
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 } */
|
|
130
|
|
131 {
|
|
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 the lower
|
|
134 bound isn't used as the minimum output (since the excessive
|
|
135 upper bound wraps around zero). It's possible to constrain
|
|
136 the upper bound on the output more, based on the upper bound
|
|
137 of the width here, but not worth the trouble. */
|
|
138 extern unsigned w;
|
|
139 if (w < 5 || (unsigned)-1 - 7 < w)
|
|
140 w = 5;
|
|
141
|
|
142 T ("%*u", w, V (int)); /* { dg-warning "between 1 and 2147483648 " } */
|
|
143 }
|
|
144
|
|
145 {
|
|
146 /* Verify that enums are correctly handled (i.e., that the warning
|
|
147 doesn't just test for TREE_CODE(type) == INTEGER_TYPE but instead
|
|
148 uses INTEGRAL_TYPE_P() or some equivalent. */
|
|
149 enum WidthEnum { e7 = 7, e9 = 9 };
|
|
150 enum WidthEnum w = V (enum WidthEnum);
|
|
151 if (w < e7 || e9 < w)
|
|
152 w = e7;
|
|
153
|
|
154 T ("%*hu", w, V (int)); /* { dg-warning "between 7 and 9 " } */
|
|
155 }
|
|
156 }
|
|
157
|
|
158 void test_precision_cst (void)
|
|
159 {
|
|
160 T ("%.*i", P (schar_t), 1); /* { dg-warning "between 1 and 127 " } */
|
|
161 T ("%.*i", P (uchar_t), 12); /* { dg-warning "between 2 and 255 " } */
|
|
162
|
|
163 T ("%.*i", P (sshort_t), 123); /* { dg-warning "between 3 and 32767 " } */
|
|
164 T ("%.*i", P (ushort_t), 1234); /* { dg-warning "between 4 and 65535 " } */
|
|
165
|
|
166 T ("%.*i", P (sint_t), 12345); /* { dg-warning "between 5 and 2147483647 " } */
|
|
167 T ("%.*i", P (uint_t), 123456); /* { dg-warning "between 6 and 2147483647 " } */
|
|
168
|
|
169 /* Exercise calls with invalid arguments (to verify there is no ICE). */
|
|
170 T ("%.*li", P (slong_t), 1234567L); /* { dg-warning "between 7 and 2147483647 " } */
|
|
171 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
172 T ("%.*li", P (ulong_t), 12345678L); /* { dg-warning "between 8 and 2147483647 " } */
|
|
173 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
174
|
|
175 T ("%.*lli", P (sllong_t), 123456789LL); /* { dg-warning "between 9 and 2147483647 " } */
|
|
176 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
177 T ("%.*lli", P (ullong_t), 1234567890LL); /* { dg-warning "between 10 and 2147483647 " } */
|
|
178 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
179
|
|
180 T ("%.*i", P (sint128_t), 0); /* { dg-warning "up to 2147483647 " } */
|
|
181 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
182 T ("%.*i", P (uint128_t), 1); /* { dg-warning "between 1 and 2147483647 " } */
|
|
183 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
184
|
|
185 {
|
|
186 extern sint128_t si128;
|
|
187 if (si128 < sint128_max / 2 || sint128_max - 8 < si128)
|
|
188 si128 = sint128_max / 2;
|
|
189
|
|
190 T ("%.*i", si128, 0); /* { dg-warning "up to 2147483647 " } */
|
|
191 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
192
|
|
193 extern uint128_t ui128;
|
|
194 if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128)
|
|
195 ui128 = uint128_max / 2;
|
|
196
|
|
197 T ("%.*i", ui128, 0); /* { dg-warning "up to 2147483647 " } */
|
|
198 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
199 }
|
|
200
|
|
201 T ("%.*i", P (float), 0); /* { dg-warning "up to 2147483647 " } */
|
|
202 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
203 T ("%.*i", P (double), 1); /* { dg-warning "between 1 and 2147483647 " } */
|
|
204 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
205 }
|
|
206
|
|
207 void test_precision_var (void)
|
|
208 {
|
|
209 T ("%.*i", P (schar_t), V (schar_t)); /* { dg-warning "up to 128 " } */
|
|
210 T ("%.*i", P (uchar_t), V (uchar_t)); /* { dg-warning "up to 255 " } */
|
|
211
|
|
212 T ("%.*i", P (sshort_t), V (sshort_t)); /* { dg-warning "up to 32768 " } */
|
|
213 T ("%.*i", P (ushort_t), V (ushort_t)); /* { dg-warning "up to 65535 " } */
|
|
214
|
|
215 T ("%.*i", P (sint_t), V (sint_t)); /* { dg-warning "up to 2147483648 " } */
|
|
216 T ("%.*i", P (uint_t), V (uint_t)); /* { dg-warning "up to 2147483648 " } */
|
|
217
|
|
218 /* Exercise calls with invalid arguments (to verify there is no ICE). */
|
|
219 T ("%.*li", P (slong_t), V (slong_t)); /* { dg-warning "up to 2147483648 " } */
|
|
220 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
221 T ("%.*li", P (ulong_t), V (ulong_t)); /* { dg-warning "up to 2147483648 " } */
|
|
222 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
223
|
|
224 T ("%.*lli", P (sllong_t), V (sllong_t)); /* { dg-warning "up to 2147483648" } */
|
|
225 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
226 T ("%.*lli", P (ullong_t), V (ullong_t)); /* { dg-warning "up to 2147483648" } */
|
|
227 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
228
|
|
229 T ("%.*i", P (float), V (int)); /* { dg-warning "up to 2147483648 " } */
|
|
230 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
231 T ("%.*i", P (double), V (int)); /* { dg-warning "up to 2147483648 " } */
|
|
232 /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */
|
|
233
|
|
234 {
|
|
235 /* Similar to the corresponding width case, create an unsigned range
|
|
236 with a lower bound greater than 1 and an upper bound in excess of
|
|
237 INT_MAX and verify that the lower bound isn't used as the minimum
|
|
238 output (since the excessive upper bound wraps around zero). */
|
|
239 extern unsigned p;
|
|
240 if (p < 7 || (unsigned)-1 - 9 < p)
|
|
241 p = 7;
|
|
242
|
|
243 T ("%.*u", p, V (int)); /* { dg-warning "up to 2147483647 " } */
|
|
244 }
|
|
245
|
|
246 {
|
|
247 /* Verify that enums are correctly handled. */
|
|
248 enum PrecEnum { e9 = 9, e17 = 17 };
|
|
249 enum PrecEnum p = V (enum PrecEnum);
|
|
250 if (p < e9 || e17 < p)
|
|
251 p = e9;
|
|
252
|
|
253 T ("%.*u", p, V (int)); /* { dg-warning "between 9 and 17 " } */
|
|
254 }
|
|
255 }
|