Merge dmd upstream e2fe2687b
[official-gcc.git] / gcc / testsuite / gdc.test / compilable / testVRP.d
blob954b5019b832aa9f2f01b1296e36d6a7e8a3ac2d
1 // PERMUTE_ARGS: -O -inline
3 // Test value-range propagation.
4 // https://issues.dlang.org/show_bug.cgi?id=3147
5 // https://issues.dlang.org/show_bug.cgi?id=6000
6 // https://issues.dlang.org/show_bug.cgi?id=5225
8 void add()
10 byte x, y;
11 short a = x + y;
14 void leftShift()
16 byte x, y;
17 short z = x << 1;
20 void leftShiftFail()
23 ubyte x, y;
24 ushort z;
25 static assert(!__traits(compiles, z = x << y));
26 // 1 << 31 surely overflows the range of 'ushort'.
29 ulong a, b;
30 int res;
31 static assert(!__traits(compiles, res = a << (b % 65U)));
35 void rightShiftFail()
38 short x;
39 byte y, z;
40 static assert(!__traits(compiles, z = x >> y));
41 // [this passes in 2.053.]
44 ulong a, b;
45 int res;
46 static assert(!__traits(compiles, res = a >> (b % 65U)));
50 void rightShift()
52 ushort x;
53 ubyte y = x >> 16;
56 void unsignedRightShiftFail()
58 int x;
59 ubyte y;
60 static assert(!__traits(compiles, y = x >>> 2));
61 // [this passes in 2.053.]
64 void subtract()
66 ubyte x, y;
67 short z = x - y;
70 void multiply()
72 byte x, y;
73 short z = x * y;
76 void subMulFail()
78 ubyte x, y;
79 ubyte z;
80 static assert(!__traits(compiles, z = x - y));
81 static assert(!__traits(compiles, z = x * y));
82 // [these pass in 2.053.]
85 void multiplyNeg1()
87 byte b;
88 b = -1 + (b * -1);
89 static assert(!__traits(compiles, b = -1 + b * ulong.max));
92 void divide()
94 short w;
95 byte y = w / 300;
98 void divideFail()
100 short w;
101 byte y;
102 static assert(!__traits(compiles, y = w / -1));
105 void plus1Fail()
107 byte u, v;
108 static assert(!__traits(compiles, v = u + 1));
109 // [these pass in 2.053.]
112 void modulus()
114 int x;
115 byte u = x % 128;
118 void modulus_bug6000a()
120 ulong t;
121 uint u = t % 16;
124 void modulus_bug6000b()
126 long n = 10520;
127 ubyte b;
128 static assert(!__traits(compiles, b = n % 10));
131 void modulus2()
133 short s;
134 byte b = byte.max;
135 byte c = s % b;
138 void modulus3()
140 int i;
141 short s = short.max;
142 short t = i % s;
145 void modulus4()
147 uint i;
148 ushort s;
149 short t;
150 static assert(!__traits(compiles, t = i % s));
153 void modulus5()
155 short a;
156 byte foo = (a - short.max - 1) % 127;
159 void modulusFail()
161 int i;
162 short s;
163 byte b;
164 static assert(!__traits(compiles, b = i % s));
165 static assert(!__traits(compiles, b = i % 257));
166 // [these pass in 2.053.]
169 void bitwise()
171 ubyte a, b, c;
172 uint d;
173 c = a & b;
174 c = a | b;
175 c = a ^ b;
176 c = d & 0xff;
177 // [these pass in 2.053.]
180 void bitAnd()
182 byte c;
183 int d;
184 c = (0x3ff_ffffU << (0&c)) & (0x4000_0000U << (0&c));
185 // the result of the above is always 0 :).
188 void bitAndTest()
191 ushort a, b;
192 byte res = ((a % 7) - 6) & ((b % 7) - 6);
195 // rhs[-128..127] outside range of lhs[0..255]
196 // -> calls byte.implicitConvTo(ubyte) => MATCH.convert
197 byte a, b;
198 ubyte res;
200 res = cast(byte)(a + 5) & b;
201 res = cast(byte)(a - 5) & b;
202 res = cast(byte)(a / 5) & b;
203 res = cast(byte)(a * 5) & b;
204 res = cast(byte)(a % 5) & b;
208 void bitOrFail()
211 ubyte c;
212 static assert(!__traits(compiles, c = c | 0x100));
213 // [this passes in 2.053.]
216 byte a, b;
217 ubyte res;
219 static assert(!__traits(compiles, res = (a + 5) | b)); // [-128..255]
220 static assert(!__traits(compiles, res = (a - 5) | b)); // [-133..127]
221 static assert(!__traits(compiles, res = (a / 5) | b)); // [-128..127]
222 static assert(!__traits(compiles, res = (a * 5) | b)); // [-640..639]
223 static assert(!__traits(compiles, res = (a % 5) | b)); // [-128..127]
227 void bitAndOr()
229 ubyte c;
230 c = (c | 0x1000) & ~0x1000;
233 void bitOrTest()
236 // Tests condition for different signs between min & max
237 // ((imin.negative ^ imax.negative) == 1 && (rhs.imin.negative ^ rhs.imax.negative) == 1
238 ushort a, b;
239 byte res = ((a % 127) - 126) | ((b % 6) - 5);
242 // rhs[-128..127] outside range of lhs[0..255]
243 // -> calls byte.implicitConvTo(ubyte) => MATCH.convert
244 byte a, b, c;
245 ubyte res;
247 res = cast(byte)(a + 5) | b;
248 res = cast(byte)(a - 5) | b;
249 res = cast(byte)(a / 5) | b;
250 res = cast(byte)(a * 5) | b;
251 res = cast(byte)(a % 5) | b;
255 void bitAndFail()
258 int d;
259 short s;
260 byte c;
261 static assert(!__traits(compiles, c = d & s));
262 static assert(!__traits(compiles, c = d & 256));
263 // [these pass in 2.053.]
266 byte a, b;
267 ubyte res;
269 static assert(!__traits(compiles, res = (a + 5) & b)); // [-128..132]
270 static assert(!__traits(compiles, res = (a - 5) & b)); // [-256..127]
271 static assert(!__traits(compiles, res = (a / 5) & b)); // [-128..127]
272 static assert(!__traits(compiles, res = (a * 5) & b)); // [-640..635]
273 static assert(!__traits(compiles, res = (a % 5) & b)); // [-128..127]
277 void bitXor()
280 ushort s;
281 ubyte c;
282 c = (0xffff << (s & 0)) ^ 0xff00;
285 // rhs[-128..127] outside range of lhs[0..255]
286 // -> calls byte.implicitConvTo(ubyte) => MATCH.convert
287 byte a, b, c;
288 ubyte res;
290 res = cast(byte)(a + 5) ^ b;
291 res = cast(byte)(a - 5) ^ b;
292 res = cast(byte)(a / 5) ^ b;
293 res = cast(byte)(a * 5) ^ b;
294 res = cast(byte)(a % 5) ^ b;
298 void bitXorFail()
301 byte a, b;
302 ubyte res;
304 static assert(!__traits(compiles, res = (a + 5) ^ b)); // [-256..255]
305 static assert(!__traits(compiles, res = (a - 5) ^ b)); // [-256..255]
306 static assert(!__traits(compiles, res = (a / 5) ^ b)); // [-128..127]
307 static assert(!__traits(compiles, res = (a * 5) ^ b)); // [-640..1023]
308 static assert(!__traits(compiles, res = (a % 5) ^ b)); // [-128..127]
312 void bitComplement()
314 int i;
315 ubyte b = ~(i | ~0xff);
318 void bitComplementFail()
320 ubyte b;
321 static assert(!__traits(compiles, b = ~(b | 1)));
322 // [this passes in 2.053.]
325 void negation()
327 int x;
328 byte b = -(x & 0x7);
331 void negationFail()
333 int x;
334 byte b;
335 static assert(!__traits(compiles, b = -(x & 255)));
336 // [this passes in 2.053.]
339 short bug5225(short a) {
340 return a>>1;
343 short bug1977_comment5(byte i) {
344 byte t = 1;
345 short o = t - i;
346 return o;
349 void testDchar()
351 dchar d;
352 uint i;
354 static assert(!__traits(compiles, d = i));
355 static assert(!__traits(compiles, d = i & 0x1fffff));
357 d = i % 0x110000;
360 void bug1977_comment11()
362 uint a;
363 byte b = a & 1;
364 // [this passes in 2.053.]
367 void bug1977_comment20()
369 long a;
370 int b = a % 1000;
373 /******************************************/
374 // 9617
376 void test9617()
378 void f1(int) {}
379 void f2(short) {}
380 void f3(byte) {}
382 // Why these calls are accepted?
383 static assert(!__traits(compiles, f1(ulong.max)));
384 static assert(!__traits(compiles, f2(ulong.max)));
385 static assert(!__traits(compiles, f3(ulong.max)));
387 // But, if argument is not constant value, compilation fails.
388 ulong x;
389 static assert(!__traits(compiles, f1(x))); // is not callable using argument types (ulong)
390 static assert(!__traits(compiles, f2(x))); // is not callable using argument types (ulong)
391 static assert(!__traits(compiles, f3(x))); // is not callable using argument types (ulong)
393 void f4(uint) {}
394 void f5(ushort) {}
395 void f6(ubyte) {}
397 // If parameter type is unsigned, it is collectly rejected
398 static assert(!__traits(compiles, f4(ulong.max))); // is not callable using argument types (ulong)
399 static assert(!__traits(compiles, f5(ulong.max))); // is not callable using argument types (ulong)
400 static assert(!__traits(compiles, f6(ulong.max))); // is not callable using argument types (ulong)
403 //import std.typetuple;
404 template TypeTuple(T...) { alias TypeTuple = T; }
405 template staticIota(size_t end)
407 static if (0 < end)
408 alias staticIota = TypeTuple!(staticIota!(end - 1), end - 1);
409 else
410 alias staticIota = TypeTuple!();
412 void test9617a()
414 alias Repr = TypeTuple!(
415 byte, "127", // T and literal representation of T.max
416 ubyte, "255",
417 short, "32767",
418 ushort, "65535",
419 int, "2147483647",
420 uint, "4294967295",
421 long, "9223372036854775807",
422 ulong, "18446744073709551615" // "" or "L" -> "signed integral overflow"
424 alias Indices = staticIota!(Repr.length / 2);
426 foreach (t; Indices)
428 alias T = Repr[t * 2];
429 void func(T)(T) {}
430 alias func!T f;
432 foreach (r; Indices)
434 alias S = Repr[r * 2];
435 S src = S.max;
437 enum x = Repr[r * 2 + 1];
438 foreach (repr; TypeTuple!(S.stringof~".max", x~"", x~"U", x~"L", x~"LU"))
440 static if (S.sizeof != T.sizeof)
441 static if (is(typeof(mixin(repr)) R))
443 // "Compilable" test should be equal, even if
444 // the given argument is either constant or runtime variable.
445 enum ct = __traits(compiles, f( mixin(repr) ));
446 enum rt = __traits(compiles, f( src ));
448 static assert(ct == rt);
449 //import std.string;
450 //enum msg = format("%6s.max to %-6s variable/constant = %d/%d, constant_repr = (%s) %s",
451 // S.stringof, T.stringof, rt, ct, R.stringof, repr);
452 //static if (ct != rt) pragma(msg, msg);
459 void test10018(ubyte value)
461 const int c = value;
462 ubyte b = c;
463 static assert(!__traits(compiles, b = c - 1));
464 static assert(!__traits(compiles, b = c + 1));
465 immutable int i = value;
466 b = i;
467 static assert(!__traits(compiles, b = i - 1));
468 static assert(!__traits(compiles, b = i + 1));
471 void test13001(bool unknown)
473 foreach (const i; 0..unknown?2:3)
475 ubyte b = i;
476 static assert(!__traits(compiles, b = i - 1));
477 b = i + 253;
478 static assert(!__traits(compiles, b = i + 254));
482 void test10310()
484 int y;
485 ubyte x = ((y & 252) ^ 2) + 1;
488 // https://issues.dlang.org/show_bug.cgi?id=15289
489 void test15289a()
491 int [] arr = [1, 2, 3, 4];
492 uint foo = 50 / arr.length;
495 void test15289b()
497 int [] arr = [1, 2, 3, 4];
498 uint foo = 50 % arr.length;
501 void testShiftRightOnNegative()
503 int neg = -1;
504 uint[] arr = [1, 2, 3];
505 ubyte b;
506 // Shift with negative value returns value in range [0, ulong.max]
507 static assert(!__traits(compiles, b = arr.length >> neg));
508 static assert(!__traits(compiles, b = arr.length << neg));