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
25 static assert(!__traits(compiles, z = x << y));
26 // 1 << 31 surely overflows the range of 'ushort'.
31 static assert(!__traits(compiles, res = a << (b % 65U)));
40 static assert(!__traits(compiles, z = x >> y));
41 // [this passes in 2.053.]
46 static assert(!__traits(compiles, res = a >> (b % 65U)));
56 void unsignedRightShiftFail()
60 static assert(!__traits(compiles, y = x >>> 2));
61 // [this passes in 2.053.]
80 static assert(!__traits(compiles, z = x - y));
81 static assert(!__traits(compiles, z = x * y));
82 // [these pass in 2.053.]
89 static assert(!__traits(compiles, b = -1 + b * ulong.max));
102 static assert(!__traits(compiles, y = w / -1));
108 static assert(!__traits(compiles, v = u + 1));
109 // [these pass in 2.053.]
118 void modulus_bug6000a()
124 void modulus_bug6000b()
128 static assert(!__traits(compiles, b = n % 10));
150 static assert(!__traits(compiles, t = i % s));
156 byte foo = (a - short.max - 1) % 127;
164 static assert(!__traits(compiles, b = i % s));
165 static assert(!__traits(compiles, b = i % 257));
166 // [these pass in 2.053.]
177 // [these pass in 2.053.]
184 c = (0x3ff_ffffU << (0&c)) & (0x4000_0000U << (0&c));
185 // the result of the above is always 0 :).
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
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;
212 static assert(!__traits(compiles, c = c | 0x100));
213 // [this passes in 2.053.]
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]
230 c = (c | 0x1000) & ~0x1000;
236 // Tests condition for different signs between min & max
237 // ((imin.negative ^ imax.negative) == 1 && (rhs.imin.negative ^ rhs.imax.negative) == 1
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
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;
261 static assert(!__traits(compiles, c = d & s));
262 static assert(!__traits(compiles, c = d & 256));
263 // [these pass in 2.053.]
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]
282 c = (0xffff << (s & 0)) ^ 0xff00;
285 // rhs[-128..127] outside range of lhs[0..255]
286 // -> calls byte.implicitConvTo(ubyte) => MATCH.convert
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;
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]
315 ubyte b = ~(i | ~0xff);
318 void bitComplementFail()
321 static assert(!__traits(compiles, b = ~(b | 1)));
322 // [this passes in 2.053.]
335 static assert(!__traits(compiles, b = -(x & 255)));
336 // [this passes in 2.053.]
339 short bug5225(short a) {
343 short bug1977_comment5(byte i) {
354 static assert(!__traits(compiles, d = i));
355 static assert(!__traits(compiles, d = i & 0x1fffff));
360 void bug1977_comment11()
364 // [this passes in 2.053.]
367 void bug1977_comment20()
373 /******************************************/
374 // https://issues.dlang.org/show_bug.cgi?id=9617
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.
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)
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)
408 alias staticIota = TypeTuple!(staticIota!(end - 1), end - 1);
410 alias staticIota = TypeTuple!();
414 alias Repr = TypeTuple!(
415 byte, "127", // T and literal representation of T.max
421 long, "9223372036854775807",
422 ulong, "18446744073709551615" // "" or "L" -> "signed integral overflow"
424 alias Indices = staticIota!(Repr.length / 2);
428 alias T = Repr[t * 2];
434 alias S = Repr[r * 2];
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);
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)
463 static assert(!__traits(compiles, b = c - 1));
464 static assert(!__traits(compiles, b = c + 1));
465 immutable int i = value;
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)
476 static assert(!__traits(compiles, b = i - 1));
478 static assert(!__traits(compiles, b = i + 254));
485 ubyte x = ((y & 252) ^ 2) + 1;
488 // https://issues.dlang.org/show_bug.cgi?id=15289
491 int [] arr = [1, 2, 3, 4];
492 uint foo = 50 / arr.length;
497 int [] arr = [1, 2, 3, 4];
498 uint foo = 50 % arr.length;
501 void testShiftRightOnNegative()
504 uint[] arr = [1, 2, 3];
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));