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 /******************************************/
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));