mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
2657 lines
52 KiB
D
2657 lines
52 KiB
D
/*
|
|
REQUIRED_ARGS: -mcpu=native
|
|
PERMUTE_ARGS: -O -inline -release
|
|
*/
|
|
|
|
import core.stdc.stdio;
|
|
|
|
template tuple(A...) { alias tuple = A; }
|
|
|
|
///////////////////////
|
|
|
|
// https://github.com/dlang/dmd/pull/11441
|
|
|
|
long sdiv1(long l)
|
|
{
|
|
return l / 2;
|
|
}
|
|
|
|
int sdiv2(int i)
|
|
{
|
|
return i / 2;
|
|
}
|
|
|
|
void testsdiv2()
|
|
{
|
|
assert(sdiv1(10) == 5);
|
|
assert(sdiv1(-10) == -5);
|
|
assert(sdiv2(10) == 5);
|
|
assert(sdiv2(-10) == -5);
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
void testulldiv()
|
|
{
|
|
__gshared ulong[4][] vectors =
|
|
[
|
|
[10,3,3,1],
|
|
[10,1,10,0],
|
|
[3,10,0,3],
|
|
[10,10,1,0],
|
|
[10_000_000_000L, 11_000_000_000L, 0, 10_000_000_000L],
|
|
[11_000_000_000L, 10_000_000_000L, 1, 1_000_000_000L],
|
|
[11_000_000_000L, 11_000_000_000L, 1, 0],
|
|
[10_000_000_000L, 10, 1_000_000_000L, 0],
|
|
[0x8000_0000_0000_0000, 0x8000_0000_0000_0000, 1, 0],
|
|
[0x8000_0000_0000_0001, 0x8000_0000_0000_0001, 1, 0],
|
|
[0x8000_0001_0000_0000, 0x8000_0001_0000_0000, 1, 0],
|
|
[0x8000_0001_0000_0000, 0x8000_0000_0000_0000, 1, 0x1_0000_0000],
|
|
[0x8000_0001_0000_0000, 0x8000_0000_8000_0000, 1, 0x8000_0000],
|
|
[0x8000_0000_0000_0000, 0x7FFF_FFFF_FFFF_FFFF, 1, 1],
|
|
[0x8000_0000_0000_0000, 0x8000_0000_0000_0001, 0, 0x8000_0000_0000_0000],
|
|
[0x8000_0000_0000_0000, 0x8000_0001_0000_0000, 0, 0x8000_0000_0000_0000],
|
|
];
|
|
|
|
for (size_t i = 0; i < vectors.length; i++)
|
|
{
|
|
ulong q = vectors[i][0] / vectors[i][1];
|
|
if (q != vectors[i][2])
|
|
printf("[%zd] %lld / %lld = %lld, should be %lld\n",
|
|
i, vectors[i][0], vectors[i][1], q, vectors[i][2]);
|
|
|
|
ulong r = vectors[i][0] % vectors[i][1];
|
|
if (r != vectors[i][3])
|
|
printf("[%zd] %lld %% %lld = %lld, should be %lld\n",
|
|
i, vectors[i][0], vectors[i][1], r, vectors[i][3]);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
uint udiv10(uint x)
|
|
{
|
|
return x / 10;
|
|
}
|
|
|
|
uint udiv14(uint x)
|
|
{
|
|
return x / 14;
|
|
}
|
|
|
|
uint udiv14007(uint x)
|
|
{
|
|
return x / 14007;
|
|
}
|
|
|
|
uint umod10(uint x)
|
|
{
|
|
return x % 10;
|
|
}
|
|
|
|
uint umod14(uint x)
|
|
{
|
|
return x % 14;
|
|
}
|
|
|
|
uint umod14007(uint x)
|
|
{
|
|
return x % 14007;
|
|
}
|
|
|
|
uint uremquo10(uint x)
|
|
{
|
|
return (x / 10) | (x % 10);
|
|
}
|
|
|
|
uint uremquo14(uint x)
|
|
{
|
|
return (x / 14) | (x % 14);
|
|
}
|
|
|
|
uint uremquo14007(uint x)
|
|
{
|
|
return (x / 14007) | (x % 14007);
|
|
}
|
|
|
|
|
|
|
|
ulong uldiv10(ulong x)
|
|
{
|
|
return x / 10;
|
|
}
|
|
|
|
ulong uldiv14(ulong x)
|
|
{
|
|
return x / 14;
|
|
}
|
|
|
|
ulong uldiv14007(ulong x)
|
|
{
|
|
return x / 14007;
|
|
}
|
|
|
|
ulong ulmod10(ulong x)
|
|
{
|
|
return x % 10;
|
|
}
|
|
|
|
ulong ulmod14(ulong x)
|
|
{
|
|
return x % 14;
|
|
}
|
|
|
|
ulong ulmod14007(ulong x)
|
|
{
|
|
return x % 14007;
|
|
}
|
|
|
|
ulong ulremquo10(ulong x)
|
|
{
|
|
return (x / 10) | (x % 10);
|
|
}
|
|
|
|
ulong ulremquo14(ulong x)
|
|
{
|
|
return (x / 14) | (x % 14);
|
|
}
|
|
|
|
ulong ulremquo14007(ulong x)
|
|
{
|
|
return (x / 14007) | (x % 14007);
|
|
}
|
|
|
|
|
|
void testfastudiv()
|
|
{
|
|
{
|
|
static uint x10 = 10;
|
|
static uint x14 = 14;
|
|
static uint x14007 = 14007;
|
|
|
|
uint u = 10000;
|
|
uint r;
|
|
r = udiv10(u); assert(r == u/x10);
|
|
r = udiv14(u); assert(r == u/x14);
|
|
r = udiv14007(u); assert(r == u/x14007);
|
|
r = umod10(u); assert(r == u%x10);
|
|
r = umod14(u); assert(r == u%x14);
|
|
r = umod14007(u); assert(r == u%x14007);
|
|
r = uremquo10(u); assert(r == ((u/10)|(u%x10)));
|
|
r = uremquo14(u); assert(r == ((u/14)|(u%x14)));
|
|
r = uremquo14007(u); assert(r == ((u/14007)|(u%x14007)));
|
|
}
|
|
{
|
|
static ulong y10 = 10;
|
|
static ulong y14 = 14;
|
|
static ulong y14007 = 14007;
|
|
|
|
ulong u = 10000;
|
|
ulong r;
|
|
r = uldiv10(u); assert(r == u/y10);
|
|
r = uldiv14(u); assert(r == u/y14);
|
|
r = uldiv14007(u); assert(r == u/y14007);
|
|
r = ulmod10(u); assert(r == u%y10);
|
|
r = ulmod14(u); assert(r == u%y14);
|
|
r = ulmod14007(u); assert(r == u%y14007);
|
|
r = ulremquo10(u); assert(r == ((u/10)|(u%y10)));
|
|
r = ulremquo14(u); assert(r == ((u/14)|(u%y14)));
|
|
r = ulremquo14007(u); assert(r == ((u/14007)|(u%y14007)));
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=14936
|
|
|
|
long sldiv1 (long x) { return x / (1L << 1); }
|
|
long sldiv2 (long x) { return x / (1L << 2); }
|
|
long sldiv3 (long x) { return x / (1L << 3); }
|
|
long sldiv7 (long x) { return x / (1L << 7); }
|
|
long sldiv8 (long x) { return x / (1L << 8); }
|
|
long sldiv9 (long x) { return x / (1L << 9); }
|
|
long sldiv30(long x) { return x / (1L << 30); }
|
|
long sldiv31(long x) { return x / (1L << 31); }
|
|
long sldiv32(long x) { return x / (1L << 32); }
|
|
long sldiv33(long x) { return x / (1L << 33); }
|
|
long sldiv34(long x) { return x / (1L << 34); }
|
|
long sldiv62(long x) { return x / (1L << 62); }
|
|
long sldiv63(long x) { return x / (1L << 63); }
|
|
|
|
void testsldiv()
|
|
{
|
|
/* Test special div code for signed long divide
|
|
* by power of 2 for 32 bit targets.
|
|
*/
|
|
|
|
// printf("63 = %llx\n", sldiv63(-0x7FFF_F8FF_FF3F_2FFFL));
|
|
|
|
static foreach (C; tuple!(
|
|
1,2,3,10,300,1000,
|
|
4_1001_2030_0030,
|
|
0x7FFF_F8FF_FF3F_2FFFL))
|
|
{
|
|
/* Check if runtime computation matches compile time
|
|
*/
|
|
assert(sldiv1 ( C) == C / (1L << 1));
|
|
assert(sldiv1 (-C) == -C / (1L << 1));
|
|
assert(sldiv2 ( C) == C / (1L << 2));
|
|
assert(sldiv2 (-C) == -C / (1L << 2));
|
|
assert(sldiv3 ( C) == C / (1L << 3));
|
|
assert(sldiv3 (-C) == -C / (1L << 3));
|
|
assert(sldiv7 ( C) == C / (1L << 7));
|
|
assert(sldiv7 (-C) == -C / (1L << 7));
|
|
assert(sldiv8 ( C) == C / (1L << 8));
|
|
assert(sldiv8 (-C) == -C / (1L << 8));
|
|
assert(sldiv9 ( C) == C / (1L << 9));
|
|
assert(sldiv9 (-C) == -C / (1L << 9));
|
|
|
|
assert(sldiv30( C) == C / (1L << 30));
|
|
assert(sldiv30(-C) == -C / (1L << 30));
|
|
assert(sldiv31( C) == C / (1L << 31));
|
|
assert(sldiv31(-C) == -C / (1L << 31));
|
|
assert(sldiv32( C) == C / (1L << 32));
|
|
assert(sldiv32(-C) == -C / (1L << 32));
|
|
assert(sldiv33( C) == C / (1L << 33));
|
|
assert(sldiv33(-C) == -C / (1L << 33));
|
|
assert(sldiv34( C) == C / (1L << 34));
|
|
assert(sldiv34(-C) == -C / (1L << 34));
|
|
assert(sldiv62( C) == C / (1L << 62));
|
|
assert(sldiv62(-C) == -C / (1L << 62));
|
|
assert(sldiv63( C) == C / (1L << 63));
|
|
assert(sldiv63(-C) == -C / (1L << 63));
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=14936
|
|
|
|
long slmod1 (long x) { return x % (1L << 1); }
|
|
long slmod2 (long x) { return x % (1L << 2); }
|
|
long slmod3 (long x) { return x % (1L << 3); }
|
|
long slmod7 (long x) { return x % (1L << 7); }
|
|
long slmod8 (long x) { return x % (1L << 8); }
|
|
long slmod9 (long x) { return x % (1L << 9); }
|
|
long slmod30(long x) { return x % (1L << 30); }
|
|
long slmod31(long x) { return x % (1L << 31); }
|
|
long slmod32(long x) { return x % (1L << 32); }
|
|
long slmod33(long x) { return x % (1L << 33); }
|
|
long slmod34(long x) { return x % (1L << 34); }
|
|
long slmod62(long x) { return x % (1L << 62); }
|
|
long slmod63(long x) { return x % (1L << 63); }
|
|
|
|
void testslmod()
|
|
{
|
|
static foreach (C; tuple!(
|
|
1,2,3,10,300,1000,
|
|
4_1001_2030_0030,
|
|
0x7FFF_F8FF_FF3F_2FFFL))
|
|
{
|
|
/* Check if runtime computation matches compile time
|
|
*/
|
|
assert(slmod1 ( C) == C % (1L << 1));
|
|
assert(slmod1 (-C) == -C % (1L << 1));
|
|
assert(slmod2 ( C) == C % (1L << 2));
|
|
assert(slmod2 (-C) == -C % (1L << 2));
|
|
assert(slmod3 ( C) == C % (1L << 3));
|
|
assert(slmod3 (-C) == -C % (1L << 3));
|
|
assert(slmod7 ( C) == C % (1L << 7));
|
|
assert(slmod7 (-C) == -C % (1L << 7));
|
|
assert(slmod8 ( C) == C % (1L << 8));
|
|
assert(slmod8 (-C) == -C % (1L << 8));
|
|
assert(slmod9 ( C) == C % (1L << 9));
|
|
assert(slmod9 (-C) == -C % (1L << 9));
|
|
|
|
assert(slmod30( C) == C % (1L << 30));
|
|
assert(slmod30(-C) == -C % (1L << 30));
|
|
assert(slmod31( C) == C % (1L << 31));
|
|
assert(slmod31(-C) == -C % (1L << 31));
|
|
assert(slmod32( C) == C % (1L << 32));
|
|
assert(slmod32(-C) == -C % (1L << 32));
|
|
assert(slmod33( C) == C % (1L << 33));
|
|
assert(slmod33(-C) == -C % (1L << 33));
|
|
assert(slmod34( C) == C % (1L << 34));
|
|
assert(slmod34(-C) == -C % (1L << 34));
|
|
assert(slmod62( C) == C % (1L << 62));
|
|
assert(slmod62(-C) == -C % (1L << 62));
|
|
assert(slmod63( C) == C % (1L << 63));
|
|
assert(slmod63(-C) == -C % (1L << 63));
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
T divC(int C, T)(T x)
|
|
{
|
|
T y = x;
|
|
y /= C;
|
|
assert(y == x / C);
|
|
y = x;
|
|
y /= -C;
|
|
assert(y == x / -C);
|
|
return x / C;
|
|
}
|
|
|
|
T modC(int C, T)(T x)
|
|
{
|
|
T y = x;
|
|
y %= C;
|
|
assert(y == x % C);
|
|
y = x;
|
|
y %= -C;
|
|
assert(y == x % -C);
|
|
return x % C;
|
|
}
|
|
|
|
T remquoC(int C, T)(T x)
|
|
{
|
|
return (x / C) | (x % C);
|
|
}
|
|
|
|
void testfastdiv()
|
|
{
|
|
static int z = 0; // prevent constant folding by optimizer
|
|
|
|
static foreach (T; tuple!(int, long, uint, ulong))
|
|
{{
|
|
T u = 10000;
|
|
T r;
|
|
static foreach (C; tuple!(10, 14, 14007, -10, -14, -14007))
|
|
{
|
|
r = divC!C(u); assert(r == u / (z + C));
|
|
r = modC!C(u); assert(r == u % (z + C));
|
|
r = remquoC!C(u); assert(r == ((u / (z + C) | (u % (z + C)))));
|
|
}
|
|
}}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/* Test the pattern:
|
|
* replace ((i / C1) / C2) with (i / (C1 * C2))
|
|
* when e1 is 0 or 1 and (i2-i1) is a power of 2.
|
|
*/
|
|
|
|
void divdiv(T, T C1, T C2)(T i)
|
|
{
|
|
auto a = (i / C1) / C2;
|
|
auto b = i / (C1 * C2);
|
|
if (a != b) assert(0);
|
|
}
|
|
|
|
void testdivdiv()
|
|
{
|
|
divdiv!(int,10,20)(30);
|
|
divdiv!(uint,10,20)(30);
|
|
divdiv!(long,10,20)(30);
|
|
divdiv!(ulong,10,20)(30);
|
|
|
|
divdiv!(int,-10,20)(30);
|
|
divdiv!(long,-10,20)(30);
|
|
|
|
divdiv!(int,-10,-20)(-30);
|
|
divdiv!(long,-10,-20)(-30);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void testdivcmp()
|
|
{
|
|
// https://github.com/dlang/dmd/pull/7128
|
|
static bool foo(uint a, uint b)
|
|
{
|
|
return cast(bool)(a / b); // convert / to >=
|
|
}
|
|
|
|
assert(!foo(3, 4));
|
|
assert(foo(4, 4));
|
|
assert(foo(5, 4));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
void testgoto()
|
|
{
|
|
int i;
|
|
|
|
i = 3;
|
|
goto L4;
|
|
L3: i++;
|
|
goto L5;
|
|
L4: goto L3;
|
|
L5: assert(i == 4);
|
|
}
|
|
|
|
int testswitch()
|
|
{
|
|
int i;
|
|
|
|
i = 3;
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
default:
|
|
assert(0);
|
|
case 3:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void testdo()
|
|
{
|
|
int x = 0;
|
|
|
|
do
|
|
{
|
|
x++;
|
|
} while (x < 10);
|
|
printf("x == %d\n", x);
|
|
assert(x == 10);
|
|
}
|
|
|
|
|
|
void testbreak()
|
|
{ int i, j;
|
|
|
|
Louter:
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
for (j = 0; j < 10; j++)
|
|
{
|
|
if (j == 3)
|
|
break Louter;
|
|
}
|
|
}
|
|
|
|
printf("i = %d, j = %d\n", i, j);
|
|
assert(i == 0);
|
|
assert(j == 3);
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
int foo(string s)
|
|
{
|
|
int i;
|
|
|
|
i = 0;
|
|
switch (s)
|
|
{
|
|
case "hello":
|
|
i = 1;
|
|
break;
|
|
case "goodbye":
|
|
i = 2;
|
|
break;
|
|
case "goodb":
|
|
i = 3;
|
|
break;
|
|
default:
|
|
i = 10;
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
|
|
void teststringswitch()
|
|
{ int i;
|
|
|
|
i = foo("hello");
|
|
printf("i = %d\n", i);
|
|
assert(i == 1);
|
|
|
|
i = foo("goodbye");
|
|
printf("i = %d\n", i);
|
|
assert(i == 2);
|
|
|
|
i = foo("goodb");
|
|
printf("i = %d\n", i);
|
|
assert(i == 3);
|
|
|
|
i = foo("huzzah");
|
|
printf("i = %d\n", i);
|
|
assert(i == 10);
|
|
}
|
|
|
|
|
|
///////////////////////
|
|
|
|
struct Foo
|
|
{
|
|
int a;
|
|
char b;
|
|
long c;
|
|
}
|
|
|
|
Foo test(Foo f)
|
|
{
|
|
f.a += 1;
|
|
f.b += 3;
|
|
f.c += 4;
|
|
return f;
|
|
}
|
|
|
|
|
|
void teststrarg()
|
|
{
|
|
Foo g;
|
|
g.a = 1;
|
|
g.b = 2;
|
|
g.c = 3;
|
|
|
|
Foo q;
|
|
q = test(g);
|
|
assert(q.a == 2);
|
|
assert(q.b == 5);
|
|
assert(q.c == 7);
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
align (1) struct Foo1
|
|
{
|
|
align (1):
|
|
int a;
|
|
char b;
|
|
long c;
|
|
}
|
|
|
|
struct Foo2
|
|
{
|
|
int a;
|
|
char b;
|
|
long c;
|
|
}
|
|
|
|
struct Foo3
|
|
{
|
|
int a;
|
|
align (1) char b;
|
|
long c;
|
|
}
|
|
|
|
struct Foo4
|
|
{
|
|
int a;
|
|
struct { char b; }
|
|
long c;
|
|
}
|
|
|
|
void testsizes()
|
|
{
|
|
printf("%zd\n", Foo1.sizeof);
|
|
assert(Foo1.a.offsetof == 0);
|
|
assert(Foo1.b.offsetof == 4);
|
|
assert(Foo1.c.offsetof == 5);
|
|
assert(Foo1.sizeof == 13);
|
|
|
|
assert(Foo2.a.offsetof == 0);
|
|
assert(Foo2.b.offsetof == 4);
|
|
assert(Foo2.c.offsetof == 8);
|
|
assert(Foo2.sizeof == 16);
|
|
|
|
assert(Foo3.a.offsetof == 0);
|
|
assert(Foo3.b.offsetof == 4);
|
|
assert(Foo3.c.offsetof == 8);
|
|
assert(Foo3.b.sizeof == 1);
|
|
assert(Foo3.sizeof == 16);
|
|
|
|
assert(Foo4.sizeof == 16);
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
size_t cond11565(size_t val)
|
|
{
|
|
return val ? size_t.max : 0;
|
|
}
|
|
|
|
void test11565()
|
|
{
|
|
assert(cond11565(true) == size_t.max);
|
|
}
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=23743
|
|
void test23743()
|
|
{
|
|
ubyte[] a = [1];
|
|
foreach (x; a)
|
|
{
|
|
ubyte v = x >= 1 ? 255 : 0;
|
|
assert(v == 255);
|
|
}
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
int[3] array1 = [1:1,2,0:3];
|
|
|
|
void testarrayinit()
|
|
{
|
|
assert(array1[0] == 3);
|
|
assert(array1[1] == 1);
|
|
assert(array1[2] == 2);
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
void test13023(ulong n)
|
|
{
|
|
static void func(bool b) {}
|
|
|
|
ulong k = 0;
|
|
|
|
func(k >= n / 2);
|
|
|
|
if (k >= n / 2)
|
|
assert(0);
|
|
}
|
|
|
|
///////////////////////
|
|
|
|
struct U { int a; union { char c; int d; } long b; }
|
|
|
|
U f = { b:3, d:0x22222222, a:1 };
|
|
|
|
void testU()
|
|
{
|
|
assert(f.b == 3);
|
|
assert(f.d == 0x22222222);
|
|
assert(f.c == 0x22);
|
|
assert(f.a == 1);
|
|
assert(f.sizeof == 16);
|
|
assert(U.sizeof == 16);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void vfunc() {}
|
|
|
|
void test12095(int k)
|
|
{
|
|
int e = 0;
|
|
e ? k || assert(0) : !e || vfunc();
|
|
e ? k || assert(0) : e && vfunc();
|
|
!e ? !e || vfunc() : k || assert(0);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
bool test3918a( float t, real u )
|
|
{
|
|
printf("%Lf\n", u );
|
|
return t && u;
|
|
}
|
|
|
|
bool test3918b( real t, float u )
|
|
{
|
|
printf("%Lf\n", t );
|
|
return t && u;
|
|
}
|
|
|
|
void test3918()
|
|
{
|
|
assert(test3918a(float.nan, real.nan));
|
|
assert(test3918b(real.nan, float.nan));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
T docond1(T)(T l, ubyte thresh, ubyte val) {
|
|
l += (thresh < val);
|
|
return l;
|
|
}
|
|
|
|
T docond2(T)(T l, ubyte thresh, ubyte val) {
|
|
l -= (thresh >= val);
|
|
return l;
|
|
}
|
|
|
|
T docond3(T)(T l, ubyte thresh, ubyte val) {
|
|
l += (thresh >= val);
|
|
return l;
|
|
}
|
|
|
|
T docond4(T)(T l, ubyte thresh, ubyte val) {
|
|
l -= (thresh < val);
|
|
return l;
|
|
}
|
|
|
|
void testdocond()
|
|
{
|
|
assert(docond1!ubyte(10,3,5) == 11);
|
|
assert(docond1!ushort(10,3,5) == 11);
|
|
assert(docond1!uint(10,3,5) == 11);
|
|
assert(docond1!ulong(10,3,5) == 11);
|
|
|
|
assert(docond2!ubyte(10,3,5) == 10);
|
|
assert(docond2!ushort(10,3,5) == 10);
|
|
assert(docond2!uint(10,3,5) == 10);
|
|
assert(docond2!ulong(10,3,5) == 10);
|
|
|
|
assert(docond3!ubyte(10,3,5) == 10);
|
|
assert(docond3!ushort(10,3,5) == 10);
|
|
assert(docond3!uint(10,3,5) == 10);
|
|
assert(docond3!ulong(10,3,5) == 10);
|
|
|
|
assert(docond4!ubyte(10,3,5) == 9);
|
|
assert(docond4!ushort(10,3,5) == 9);
|
|
assert(docond4!uint(10,3,5) == 9);
|
|
assert(docond4!ulong(10,3,5) == 9);
|
|
|
|
|
|
assert(docond1!ubyte(10,5,3) == 10);
|
|
assert(docond1!ushort(10,5,3) == 10);
|
|
assert(docond1!uint(10,5,3) == 10);
|
|
assert(docond1!ulong(10,5,3) == 10);
|
|
|
|
assert(docond2!ubyte(10,5,3) == 9);
|
|
assert(docond2!ushort(10,5,3) == 9);
|
|
assert(docond2!uint(10,5,3) == 9);
|
|
assert(docond2!ulong(10,5,3) == 9);
|
|
|
|
assert(docond3!ubyte(10,5,3) == 11);
|
|
assert(docond3!ushort(10,5,3) == 11);
|
|
assert(docond3!uint(10,5,3) == 11);
|
|
assert(docond3!ulong(10,5,3) == 11);
|
|
|
|
assert(docond4!ubyte(10,5,3) == 10);
|
|
assert(docond4!ushort(10,5,3) == 10);
|
|
assert(docond4!uint(10,5,3) == 10);
|
|
assert(docond4!ulong(10,5,3) == 10);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct S8658
|
|
{
|
|
int[16385] a;
|
|
}
|
|
|
|
void foo8658(S8658 s)
|
|
{
|
|
int x;
|
|
}
|
|
|
|
void test8658()
|
|
{
|
|
S8658 s;
|
|
for(int i = 0; i < 1000; i++)
|
|
foo8658(s);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
uint neg(uint i)
|
|
{
|
|
return ~i + 1;
|
|
}
|
|
|
|
uint com(uint i)
|
|
{
|
|
return -i - 1;
|
|
}
|
|
|
|
float com(float i)
|
|
{
|
|
return -i - 1;
|
|
}
|
|
|
|
uint com2(uint i)
|
|
{
|
|
return -(i + 1);
|
|
}
|
|
|
|
void testnegcom()
|
|
{
|
|
assert(neg(3) == -3);
|
|
assert(com(3) == -4);
|
|
assert(com(3.0f) == -4.0f);
|
|
assert(com2(3) == -4);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int oror1(char c)
|
|
{
|
|
return ((((((((((cast(int) c <= 32 || cast(int) c == 46) || cast(int) c == 44)
|
|
|| cast(int) c == 58) || cast(int) c == 59) || cast(int) c == 60)
|
|
|| cast(int) c == 62) || cast(int) c == 34) || cast(int) c == 92)
|
|
|| cast(int) c == 39) != 0);
|
|
}
|
|
|
|
int oror2(char c)
|
|
{
|
|
return ((((((((((c <= 32 || c == 46) || c == 44)
|
|
|| c == 58) || c == 59) || c == 60)
|
|
|| c == 62) || c == 34) || c == 92)
|
|
|| c == 39) != 0);
|
|
}
|
|
|
|
void testoror()
|
|
{
|
|
assert(oror1(0) == 1);
|
|
assert(oror1(32) == 1);
|
|
assert(oror1(46) == 1);
|
|
assert(oror1(44) == 1);
|
|
assert(oror1(58) == 1);
|
|
assert(oror1(59) == 1);
|
|
assert(oror1(60) == 1);
|
|
assert(oror1(62) == 1);
|
|
assert(oror1(34) == 1);
|
|
assert(oror1(92) == 1);
|
|
assert(oror1(39) == 1);
|
|
assert(oror1(33) == 0);
|
|
assert(oror1(61) == 0);
|
|
assert(oror1(93) == 0);
|
|
assert(oror1(255) == 0);
|
|
|
|
assert(oror2(0) == 1);
|
|
assert(oror2(32) == 1);
|
|
assert(oror2(46) == 1);
|
|
assert(oror2(44) == 1);
|
|
assert(oror2(58) == 1);
|
|
assert(oror2(59) == 1);
|
|
assert(oror2(60) == 1);
|
|
assert(oror2(62) == 1);
|
|
assert(oror2(34) == 1);
|
|
assert(oror2(92) == 1);
|
|
assert(oror2(39) == 1);
|
|
assert(oror2(33) == 0);
|
|
assert(oror2(61) == 0);
|
|
assert(oror2(93) == 0);
|
|
assert(oror2(255) == 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
bool bt1(int p, int a, int b)
|
|
{
|
|
return p && ((1 << b) & a);
|
|
}
|
|
|
|
bool bt2(int p, long a, long b)
|
|
{
|
|
return p && ((1L << b) & a);
|
|
}
|
|
|
|
void testbt()
|
|
{
|
|
assert(bt1(1,7,2) == 1);
|
|
assert(bt1(1,7,3) == 0);
|
|
|
|
assert(bt2(1,0x7_0000_0000,2+32) == 1);
|
|
assert(bt2(1,0x7_0000_0000,3+32) == 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test13383()
|
|
{
|
|
foreach (k; 32..33)
|
|
{
|
|
if (1L & (1L << k))
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int andand1(int c)
|
|
{
|
|
return (c > 32 && c != 46 && c != 44
|
|
&& c != 58 && c != 59
|
|
&& c != 60 && c != 62
|
|
&& c != 34 && c != 92
|
|
&& c != 39) != 0;
|
|
}
|
|
|
|
bool andand2(long c)
|
|
{
|
|
return (c > 32 && c != 46 && c != 44
|
|
&& c != 58 && c != 59
|
|
&& c != 60 && c != 62
|
|
&& c != 34 && c != 92
|
|
&& c != 39) != 0;
|
|
}
|
|
|
|
int foox3() { return 1; }
|
|
|
|
int andand3(uint op)
|
|
{
|
|
if (foox3() &&
|
|
op != 7 &&
|
|
op != 3 &&
|
|
op != 18 &&
|
|
op != 30 &&
|
|
foox3())
|
|
return 3;
|
|
return 4;
|
|
}
|
|
|
|
|
|
void testandand()
|
|
{
|
|
assert(andand1(0) == 0);
|
|
assert(andand1(32) == 0);
|
|
assert(andand1(46) == 0);
|
|
assert(andand1(44) == 0);
|
|
assert(andand1(58) == 0);
|
|
assert(andand1(59) == 0);
|
|
assert(andand1(60) == 0);
|
|
assert(andand1(62) == 0);
|
|
assert(andand1(34) == 0);
|
|
assert(andand1(92) == 0);
|
|
assert(andand1(39) == 0);
|
|
assert(andand1(33) == 1);
|
|
assert(andand1(61) == 1);
|
|
assert(andand1(93) == 1);
|
|
assert(andand1(255) == 1);
|
|
|
|
assert(andand2(0) == false);
|
|
assert(andand2(32) == false);
|
|
assert(andand2(46) == false);
|
|
assert(andand2(44) == false);
|
|
assert(andand2(58) == false);
|
|
assert(andand2(59) == false);
|
|
assert(andand2(60) == false);
|
|
assert(andand2(62) == false);
|
|
assert(andand2(34) == false);
|
|
assert(andand2(92) == false);
|
|
assert(andand2(39) == false);
|
|
assert(andand2(33) == true);
|
|
assert(andand2(61) == true);
|
|
assert(andand2(93) == true);
|
|
assert(andand2(255) == true);
|
|
|
|
assert(andand3(6) == 3);
|
|
assert(andand3(30) == 4);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
bool bittest11508(char c)
|
|
{
|
|
return c=='_' || c=='-' || c=='+' || c=='.';
|
|
}
|
|
|
|
void testbittest()
|
|
{
|
|
assert(bittest11508('_'));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
uint or1(ubyte x)
|
|
{
|
|
return x | (x<<8) | (x<<16) | (x<<24) | (x * 3);
|
|
}
|
|
|
|
void testor_combine()
|
|
{
|
|
printf("%x\n", or1(1));
|
|
assert(or1(5) == 5 * (0x1010101 | 3));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
int shrshl(int i) {
|
|
return ((i+1)>>1)<<1;
|
|
}
|
|
|
|
void testshrshl()
|
|
{
|
|
assert(shrshl(6) == 6);
|
|
assert(shrshl(7) == 8);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
bool bt10715(in uint[] ary, size_t bitnum)
|
|
{
|
|
return !!(ary[bitnum >> 5] & 1 << (bitnum & 31)); // uses bt
|
|
}
|
|
|
|
bool neg_bt10715(in uint[] ary, size_t bitnum)
|
|
{
|
|
return !(ary[bitnum >> 5] & 1 << (bitnum & 31)); // does not use bt
|
|
}
|
|
|
|
void test10715()
|
|
{
|
|
static uint[2] a1 = [0x1001_1100, 0x0220_0012];
|
|
|
|
if ( bt10715(a1,30)) assert(0);
|
|
if (!bt10715(a1,8)) assert(0);
|
|
if ( bt10715(a1,30+32)) assert(0);
|
|
if (!bt10715(a1,1+32)) assert(0);
|
|
|
|
if (!neg_bt10715(a1,30)) assert(0);
|
|
if ( neg_bt10715(a1,8)) assert(0);
|
|
if (!neg_bt10715(a1,30+32)) assert(0);
|
|
if ( neg_bt10715(a1,1+32)) assert(0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
ptrdiff_t compare12164(A12164* rhsPA, A12164* zis)
|
|
{
|
|
if (*rhsPA == *zis)
|
|
return 0;
|
|
return ptrdiff_t.min;
|
|
}
|
|
|
|
struct A12164
|
|
{
|
|
int a;
|
|
}
|
|
|
|
void test12164()
|
|
{
|
|
auto a = A12164(3);
|
|
auto b = A12164(2);
|
|
assert(compare12164(&a, &b));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int foo10678(char[5] txt)
|
|
{
|
|
return txt[0] + txt[1] + txt[4];
|
|
}
|
|
|
|
void test10678()
|
|
{
|
|
char[5] hello = void;
|
|
hello[0] = 8;
|
|
hello[1] = 9;
|
|
hello[4] = 10;
|
|
int i = foo10678(hello);
|
|
assert(i == 27);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct S12051
|
|
{
|
|
this(char c)
|
|
{
|
|
assert(c == 'P' || c == 'M');
|
|
}
|
|
}
|
|
|
|
void test12051()
|
|
{
|
|
auto ip = ["abc"];
|
|
foreach (i, s; ip)
|
|
{
|
|
S12051(i < ip.length ? 'P' : 'M');
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void bug7565( double x) { assert(x == 3); }
|
|
|
|
void test7565()
|
|
{
|
|
double y = 3;
|
|
bug7565( y++ );
|
|
assert(y == 4);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int bug8525(int[] devt)
|
|
{
|
|
return devt[$ - 1];
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void func13190(int) {}
|
|
|
|
struct Struct13190
|
|
{
|
|
ulong a;
|
|
uint b;
|
|
};
|
|
|
|
__gshared Struct13190* table13190 =
|
|
[
|
|
Struct13190(1, 1),
|
|
Struct13190(0, 2)
|
|
];
|
|
|
|
void test13190()
|
|
{
|
|
for (int i = 0; table13190[i].a; i++)
|
|
{
|
|
ulong tbl = table13190[i].a;
|
|
func13190(i);
|
|
if (1 + tbl)
|
|
{
|
|
if (tbl == 0x80000)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
double foo13485(double c, double d)
|
|
{
|
|
// This must not be optimized to c += (d + d)
|
|
c += d;
|
|
c += d;
|
|
return c;
|
|
}
|
|
|
|
void test13485()
|
|
{
|
|
enum double d = 0X1P+1023;
|
|
assert(foo13485(-d, d) == d);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test12833a(int a)
|
|
{
|
|
long x = cast(long)a;
|
|
|
|
switch (cast(int)(cast(ushort)(x >> 16 & 65535L)))
|
|
{
|
|
case 1:
|
|
{
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void test12833()
|
|
{
|
|
test12833a(0x1_0000);
|
|
}
|
|
|
|
/***********************************************/
|
|
|
|
struct Point9449
|
|
{
|
|
double f = 3.0;
|
|
double g = 4.0;
|
|
}
|
|
|
|
void test9449()
|
|
{
|
|
Point9449[1] arr;
|
|
if (arr[0].f != 3.0) assert(0);
|
|
if (arr[0].g != 4.0) assert(0);
|
|
}
|
|
|
|
struct Point9449x
|
|
{
|
|
float f = 0.0;
|
|
double g = 0.0;
|
|
}
|
|
|
|
void test9449x()
|
|
{
|
|
Point9449x[1] arr;
|
|
if (arr[0].f != 0.0) assert(0);
|
|
if (arr[0].g != 0.0) assert(0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=12057
|
|
|
|
bool prop12057(real x) { return false; }
|
|
double f12057(real) { return double.init; }
|
|
void test12057()
|
|
{
|
|
real fc = f12057(real.init);
|
|
if (fc == 0 || fc.prop12057) {}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
long modulo24 (long ticks)
|
|
{
|
|
ticks %= 864000000000;
|
|
if (ticks < 0)
|
|
ticks += 864000000000;
|
|
return ticks;
|
|
}
|
|
|
|
void test13784()
|
|
{
|
|
assert (modulo24(-141600000000) == 722400000000);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct S13969 {
|
|
int x, y;
|
|
}
|
|
|
|
int test13969(const S13969* f) {
|
|
return 0 % ((f.y > 0) ? f.x / f.y : f.x / -f.y);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int[] arr14436;
|
|
void test14436()
|
|
{
|
|
assert(arr14436 == null);
|
|
arr14436 = [1, 2, 3];
|
|
assert(arr14436 != null);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test14220()
|
|
{
|
|
auto a = toString(14);
|
|
|
|
printf("a.ptr = %p, a.length = %d\n", a.ptr, cast(int)a.length);
|
|
return;
|
|
}
|
|
|
|
auto toString(int value)
|
|
{
|
|
uint mValue = value;
|
|
|
|
char[int.sizeof * 3] buffer = void;
|
|
size_t index = buffer.length;
|
|
|
|
do
|
|
{
|
|
uint div = cast(int)(mValue / 10);
|
|
char mod = mValue % 10 + '0';
|
|
buffer[--index] = mod; // Line 22
|
|
mValue = div;
|
|
} while (mValue);
|
|
|
|
//printf("buffer.ptr = %p, index = %d\n", buffer.ptr, cast(int)index);
|
|
return dup(buffer[index .. $]);
|
|
}
|
|
|
|
char[] dup(char[] a)
|
|
{
|
|
//printf("a.ptr = %p, a.length = %d\n", a.ptr, cast(int)a.length);
|
|
a[0] = 1; // segfault
|
|
return a;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int stripLeft(int str, int dc)
|
|
{
|
|
while (true)
|
|
{
|
|
int a = str;
|
|
int s = a;
|
|
str += 1;
|
|
if (dc) return s;
|
|
}
|
|
}
|
|
|
|
void test14829()
|
|
{
|
|
if (stripLeft(3, 1) != 3) // fails with -O
|
|
assert(0);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test3()
|
|
{
|
|
int[6] a;
|
|
int[] b;
|
|
b = a;
|
|
b = (b.ptr + b.length - 5)[0 .. b.ptr + b.length - 1 - a.ptr];
|
|
assert(b.ptr == a.ptr + 1);
|
|
assert(b.length == 5);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=14782
|
|
|
|
|
|
void test14782()
|
|
{
|
|
static struct Foo
|
|
{
|
|
long a = 8;
|
|
int b = 7;
|
|
}
|
|
|
|
static Foo[1] fun() { Foo[1] a; return a; }
|
|
|
|
auto result = fun();
|
|
assert(result[0].a == 8);
|
|
assert(result[0].b == 7);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test14987()
|
|
{
|
|
static struct Foo
|
|
{
|
|
int b = 7;
|
|
}
|
|
static assert((Foo[4]).sizeof == 16);
|
|
|
|
static Foo[4] fun() { Foo[4] a; return a; }
|
|
|
|
auto result = fun();
|
|
assert(result[0].b == 7);
|
|
assert(result[1].b == 7);
|
|
assert(result[2].b == 7);
|
|
assert(result[3].b == 7);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void[] calloc15272(size_t bc) nothrow pure
|
|
{
|
|
assert(bc == 1);
|
|
return new void[1];
|
|
}
|
|
|
|
void test15272()
|
|
{
|
|
void[] scache = cast(void[])"abc";
|
|
size_t count = 1;
|
|
void[]* buckets = &scache;
|
|
*buckets = calloc15272(count)[0 .. count];
|
|
}
|
|
|
|
/*****************************************
|
|
* https://issues.dlang.org/show_bug.cgi?id=15861
|
|
*/
|
|
|
|
void test15861()
|
|
{
|
|
double val = 4286853117.;
|
|
|
|
(){
|
|
assert(val == 4286853117.);
|
|
}();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=15629 comment 3
|
|
// -O
|
|
|
|
void test15629()
|
|
{
|
|
int[] a = [3];
|
|
int value = a[0] >= 0 ? a[0] : -a[0];
|
|
assert(a[0] == 3);
|
|
writeln(value, a);
|
|
}
|
|
|
|
void writeln(int v, int[] a)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
real binPosPow2() { return 1.0L; }
|
|
|
|
real binPow2()
|
|
{
|
|
return 1.0L/binPosPow2();
|
|
}
|
|
|
|
void test4()
|
|
{
|
|
assert(binPow2() == 1.0L);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=13474
|
|
|
|
|
|
double sumKBN(double s = 0.0)
|
|
{
|
|
import core.math : fabs;
|
|
double c = 0.0;
|
|
foreach(double x; [1, 1e100, 1, -1e100])
|
|
{
|
|
x = multiply(x);
|
|
double t = s + x;
|
|
if(s.fabs >= x.fabs)
|
|
{
|
|
double y = s-t;
|
|
c += y+x;
|
|
}
|
|
else
|
|
{
|
|
double y = x-t;
|
|
c += y+s;
|
|
}
|
|
s = t;
|
|
}
|
|
return s + c;
|
|
}
|
|
|
|
double multiply(double a) { return a * 10000; }
|
|
|
|
void test13474()
|
|
{
|
|
double r = 20000;
|
|
assert(r == sumKBN());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=16699
|
|
|
|
ulong[1] parseDateRange()
|
|
{
|
|
try
|
|
{
|
|
ulong[1] result;
|
|
result[0] = 6;
|
|
return result;
|
|
}
|
|
finally
|
|
{
|
|
}
|
|
}
|
|
|
|
void test16699()
|
|
{
|
|
ulong[1] range = parseDateRange();
|
|
assert(range[0] == 6);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=16102
|
|
|
|
struct S16102 { ~this() { } }
|
|
|
|
long[1] f16102()
|
|
{
|
|
S16102 a;
|
|
return [1];
|
|
}
|
|
|
|
void test16102()
|
|
{
|
|
assert( f16102() == [1] );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test5a(ulong x, ulong y)
|
|
{
|
|
int a;
|
|
if (x >> 32)
|
|
a = 1;
|
|
else
|
|
a = 2;
|
|
assert(a == 1);
|
|
|
|
if (y >> 32)
|
|
a = 1;
|
|
else
|
|
a = 2;
|
|
assert(a == 2);
|
|
}
|
|
|
|
void test5()
|
|
{
|
|
test5a(uint.max + 1L, uint.max);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/* Test the pattern:
|
|
* replace (e ? i1 : i2) with (i1 + e * (i2 - i1))
|
|
* when e1 is 0 or 1 and (i2-i1) is a power of 2.
|
|
*/
|
|
|
|
int foo61(int i)
|
|
{
|
|
return (i % 2 != 0) ? 4 : 2;
|
|
}
|
|
|
|
int foo62(int i)
|
|
{
|
|
return (i % 2 != 0) ? 2 : 4;
|
|
}
|
|
|
|
bool bar6(bool b) { return b; }
|
|
|
|
int foo63(bool b)
|
|
{
|
|
return bar6(b) ? 16 : 8;
|
|
}
|
|
|
|
int foo64(bool b)
|
|
{
|
|
return bar6(b) ? 8 : 16;
|
|
}
|
|
|
|
void test6()
|
|
{
|
|
if (foo61(0) != 2) assert(0);
|
|
if (foo61(1) != 4) assert(0);
|
|
if (foo62(0) != 4) assert(0);
|
|
if (foo62(1) != 2) assert(0);
|
|
if (foo63(0) != 8) assert(0);
|
|
if (foo63(1) != 16) assert(0);
|
|
if (foo64(0) != 16) assert(0);
|
|
if (foo64(1) != 8) assert(0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int dataflow(int b) {
|
|
int ret;
|
|
|
|
if (b==4)
|
|
ret = 3;
|
|
else
|
|
ret = 5;
|
|
|
|
if (ret == 4)
|
|
return 0;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
void testeqeqranges()
|
|
{
|
|
int i = dataflow(4);
|
|
if (i != 1)
|
|
assert(0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=16189
|
|
|
|
void test16189()
|
|
{
|
|
ubyte[9][1] data;
|
|
uint a = 0;
|
|
loop:
|
|
data[0] = data[a];
|
|
a--;
|
|
bool b = false;
|
|
if (b) goto loop;
|
|
assert(a == -1); // was failing with -O
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=16997
|
|
|
|
void test16997()
|
|
{
|
|
/* Exhaustively test all signed and unsigned byte promotions for
|
|
* - + and ~
|
|
*/
|
|
for (int i = 0; i < 256; ++i)
|
|
{
|
|
ubyte c = cast(ubyte)i;
|
|
|
|
int i1 = cast(int)(~c);
|
|
int i2 = cast(int)(~cast(int)c);
|
|
|
|
//printf("%d, %d\n", i1, i2);
|
|
assert(i1 == i2);
|
|
|
|
i1 = cast(int)(+c);
|
|
i2 = cast(int)(+cast(int)c);
|
|
assert(i1 == i2);
|
|
|
|
i1 = cast(int)(-c);
|
|
i2 = cast(int)(-cast(int)c);
|
|
assert(i1 == i2);
|
|
}
|
|
|
|
for (int i = 0; i < 256; ++i)
|
|
{
|
|
byte c = cast(byte)i;
|
|
|
|
int i1 = cast(int)(~c);
|
|
int i2 = cast(int)(~cast(int)c);
|
|
|
|
//printf("%d, %d\n", i1, i2);
|
|
assert(i1 == i2);
|
|
|
|
i1 = cast(int)(+c);
|
|
i2 = cast(int)(+cast(int)c);
|
|
assert(i1 == i2);
|
|
|
|
i1 = cast(int)(-c);
|
|
i2 = cast(int)(-cast(int)c);
|
|
assert(i1 == i2);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test18315() // https://issues.dlang.org/show_bug.cgi?id=18315
|
|
{
|
|
int i = int.min;
|
|
bool b = i > 0;
|
|
assert(!b);
|
|
b = 0 < i;
|
|
assert(!b);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=18461
|
|
|
|
void test18461()
|
|
{
|
|
import core.bitop;
|
|
|
|
size_t test_val = 0b0001_0000;
|
|
|
|
if (bt(&test_val, 4) == 0)
|
|
assert(false);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test18730() // https://issues.dlang.org/show_bug.cgi?id=18730
|
|
{
|
|
static if (size_t.sizeof == 8)
|
|
{
|
|
static int bt18730_64_64(in ulong* p, ulong bitnum) pure @system
|
|
{
|
|
return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;
|
|
}
|
|
static int bt18730_64_32(in ulong* p, uint bitnum) pure @system
|
|
{
|
|
return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;
|
|
}
|
|
static int bt18730_32_64(in uint* p, ulong bitnum) pure @system
|
|
{
|
|
return ((p[bitnum >> 5] & (1 << (bitnum & 31)))) != 0;
|
|
}
|
|
|
|
// Check that bt_64_64 uses a 64-bit register for the offset.
|
|
{
|
|
enum bitIndex = int.max + 1L;
|
|
auto a = new ulong[](bitIndex / 64 + 1);
|
|
a[bitIndex / 64] = 1;
|
|
assert(bt18730_64_64(a.ptr, bitIndex));
|
|
assert(!bt18730_64_64(a.ptr, bitIndex + 1));
|
|
assert(!bt18730_64_64(a.ptr, bitIndex - 1));
|
|
}
|
|
// Check that bt_64_32 uses a 32-bit register for the offset.
|
|
{
|
|
static int f(ulong* p, ulong bitnum)
|
|
{
|
|
return bt18730_64_32(p, cast(uint) bitnum);
|
|
}
|
|
enum bitIndex = uint.max + 1L;
|
|
assert(cast(uint) bitIndex == 0);
|
|
ulong s = 1;
|
|
assert(f(&s, bitIndex));
|
|
}
|
|
/* Check that bt_32_64 does not become a 64-bit bt instruction. Would lead
|
|
to a segfault when trying to load 8 bytes while only 4 are accessible. */
|
|
version (Posix)
|
|
{{
|
|
import core.sys.posix.sys.mman;
|
|
import core.sys.posix.unistd;
|
|
// Allocate two pages.
|
|
immutable sz = 2 * sysconf(_SC_PAGESIZE);
|
|
auto m = mmap(null, sz, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
// Discard the higher page. It becomes unreadable.
|
|
munmap(m + sz / 2, sz / 2);
|
|
// Try looking at the last 4 bytes of the readable page.
|
|
uint* p = cast(uint*) (m + sz / 2 - uint.sizeof);
|
|
bt18730_32_64(p, 0);
|
|
munmap(m, sz / 2); // Free the readable page.
|
|
}}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void test19497() // https://issues.dlang.org/show_bug.cgi?id=19497
|
|
{
|
|
{
|
|
ubyte[1024] data;
|
|
ushort* ushortPtr = cast(ushort*) data.ptr;
|
|
*ushortPtr++ = 0xfe00;
|
|
printf("ushortPtr(%p)\n", ushortPtr);
|
|
fflush(stdout);
|
|
}
|
|
|
|
alias Seq(stuff ...) = stuff;
|
|
static foreach (T; Seq!(ubyte, ushort, uint, ulong, byte, short, int, long))
|
|
{{
|
|
T[2] data = 0x2A;
|
|
T* q = &data[0];
|
|
*q++ = cast(T) 0x1122334455667788;
|
|
if (*q != 0x2A) assert(false);
|
|
}}
|
|
|
|
{
|
|
static int toStringz(string s) { return s.length > 0 ? s[0] : 0; }
|
|
static void toAStringz(in string[] a, int* az)
|
|
{
|
|
foreach (string s; a)
|
|
{
|
|
*az++ = toStringz(s);
|
|
}
|
|
}
|
|
string[1] sa = ["abc"];
|
|
int[2] tgt = 0x2a;
|
|
toAStringz(sa[], tgt.ptr);
|
|
if (tgt[0] != 'a') assert(false);
|
|
if (tgt[1] != 0x2a) assert(false);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=18794
|
|
|
|
bool method18794(size_t* p)
|
|
{
|
|
int bitIdx = 0;
|
|
func18794();
|
|
return (*p & (1UL << bitIdx)) != 0;
|
|
}
|
|
|
|
void func18794() {}
|
|
|
|
void prep18794()
|
|
{
|
|
asm {}
|
|
ulong[2] x = -1;
|
|
}
|
|
|
|
void test18794()
|
|
{
|
|
prep18794();
|
|
size_t s;
|
|
method18794(&s);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/* Test the optimization
|
|
* (e1+c)-e2 => (e1-e2)+c
|
|
*/
|
|
|
|
void testelmin()
|
|
{
|
|
static void foo(int i)
|
|
{
|
|
static ubyte[4] bar()
|
|
{
|
|
ubyte[4] array;
|
|
foreach (i, ref a; array)
|
|
a = cast(ubyte)(i + 1);
|
|
return array;
|
|
}
|
|
|
|
static void test(int i, ubyte* p)
|
|
{
|
|
foreach (j; 0 .. 4)
|
|
assert(p[i * 4 + j] == j + 1);
|
|
}
|
|
|
|
ubyte[32] data;
|
|
data[i*4..(i+1)*4] = bar(); // optimize to single MOV
|
|
|
|
test(i, data.ptr);
|
|
}
|
|
|
|
foo(4);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
const(char)* fastpar(string s)
|
|
{
|
|
return s.ptr + s.length;
|
|
}
|
|
|
|
void testfastpar()
|
|
{
|
|
string s = "abcde";
|
|
auto p = fastpar(s);
|
|
assert(*p == 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=20363
|
|
|
|
ulong foo20363(double d)
|
|
{
|
|
ulong u = * cast(ulong*) &d;
|
|
return (u >> 1) & 1;
|
|
}
|
|
|
|
void test20363()
|
|
{
|
|
ulong u = 0b10;
|
|
if (foo20363(*cast(double*) &u) == 0)
|
|
assert(false);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
T testfooa(T)(T value)
|
|
{
|
|
return 10 - (value * 57); // gets rewritten into (value*-57)+10
|
|
}
|
|
|
|
T testfoob(T)(T value)
|
|
{
|
|
return (value * -57) + 10;
|
|
}
|
|
|
|
void testNegConst()
|
|
{
|
|
assert(testfooa(1) == -47);
|
|
assert(testfoob(1) == -47);
|
|
assert(testfooa(1.0) == -47);
|
|
assert(testfoob(1.0) == -47);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=16317
|
|
|
|
int add8ret3(ref int s)
|
|
{
|
|
s += 8;
|
|
return 3;
|
|
}
|
|
|
|
int binAdd(int val)
|
|
{
|
|
val = val + add8ret3(val);
|
|
return val;
|
|
}
|
|
|
|
void test16317()
|
|
{
|
|
assert(binAdd(1) == (1 + 3));
|
|
static assert(binAdd(1) == (1 + 3));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=20050
|
|
|
|
int test20050_g = 0;
|
|
void test20050_impure_function_1() { ++test20050_g; }
|
|
void function() test20050_get_impure_function() pure
|
|
{
|
|
static void impure_function_2()
|
|
{
|
|
++test20050_g;
|
|
test20050_impure_function_1();
|
|
}
|
|
return &impure_function_2;
|
|
}
|
|
void test20050()
|
|
{
|
|
auto f = test20050_get_impure_function();
|
|
f();
|
|
assert(test20050_g == 2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://github.com/dlang/dmd/pull/11238
|
|
|
|
int testCpStatic1(int y)
|
|
{
|
|
__gshared int yyy = 7;
|
|
auto x = yyy; // no copy-propagation
|
|
if (y)
|
|
return x;
|
|
return x + 3;
|
|
}
|
|
|
|
void testCpStatic()
|
|
{
|
|
assert(testCpStatic1(1) == 7);
|
|
assert(testCpStatic1(0) == 10);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=20991
|
|
|
|
int x7;
|
|
|
|
void bar7(int i)
|
|
{
|
|
assert(i == x7);
|
|
++x7;
|
|
}
|
|
|
|
void test7()
|
|
{
|
|
for (int i = 0; i <= 1; ++i)
|
|
bar7(i);
|
|
assert(x7 == 2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://github.com/dlang/dmd/pull/11388
|
|
|
|
ushort byteswap(ushort x) pure
|
|
{
|
|
// Should be detected and XCHG instruction generated
|
|
return cast(ushort) (((x >> 8) & 0xFF) | ((x << 8) & 0xFF00u));
|
|
}
|
|
|
|
void testbyteswap()
|
|
{
|
|
assert(byteswap(0xF234) == 0x34F2);
|
|
static ushort xx = 0xF234;
|
|
assert(byteswap(xx) == 0x34F2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// These should all be recognized by the compiler and generate ROL or ROR
|
|
// instructions.
|
|
|
|
uint rol32(uint x, uint n)
|
|
{
|
|
return (x << n) | (x >> (32 - n));
|
|
}
|
|
|
|
uint ror32(uint x, uint n)
|
|
{
|
|
return (x >> n) | (x << (32 - n));
|
|
}
|
|
|
|
ulong rol64(ulong x, uint n)
|
|
{
|
|
return (x << n) | (x >> (64 - n));
|
|
}
|
|
|
|
ulong ror64(ulong x, uint n)
|
|
{
|
|
return (x >> n) | (x << (64 - n));
|
|
}
|
|
|
|
void testrolror()
|
|
{
|
|
assert(ror32(0x0123_4567u, 4) == 0x7012_3456);
|
|
assert(rol32(0x7012_3456u, 4) == 0x0123_4567);
|
|
|
|
assert(ror64(0x0123_4567_89AB_CDEFuL, 4) == 0xF012_3456_789A_BCDE);
|
|
assert(rol64(0xF012_3456_789A_BCDEuL, 4) == 0x0123_4567_89AB_CDEF);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=20162
|
|
|
|
void test20162()
|
|
{
|
|
static long f(long a)
|
|
{
|
|
assert(a == -1L);
|
|
return a;
|
|
}
|
|
|
|
foreach (i; 1 .. 2)
|
|
{
|
|
foreach (j; 0 .. 2)
|
|
{
|
|
printf("%d %d %llx\n", i,
|
|
((i != 0) ? -1 : +1),
|
|
f((i != 0) ? -1 : +1));
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=3713
|
|
|
|
int star1(int i)
|
|
{
|
|
return i ? star1(i - 1) : 0;
|
|
}
|
|
|
|
int star2(int i)
|
|
{
|
|
return i == 0 ? 0 : star2(i - 1);
|
|
}
|
|
|
|
int star3(int i)
|
|
{
|
|
if (i == 0)
|
|
return 0;
|
|
return i == 2 ? star3(i - 2) : star3(i - 1);
|
|
}
|
|
|
|
int star4(int i)
|
|
{
|
|
return (i == 0) ? 0
|
|
: i != 2 ? star4(i - 1)
|
|
: star4(i - 2);
|
|
}
|
|
|
|
void test3713()
|
|
{
|
|
assert(star1(10) == 0);
|
|
assert(star2(10) == 0);
|
|
assert(star3(10) == 0);
|
|
assert(star4(10) == 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void testsbbrex()
|
|
{
|
|
// special code is generated for these two cases
|
|
static long foolt(dchar c)
|
|
{
|
|
return c < 0x10000 ? 1 : 2;
|
|
}
|
|
|
|
static long fooge(uint c)
|
|
{
|
|
return c >= 0x10000 ? 1L : 2L;
|
|
}
|
|
|
|
assert(foolt(0) == 1);
|
|
assert(foolt(0x10000) == 2);
|
|
assert(fooge(0) == 2);
|
|
assert(fooge(0x10000) == 1);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=19846
|
|
|
|
alias Void = byte[0];
|
|
static immutable Void VOID; // = [];
|
|
|
|
__gshared int x19846;
|
|
|
|
Void print19846()
|
|
{
|
|
//printf("This should print\n");
|
|
x19846 = 3;
|
|
return VOID;
|
|
}
|
|
|
|
Void identity19846(Void value, out int i)
|
|
{
|
|
i = 7;
|
|
return value;
|
|
}
|
|
|
|
void test19846()
|
|
{
|
|
int i;
|
|
identity19846(print19846(), i);
|
|
//printf("i = %d\n", i);
|
|
assert(x19846 == 3);
|
|
assert(i == 7);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// Some tests for OPmemcpy
|
|
|
|
enum N = 128;
|
|
|
|
ubyte[N] def()
|
|
{
|
|
ubyte[N] array;
|
|
foreach (i, ref a; array)
|
|
a = cast(ubyte)(i + 1);
|
|
return array;
|
|
}
|
|
|
|
|
|
void ghi(ubyte* p)
|
|
{
|
|
foreach (i; 0 .. N)
|
|
assert(p[i] == i + 1);
|
|
}
|
|
|
|
void testmemcpy()
|
|
{
|
|
ubyte[N] bits;
|
|
ubyte[N] bits2;
|
|
bits2[0..N] = bits[0..N] = def();
|
|
ghi(bits.ptr);
|
|
ghi(bits2.ptr);
|
|
|
|
__gshared size_t n = N;
|
|
ubyte[N] bits3;
|
|
ubyte[N] bits4;
|
|
bits4[0..n] = bits3[0..n] = def();
|
|
ghi(bits3.ptr);
|
|
ghi(bits4.ptr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/* Test all the cases of uses of LEA for multiplication by a constant
|
|
*/
|
|
|
|
T testlea(uint C, T)(T x, T y)
|
|
{
|
|
y = y * C; // cdmul()
|
|
x *= C; // cdmulass()
|
|
return x + y;
|
|
}
|
|
|
|
void testleax(uint C)(uint X, uint Y)
|
|
{
|
|
assert(testlea!C(X,Y) == C * (X + Y));
|
|
assert(testlea!C(cast(long)X,cast(long)Y) == cast(long)C*X + cast(long)C*Y);
|
|
}
|
|
|
|
void testMulLea()
|
|
{
|
|
testleax!3(10,11);
|
|
testleax!5(10,11);
|
|
testleax!6(10,11);
|
|
testleax!9(10,11);
|
|
|
|
testleax!10(10,11);
|
|
testleax!12(10,11);
|
|
testleax!18(10,11);
|
|
testleax!20(10,11);
|
|
testleax!24(10,11);
|
|
testleax!36(10,11);
|
|
testleax!40(10,11);
|
|
testleax!72(10,11);
|
|
|
|
testleax!37(10,11);
|
|
testleax!74(10,11);
|
|
testleax!13(10,11);
|
|
testleax!26(10,11);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/* Test *= of register pair
|
|
*/
|
|
|
|
void testMulAssPair()
|
|
{
|
|
static ulong pow(ulong x, int m)
|
|
{
|
|
ulong v = x;
|
|
ulong p = 1;
|
|
while (1)
|
|
{
|
|
if (m & 1)
|
|
p *= v;
|
|
m >>= 1;
|
|
if (!m)
|
|
break;
|
|
v *= v;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
enum ulong e_10_pow_19 = 10uL^^19;
|
|
assert(e_10_pow_19 == pow(10uL, 19));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=21038
|
|
|
|
const(wchar)* x21038 = "xz";
|
|
const(dchar)* name21038 = "abcd";
|
|
|
|
void test21038()
|
|
{
|
|
assert((cast(size_t) x21038) % wchar.sizeof == 0);
|
|
assert((cast(size_t) name21038) % dchar.sizeof == 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=21325
|
|
|
|
real f21325(const real x) pure @safe nothrow @nogc
|
|
{
|
|
return (x != 0.0L) ? x : real.nan;
|
|
}
|
|
|
|
void test21325() @safe
|
|
{
|
|
ulong x = 0uL;
|
|
while(true)
|
|
{
|
|
const y = f21325(x); // should set y to real.nan
|
|
|
|
assert(y != y);
|
|
|
|
if (++x)
|
|
return; // good
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=16274
|
|
|
|
extern(C) int pair(short a, ushort b, byte c, ubyte d);
|
|
|
|
struct S
|
|
{
|
|
// provide alternate implementation of .pair()
|
|
pragma(mangle, "pair")
|
|
extern(C) static void pair(int a, int b, int c, int d)
|
|
{
|
|
//printf("%d %d %d %d\n", a, b, c, d);
|
|
assert(a == -1);
|
|
assert(b == 2);
|
|
assert(c == -3);
|
|
assert(d == 4);
|
|
}
|
|
}
|
|
|
|
void test16274()
|
|
{
|
|
version (X86_64)
|
|
pair(-1, 2, -3, 4);
|
|
version (X86)
|
|
pair(-1, 2, -3, 4);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=16268
|
|
|
|
void test16268()
|
|
{
|
|
static void f(byte x)
|
|
{
|
|
for (byte i = 0; i <= x && i >= 0; ++i)
|
|
{
|
|
assert(i >= 0);
|
|
assert(i != -1);
|
|
//printf("%d\n", i);
|
|
}
|
|
}
|
|
|
|
f(byte.max);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=11435
|
|
|
|
void test11435a()
|
|
{
|
|
alias T = byte;
|
|
|
|
static void fun(T c, T b, int v)
|
|
{
|
|
}
|
|
|
|
static void abc(T[] b)
|
|
{
|
|
fun(b[0], b[1], 0);
|
|
}
|
|
|
|
version(Windows)
|
|
{
|
|
import core.sys.windows.windows;
|
|
auto p = VirtualAlloc(null, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
}
|
|
else
|
|
{
|
|
import core.sys.posix.sys.mman;
|
|
auto p = mmap(null, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0L);
|
|
}
|
|
assert(p);
|
|
auto px = (cast(T*)(p + 4096 - 2 * T.sizeof));
|
|
abc(px[0..2]);
|
|
}
|
|
|
|
void test11435b()
|
|
{
|
|
import core.sys.windows.windows;
|
|
alias T = short;
|
|
|
|
static void fun(T c, T b, int v)
|
|
{
|
|
}
|
|
|
|
static void abc(T[] b)
|
|
{
|
|
fun(b[0], b[1], 0);
|
|
}
|
|
|
|
version(Windows)
|
|
{
|
|
import core.sys.windows.windows;
|
|
auto p = VirtualAlloc(null, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
}
|
|
else
|
|
{
|
|
import core.sys.posix.sys.mman;
|
|
auto p = mmap(null, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0L);
|
|
}
|
|
assert(p);
|
|
auto px = (cast(T*)(p + 4096 - 2 * T.sizeof));
|
|
abc(px[0..2]);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=21513
|
|
|
|
struct Stuff
|
|
{
|
|
size_t c; // declare after items and not crash !
|
|
ubyte[1] items;
|
|
}
|
|
|
|
void grow(ref Stuff stuff)
|
|
{
|
|
with (stuff)
|
|
{
|
|
const oldCapacity = c;
|
|
items.ptr[0..oldCapacity] = items.ptr[0..0]; // use literal 0 instead of
|
|
items.ptr[0] = 0; // oldcapacity and no crash !
|
|
}
|
|
}
|
|
|
|
void test21513()
|
|
{
|
|
Stuff stuff;
|
|
grow(stuff);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=21526
|
|
|
|
double f21256(double a, double b) {
|
|
double c = a + b;
|
|
return c;
|
|
}
|
|
|
|
void test21256()
|
|
{
|
|
union DX
|
|
{
|
|
double d;
|
|
ulong l;
|
|
}
|
|
|
|
DX a, b;
|
|
a.l = 0x4341c37937e08000;
|
|
b.l = 0x4007ffcb923a29c7;
|
|
|
|
DX r;
|
|
r.d = f21256(a.d, b.d);
|
|
//if (r.d != 0x1.1c37937e08001p+53)
|
|
//printf("r = %A should be 0x1.1c37937e08001p+53 %A\n", r.d, 0x1.1c37937e08001p+53);
|
|
//assert(r == 0x1.1c37937e08001p+53);
|
|
|
|
// cannot seem to get the two to produce the same value
|
|
assert(r.l == 0x4341c37937e08001 || // value using XMM
|
|
r.l == 0x4341c37937e08002); // value using x87
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=21816
|
|
|
|
bool test21816a(float t)
|
|
{
|
|
return cast(bool)t;
|
|
}
|
|
|
|
void test21816()
|
|
{
|
|
assert(test21816a(float.nan));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://issues.dlang.org/show_bug.cgi?id=21835
|
|
|
|
struct Point21835
|
|
{
|
|
float f = 3.0;
|
|
double d = 4.0;
|
|
real r = 5.0;
|
|
}
|
|
|
|
void test21835y()
|
|
{
|
|
Point21835[1] arr;
|
|
if (arr[0].f != 3.0) assert(0);
|
|
if (arr[0].d != 4.0) assert(0);
|
|
if (arr[0].r != 5.0) assert(0);
|
|
}
|
|
|
|
struct Point21835x
|
|
{
|
|
float f = 0.0;
|
|
double d = 0.0;
|
|
real r = 0.0;
|
|
}
|
|
|
|
void test21835()
|
|
{
|
|
test21835y();
|
|
Point21835x[1] arr;
|
|
if (arr[0].f != 0.0) assert(0);
|
|
if (arr[0].d != 0.0) assert(0);
|
|
if (arr[0].r != 0.0) assert(0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://github.com/dlang/dmd/pull/16187#issuecomment-1946534649
|
|
|
|
void testDoWhileContinue()
|
|
{
|
|
int i = 10;
|
|
do
|
|
{
|
|
continue;
|
|
}
|
|
while(--i > 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// https://github.com/dlang/dmd/issues/20574
|
|
|
|
int test20574x(int i, int y)
|
|
{
|
|
return i ? y : y;
|
|
}
|
|
|
|
void test20574()
|
|
{
|
|
assert(test20574x(1, 2) == 2);
|
|
assert(test20574x(0, 2) == 2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct S8
|
|
{
|
|
int x,y,z;
|
|
}
|
|
|
|
int test8x(S8 s)
|
|
{
|
|
s = s;
|
|
return s.y;
|
|
}
|
|
|
|
void test8()
|
|
{
|
|
S8 s;
|
|
s.y = 2;
|
|
assert(test8x(s) == 2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct S9
|
|
{
|
|
int a,b;
|
|
~this() { }
|
|
}
|
|
|
|
|
|
S9 test9x(ref S9 arg)
|
|
{
|
|
return arg;
|
|
}
|
|
|
|
void test9()
|
|
{
|
|
S9 s;
|
|
s.b = 3;
|
|
S9 t = test9x(s);
|
|
assert(t.b == 3);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
int main()
|
|
{
|
|
// All the various integer divide tests
|
|
testsdiv2();
|
|
testulldiv();
|
|
testfastudiv();
|
|
testsldiv();
|
|
testslmod();
|
|
testfastdiv();
|
|
testdivdiv();
|
|
testdivcmp();
|
|
|
|
testgoto();
|
|
testswitch();
|
|
testdo();
|
|
testbreak();
|
|
teststringswitch();
|
|
teststrarg();
|
|
test12164();
|
|
testsizes();
|
|
testarrayinit();
|
|
testU();
|
|
testbittest();
|
|
test8658();
|
|
test3918();
|
|
test12051();
|
|
testdocond();
|
|
testnegcom();
|
|
test11565();
|
|
test23743();
|
|
testoror();
|
|
testbt();
|
|
test12095(0);
|
|
testandand();
|
|
testor_combine();
|
|
testshrshl();
|
|
test13383();
|
|
test13190();
|
|
test13485();
|
|
test14436();
|
|
test10715();
|
|
test10678();
|
|
test7565();
|
|
test13023(0x10_0000_0000);
|
|
test12833();
|
|
test9449();
|
|
test9449x();
|
|
test12057();
|
|
test13784();
|
|
test14220();
|
|
test14829();
|
|
test3();
|
|
test14782();
|
|
test14987();
|
|
test15272();
|
|
test15861();
|
|
test15629();
|
|
test4();
|
|
test13474();
|
|
test16699();
|
|
test16102();
|
|
test5();
|
|
test6();
|
|
testeqeqranges();
|
|
test16189();
|
|
test16997();
|
|
test18315();
|
|
test18461();
|
|
test18730();
|
|
test19497();
|
|
test18794();
|
|
testelmin();
|
|
testfastpar();
|
|
test20363();
|
|
testNegConst();
|
|
test16317();
|
|
test20050();
|
|
testCpStatic();
|
|
test7();
|
|
testbyteswap();
|
|
testrolror();
|
|
test20162();
|
|
test3713();
|
|
testsbbrex();
|
|
test19846();
|
|
testmemcpy();
|
|
testMulLea();
|
|
testMulAssPair();
|
|
test21038();
|
|
test21325();
|
|
test16274();
|
|
test16268();
|
|
test11435a();
|
|
test11435b();
|
|
test21513();
|
|
test21256();
|
|
test21816();
|
|
test21835();
|
|
testDoWhileContinue();
|
|
test20574();
|
|
test8();
|
|
test9();
|
|
|
|
printf("Success\n");
|
|
return 0;
|
|
}
|