]>
Commit | Line | Data |
---|---|---|
3812f460 MS |
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 | |
7c8a416d MS |
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); | |
3812f460 MS |
140 | if (w < 5 || (unsigned)-1 - 7 < w) |
141 | w = 5; | |
7c8a416d | 142 | int val = V (int); |
3812f460 | 143 | |
7c8a416d | 144 | T ("%*u", (int)w, val); /* { dg-warning "between 1 and 2147483648 " } */ |
3812f460 MS |
145 | } |
146 | ||
147 | { | |
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; | |
155 | ||
156 | T ("%*hu", w, V (int)); /* { dg-warning "between 7 and 9 " } */ | |
157 | } | |
158 | } | |
159 | ||
160 | void test_precision_cst (void) | |
161 | { | |
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 " } */ | |
164 | ||
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 " } */ | |
167 | ||
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 " } */ | |
170 | ||
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 } */ | |
176 | ||
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 } */ | |
181 | ||
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 } */ | |
186 | ||
187 | { | |
188 | extern sint128_t si128; | |
189 | if (si128 < sint128_max / 2 || sint128_max - 8 < si128) | |
190 | si128 = sint128_max / 2; | |
191 | ||
192 | T ("%.*i", si128, 0); /* { dg-warning "up to 2147483647 " } */ | |
193 | /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ | |
194 | ||
195 | extern uint128_t ui128; | |
196 | if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128) | |
197 | ui128 = uint128_max / 2; | |
198 | ||
199 | T ("%.*i", ui128, 0); /* { dg-warning "up to 2147483647 " } */ | |
200 | /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ | |
201 | } | |
202 | ||
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 } */ | |
207 | } | |
208 | ||
209 | void test_precision_var (void) | |
210 | { | |
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 " } */ | |
213 | ||
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 " } */ | |
216 | ||
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 " } */ | |
219 | ||
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 } */ | |
225 | ||
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 } */ | |
230 | ||
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 } */ | |
235 | ||
236 | { | |
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 | |
7c8a416d MS |
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); | |
3812f460 MS |
244 | if (p < 7 || (unsigned)-1 - 9 < p) |
245 | p = 7; | |
246 | ||
7c8a416d MS |
247 | int val = V (int); |
248 | ||
249 | T ("%.*u", (int)p, val); /* { dg-warning "up to 2147483647 " } */ | |
3812f460 MS |
250 | } |
251 | ||
252 | { | |
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; | |
258 | ||
259 | T ("%.*u", p, V (int)); /* { dg-warning "between 9 and 17 " } */ | |
260 | } | |
261 | } |