mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
7909 lines
152 KiB
D
7909 lines
152 KiB
D
// PERMUTE_ARGS: -inline
|
|
// REQUIRED_ARGS: -verrors=simple
|
|
/*
|
|
TEST_OUTPUT:
|
|
---
|
|
compilable/interpret3.d(6351): Deprecation: identity comparison of static arrays implicitly coerces them to slices, which are compared by reference
|
|
---
|
|
*/
|
|
|
|
template compiles(int T)
|
|
{
|
|
bool compiles = true;
|
|
}
|
|
|
|
alias TypeTuple(T...) = T;
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=3901
|
|
// Arbitrary struct assignment, ref return
|
|
|
|
struct ArrayRet
|
|
{
|
|
int x;
|
|
}
|
|
|
|
int arrayRetTest(int z)
|
|
{
|
|
ArrayRet[6] w;
|
|
int q = (w[3].x = z);
|
|
return q;
|
|
}
|
|
static assert(arrayRetTest(51) == 51);
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=3842 -- must not segfault
|
|
int ice3842(int z)
|
|
{
|
|
ArrayRet w;
|
|
return arrayRetTest((*(&w)).x);
|
|
}
|
|
static assert(true || is(typeof(compiles!(ice3842(51)))));
|
|
|
|
int arrayret2()
|
|
{
|
|
int[5] a;
|
|
int[3] b;
|
|
b[] = a[1 .. $-1] = 5;
|
|
return b[1];
|
|
}
|
|
static assert(arrayret2() == 5);
|
|
|
|
struct DotVarTest
|
|
{
|
|
ArrayRet z;
|
|
}
|
|
|
|
struct DotVarTest2
|
|
{
|
|
ArrayRet z;
|
|
DotVarTest p;
|
|
}
|
|
|
|
int dotvar1()
|
|
{
|
|
DotVarTest w;
|
|
w.z.x = 3;
|
|
return w.z.x;
|
|
}
|
|
static assert(dotvar1() == 3);
|
|
|
|
int dotvar2()
|
|
{
|
|
DotVarTest2[4] m;
|
|
m[2].z.x = 3;
|
|
m[1].p.z.x = 5;
|
|
return m[2].z.x + 7;
|
|
}
|
|
static assert(dotvar2() == 10);
|
|
|
|
|
|
struct RetRefStruct
|
|
{
|
|
int x;
|
|
char c;
|
|
}
|
|
|
|
// Return value reference tests, for D2 only.
|
|
|
|
ref RetRefStruct reffunc1(return ref RetRefStruct a)
|
|
{
|
|
int y = a.x;
|
|
return a;
|
|
}
|
|
|
|
ref RetRefStruct reffunc2(return ref RetRefStruct a)
|
|
{
|
|
RetRefStruct z = a;
|
|
return reffunc1(a);
|
|
}
|
|
|
|
ref int reffunc7(return ref RetRefStruct aa)
|
|
{
|
|
return reffunc1(aa).x;
|
|
}
|
|
|
|
ref int reffunc3(return ref int a)
|
|
{
|
|
return a;
|
|
}
|
|
|
|
struct RefTestStruct
|
|
{
|
|
RetRefStruct r;
|
|
|
|
ref RefTestStruct reffunc4(ref RetRefStruct[3] a) return
|
|
{
|
|
return this;
|
|
}
|
|
|
|
ref int reffunc6() return
|
|
{
|
|
return this.r.x;
|
|
}
|
|
}
|
|
|
|
ref RetRefStruct reffunc5(return ref RetRefStruct[3] a)
|
|
{
|
|
int t = 1;
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
if (i == 7)
|
|
++t;
|
|
}
|
|
return a[reffunc3(t)];
|
|
}
|
|
|
|
int retRefTest1()
|
|
{
|
|
RetRefStruct b = RetRefStruct(0, 'a');
|
|
reffunc1(b).x = 3;
|
|
return b.x - 1;
|
|
}
|
|
|
|
int retRefTest2()
|
|
{
|
|
RetRefStruct b = RetRefStruct(0, 'a');
|
|
reffunc2(b).x = 3;
|
|
RetRefStruct[3] z;
|
|
RefTestStruct w;
|
|
w.reffunc4(z).reffunc4(z).r.x = 4;
|
|
assert(w.r.x == 4);
|
|
w.reffunc6() = 218;
|
|
assert(w.r.x == 218);
|
|
z[2].x = 3;
|
|
int q = 4;
|
|
int u = reffunc5(z).x + reffunc3(q);
|
|
assert(u == 7);
|
|
reffunc5(z).x += 7;
|
|
assert(z[2].x == 10);
|
|
RetRefStruct m = RetRefStruct(7, 'c');
|
|
m.x = 6;
|
|
reffunc7(m) += 3;
|
|
assert(m.x == 9);
|
|
return b.x - 1;
|
|
}
|
|
|
|
int retRefTest3()
|
|
{
|
|
RetRefStruct b = RetRefStruct(0, 'a');
|
|
auto deleg = function (RetRefStruct a){ return a; };
|
|
typeof(deleg)[3] z;
|
|
z[] = deleg;
|
|
auto y = deleg(b).x + 27;
|
|
b.x = 5;
|
|
assert(y == 27);
|
|
y = z[1](b).x + 22;
|
|
return y - 1;
|
|
}
|
|
|
|
int retRefTest4()
|
|
{
|
|
RetRefStruct b = RetRefStruct(0, 'a');
|
|
reffunc3(b.x) = 218;
|
|
assert(b.x == 218);
|
|
return b.x;
|
|
}
|
|
|
|
static assert(retRefTest1() == 2);
|
|
static assert(retRefTest2() == 2);
|
|
static assert(retRefTest3() == 26);
|
|
static assert(retRefTest4() == 218);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7887
|
|
// assign to returned reference
|
|
|
|
bool test7887()
|
|
{
|
|
ref int f(ref int x) { return x; }
|
|
int a;
|
|
f(a) = 42;
|
|
return (a == 42);
|
|
}
|
|
static assert(test7887());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7473
|
|
// struct non-ref
|
|
|
|
struct S7473
|
|
{
|
|
int i;
|
|
}
|
|
|
|
static assert({
|
|
S7473 s = S7473(1);
|
|
assert(s.i == 1);
|
|
bug7473(s);
|
|
assert(s.i == 1);
|
|
return true;
|
|
}());
|
|
|
|
void bug7473(S7473 s)
|
|
{
|
|
s.i = 2;
|
|
}
|
|
|
|
struct S7473b
|
|
{
|
|
S7473 m;
|
|
}
|
|
|
|
static assert({
|
|
S7473b s = S7473b(S7473(7));
|
|
assert(s.m.i == 7);
|
|
bug7473b(s);
|
|
assert(s.m.i == 7);
|
|
return true;
|
|
}());
|
|
|
|
void bug7473b(S7473b s)
|
|
{
|
|
s.m.i = 2;
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4389
|
|
|
|
int bug4389()
|
|
{
|
|
string s;
|
|
dchar c = '\u2348';
|
|
s ~= c;
|
|
assert(s.length == 3);
|
|
dchar d = 'D';
|
|
s ~= d;
|
|
assert(s.length == 4);
|
|
s = "";
|
|
s ~= c;
|
|
assert(s.length == 3);
|
|
s ~= d;
|
|
assert(s.length == 4);
|
|
string z;
|
|
wchar w = '\u0300';
|
|
z ~= w;
|
|
assert(z.length == 2);
|
|
z = "";
|
|
z ~= w;
|
|
assert(z.length == 2);
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug4389());
|
|
|
|
// ICE(constfold.c)
|
|
int ice4389()
|
|
{
|
|
string s;
|
|
dchar c = '\u2348';
|
|
s ~= c;
|
|
s = s ~ "xxx";
|
|
return 1;
|
|
}
|
|
|
|
static assert(ice4389());
|
|
|
|
// ICE(expression.c)
|
|
string ice4390()
|
|
{
|
|
string s;
|
|
dchar c = '`';
|
|
s ~= c;
|
|
s ~= c;
|
|
return s;
|
|
}
|
|
|
|
static assert(mixin(ice4390()) == ``);
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=5248
|
|
// (D1 + D2)
|
|
struct Leaf5248
|
|
{
|
|
string Compile_not_ovloaded()
|
|
{
|
|
return "expression";
|
|
}
|
|
}
|
|
struct Matrix5248
|
|
{
|
|
Leaf5248 Right;
|
|
|
|
string Compile()
|
|
{
|
|
return Right.Compile_not_ovloaded();
|
|
}
|
|
};
|
|
|
|
static assert(Matrix5248().Compile());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4837
|
|
// >>>=
|
|
|
|
bool bug4837()
|
|
{
|
|
ushort x = 0x89AB;
|
|
x >>>= 4;
|
|
assert(x == 0x89A);
|
|
byte y = 0x7C;
|
|
y >>>= 2;
|
|
assert(y == 0x1F);
|
|
return true;
|
|
}
|
|
|
|
static assert(bug4837());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10252
|
|
// shift out of range
|
|
|
|
int lshr10252(int shift)
|
|
{
|
|
int a = 5;
|
|
return a << shift;
|
|
}
|
|
|
|
int rshr10252(int shift)
|
|
{
|
|
int a = 5;
|
|
return a >> shift;
|
|
}
|
|
|
|
int ushr10252(int shift)
|
|
{
|
|
int a = 5;
|
|
return a >>> shift;
|
|
}
|
|
|
|
static assert( is(typeof(compiles!(lshr10252( 4)))));
|
|
static assert(!is(typeof(compiles!(lshr10252(60)))));
|
|
static assert( is(typeof(compiles!(rshr10252( 4)))));
|
|
static assert(!is(typeof(compiles!(rshr10252(80)))));
|
|
static assert( is(typeof(compiles!(ushr10252( 2)))));
|
|
static assert(!is(typeof(compiles!(ushr10252(60)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=1982
|
|
// CTFE null problems
|
|
|
|
enum a1982 = [1, 2, 3];
|
|
static assert(a1982 !is null);
|
|
|
|
string foo1982() { return null; }
|
|
static assert(foo1982() is null);
|
|
static assert(!foo1982().length);
|
|
|
|
static assert(null is null);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7988
|
|
// CTFE return values should be allowed in compile-time expressions
|
|
|
|
class X7988 { int y; this() { y = 2; } }
|
|
static assert((new X7988).y == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8253
|
|
// ICE: calling of member function of non-CTFE class variable
|
|
|
|
class Bug8253
|
|
{
|
|
bool j()
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
Bug8253 m8253;
|
|
static assert(!is(typeof(compiles!(m8253.j()))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8285
|
|
// Issue with slice returned from CTFE function
|
|
|
|
string foo8285()
|
|
{
|
|
string s = "ab";
|
|
return s[0 .. $];
|
|
}
|
|
|
|
template T8285b(string s) { }
|
|
|
|
template T8285a()
|
|
{
|
|
enum s = foo8285();
|
|
alias T8285b!(s) t2;
|
|
}
|
|
|
|
int bar8285()
|
|
{
|
|
alias T8285a!() t1;
|
|
return 0;
|
|
}
|
|
|
|
int baz8285(int x)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static assert(baz8285(bar8285()) == 0);
|
|
|
|
// test case 2
|
|
|
|
string xbar8285()
|
|
{
|
|
string s = "ab";
|
|
return s[0 .. $];
|
|
}
|
|
|
|
template xT8285a()
|
|
{
|
|
enum xT8285a = xbar8285()[0 .. $];
|
|
}
|
|
|
|
string xbaz8285()
|
|
{
|
|
return xT8285a!();
|
|
}
|
|
|
|
string xfoo8285(string s)
|
|
{
|
|
return s;
|
|
}
|
|
|
|
static assert(xfoo8285(xbaz8285()) == "ab");
|
|
|
|
/**************************************************
|
|
'this' parameter bug revealed during refactoring
|
|
**************************************************/
|
|
|
|
int thisbug1(int x) { return x; }
|
|
|
|
struct ThisBug1
|
|
{
|
|
int m = 1;
|
|
int wut()
|
|
{
|
|
return thisbug1(m);
|
|
}
|
|
}
|
|
|
|
int thisbug2()
|
|
{
|
|
ThisBug1 spec;
|
|
return spec.wut();
|
|
}
|
|
|
|
static assert(thisbug2());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6972
|
|
// ICE with cast()cast()assign
|
|
|
|
int bug6972()
|
|
{
|
|
ubyte n = 6;
|
|
n /= 2u;
|
|
return n;
|
|
}
|
|
static assert(bug6972() == 3);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6164
|
|
|
|
size_t bug6164()
|
|
{
|
|
int[] ctfe2(int n)
|
|
{
|
|
int[] r = [];
|
|
if (n != 0)
|
|
r ~= [1] ~ ctfe2(n - 1);
|
|
return r;
|
|
}
|
|
return ctfe2(2).length;
|
|
}
|
|
static assert(bug6164() == 2);
|
|
|
|
/**************************************************
|
|
Interpreter code coverage tests
|
|
**************************************************/
|
|
|
|
int cov1(int a)
|
|
{
|
|
a %= 15382;
|
|
a /= 5;
|
|
a = ~ a;
|
|
bool c = (a == 0);
|
|
bool b = true && c;
|
|
assert(b == 0);
|
|
b = false && c;
|
|
assert(b == 0);
|
|
b = false || c;
|
|
assert(b == 0);
|
|
a ^= 0x45349;
|
|
a = ~ a;
|
|
a &= 0xFF3F;
|
|
a >>>= 1;
|
|
a = a ^ 0x7393;
|
|
a = a >> 1;
|
|
a = a >>> 1;
|
|
a = a | 0x010101;
|
|
return a;
|
|
}
|
|
static assert(cov1(534564) == 71589);
|
|
|
|
int cov2()
|
|
{
|
|
int i = 0;
|
|
do
|
|
{
|
|
goto DOLABEL;
|
|
DOLABEL:
|
|
if (i != 0)
|
|
{
|
|
goto IFLABEL;
|
|
IFLABEL:
|
|
switch(i)
|
|
{
|
|
case 3:
|
|
break;
|
|
case 6:
|
|
goto SWITCHLABEL;
|
|
SWITCHLABEL:
|
|
i = 27;
|
|
goto case 3;
|
|
default:
|
|
assert(0);
|
|
}
|
|
return i;
|
|
}
|
|
i = 6;
|
|
} while(true);
|
|
return 88; // unreachable
|
|
}
|
|
static assert(cov2() == 27);
|
|
|
|
template CovTuple(T...)
|
|
{
|
|
alias T CovTuple;
|
|
}
|
|
|
|
alias CovTuple!(int, long) TCov3;
|
|
|
|
int cov3(TCov3 t)
|
|
{
|
|
TCov3 s;
|
|
s = t;
|
|
assert(s[0] == 1);
|
|
assert(s[1] == 2);
|
|
return 7;
|
|
}
|
|
static assert(cov3(1, 2) == 7);
|
|
|
|
int badassert1(int z)
|
|
{
|
|
assert(z == 5, "xyz");
|
|
return 1;
|
|
}
|
|
|
|
size_t badslice1(int[] z)
|
|
{
|
|
return z[0 .. 3].length;
|
|
}
|
|
|
|
size_t badslice2(int[] z)
|
|
{
|
|
return z[0 .. badassert1(1)].length;
|
|
}
|
|
|
|
size_t badslice3(int[] z)
|
|
{
|
|
return z[badassert1(1) .. 2].length;
|
|
}
|
|
|
|
static assert(!is(typeof(compiles!(badassert1(67)))));
|
|
static assert( is(typeof(compiles!(badassert1(5)))));
|
|
static assert(!is(typeof(compiles!(badslice1([1,2])))));
|
|
static assert(!is(typeof(compiles!(badslice2([1,2])))));
|
|
static assert(!is(typeof(compiles!(badslice3([1,2,3])))));
|
|
|
|
/*******************************************/
|
|
|
|
int bug7894()
|
|
{
|
|
for (int k = 0; k < 2; ++k)
|
|
{
|
|
goto Lagain;
|
|
Lagain:
|
|
;
|
|
}
|
|
int m = 1;
|
|
do
|
|
{
|
|
++m;
|
|
goto Ldo;
|
|
Ldo: ;
|
|
} while (m < 3);
|
|
assert(m == 3);
|
|
|
|
return 1;
|
|
}
|
|
static assert(bug7894());
|
|
|
|
/*******************************************/
|
|
|
|
size_t bug5524(int x, int[] more...)
|
|
{
|
|
int[0] zz;
|
|
assert(zz.length == 0);
|
|
return 7 + more.length + x;
|
|
}
|
|
static assert(bug5524(3) == 10);
|
|
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=5722
|
|
|
|
static assert(("" ~ "\©"[0]).length == 1);
|
|
const char[] null5722 = null;
|
|
static assert((null5722 ~ "\©"[0]).length == 1);
|
|
static assert(("\©"[0] ~ null5722).length == 1);
|
|
|
|
/*******************************************
|
|
* Tests for CTFE Array support.
|
|
* https://issues.dlang.org/show_bug.cgi?id=1330
|
|
* https://issues.dlang.org/show_bug.cgi?id=3801
|
|
* https://issues.dlang.org/show_bug.cgi?id=3835
|
|
* https://issues.dlang.org/show_bug.cgi?id=4050
|
|
* https://issues.dlang.org/show_bug.cgi?id=4051
|
|
* https://issues.dlang.org/show_bug.cgi?id=5147
|
|
* and major functionality
|
|
*******************************************/
|
|
|
|
char[] bug1330StringIndex()
|
|
{
|
|
char[] blah = "foo".dup;
|
|
assert(blah == "foo");
|
|
char[] s = blah[0 .. 2];
|
|
blah[0] = 'h';
|
|
assert(s == "ho");
|
|
s[0] = 'm';
|
|
return blah;
|
|
}
|
|
static assert(bug1330StringIndex() == "moo");
|
|
static assert(bug1330StringIndex() == "moo"); // check we haven't clobbered any string literals
|
|
|
|
int[] bug1330ArrayIndex()
|
|
{
|
|
int[] blah = [1,2,3];
|
|
int[] s = blah;
|
|
s = blah[0 .. 2];
|
|
int z = blah[0] = 6;
|
|
assert(z == 6);
|
|
assert(blah[0] == 6);
|
|
assert(s[0] == 6);
|
|
assert(s == [6, 2]);
|
|
s[1] = 4;
|
|
assert(z == 6);
|
|
return blah;
|
|
}
|
|
static assert(bug1330ArrayIndex() == [6, 4, 3]);
|
|
static assert(bug1330ArrayIndex() == [6, 4, 3]); // check we haven't clobbered any literals
|
|
|
|
char[] bug1330StringSliceAssign()
|
|
{
|
|
char[] blah = "food".dup;
|
|
assert(blah == "food");
|
|
char[] s = blah[1 .. 4];
|
|
blah[0 .. 2] = "hc";
|
|
assert(s == "cod");
|
|
s[0 .. 2] = ['a', 'b']; // Mix string + array literal
|
|
assert(blah == "habd");
|
|
s[0 .. 2] = "mq";
|
|
return blah;
|
|
}
|
|
static assert(bug1330StringSliceAssign() == "hmqd");
|
|
static assert(bug1330StringSliceAssign() == "hmqd");
|
|
|
|
int[] bug1330ArraySliceAssign()
|
|
{
|
|
int[] blah = [1, 2, 3, 4];
|
|
int[] s = blah[1 .. 4];
|
|
blah[0 .. 2] = [7, 9];
|
|
assert(s == [9, 3, 4]);
|
|
s[0 .. 2] = [8, 15];
|
|
return blah;
|
|
}
|
|
static assert(bug1330ArraySliceAssign() == [7, 8, 15, 4]);
|
|
|
|
int[] bug1330ArrayBlockAssign()
|
|
{
|
|
int[] blah = [1, 2, 3, 4, 5];
|
|
int[] s = blah[1 .. 4];
|
|
blah[0 .. 2] = 17;
|
|
assert(s == [17, 3, 4]);
|
|
s[0 .. 2] = 9;
|
|
return blah;
|
|
}
|
|
static assert(bug1330ArrayBlockAssign() == [17, 9, 9, 4, 5]);
|
|
|
|
char[] bug1330StringBlockAssign()
|
|
{
|
|
char[] blah = "abcde".dup;
|
|
char[] s = blah[1 .. 4];
|
|
blah[0 .. 2] = 'x';
|
|
assert(s == "xcd");
|
|
s[0 .. 2] = 'y';
|
|
return blah;
|
|
}
|
|
static assert(bug1330StringBlockAssign() == "xyyde");
|
|
|
|
int assignAA(int x)
|
|
{
|
|
int[int] aa;
|
|
int[int] cc = aa;
|
|
assert(cc.values.length == 0);
|
|
assert(cc.keys.length == 0);
|
|
aa[1] = 2;
|
|
aa[x] = 6;
|
|
int[int] bb = aa;
|
|
assert(bb.keys.length == 2);
|
|
assert(cc.keys.length == 0); // cc is not affected to aa, because it is null
|
|
aa[500] = 65;
|
|
assert(bb.keys.length == 3); // but bb is affected by changes to aa
|
|
return aa[1] + aa[x];
|
|
}
|
|
static assert(assignAA(12) == 8);
|
|
|
|
template Compileable(int z) { bool OK; }
|
|
|
|
int arraybounds(int j, int k)
|
|
{
|
|
int[] xxx = [1, 2, 3, 4, 5];
|
|
int[] s = xxx[1 .. $];
|
|
s = s[j .. k]; // slice of slice
|
|
return s[$ - 1];
|
|
}
|
|
static assert(!is(typeof(Compileable!(arraybounds(1, 14)))));
|
|
static assert(!is(typeof(Compileable!(arraybounds(15, 3)))));
|
|
static assert(arraybounds(2, 4) == 5);
|
|
|
|
int arraybounds2(int j, int k)
|
|
{
|
|
int[] xxx = [1, 2, 3, 4, 5];
|
|
int[] s = xxx[j .. k]; // direct slice
|
|
return 1;
|
|
}
|
|
static assert(!is(typeof(Compileable!(arraybounds2(1, 14)))));
|
|
static assert(!is(typeof(Compileable!(arraybounds2(15, 3)))));
|
|
static assert(arraybounds2(2, 4) == 1);
|
|
|
|
int bug5147a()
|
|
{
|
|
int[1][2] a = 37;
|
|
return a[0][0];
|
|
}
|
|
static assert(bug5147a() == 37);
|
|
|
|
int bug5147b()
|
|
{
|
|
int[4][2][3][17] a = 37;
|
|
return a[0][0][0][0];
|
|
}
|
|
static assert(bug5147b() == 37);
|
|
|
|
int setlen()
|
|
{
|
|
int[][] zzz;
|
|
zzz.length = 2;
|
|
zzz[0].length = 10;
|
|
assert(zzz.length == 2);
|
|
assert(zzz[0].length == 10);
|
|
assert(zzz[1].length == 0);
|
|
return 2;
|
|
}
|
|
static assert(setlen() == 2);
|
|
|
|
int[1][1] bug5147()
|
|
{
|
|
int[1][1] a = 1;
|
|
return a;
|
|
}
|
|
static assert(bug5147() == [[1]]);
|
|
|
|
enum int[1][1] enum5147 = bug5147();
|
|
static assert(enum5147 == [[1]]);
|
|
|
|
immutable int[1][1] bug5147imm = bug5147();
|
|
|
|
// Index referencing
|
|
int[2][2] indexref1()
|
|
{
|
|
int[2][2] a = 2;
|
|
a[0] = 7;
|
|
|
|
int[][] b = [null, null];
|
|
b[0 .. $] = a[0][0 .. 2];
|
|
assert(b[0][0] == 7);
|
|
assert(b[0][1] == 7);
|
|
int[] w;
|
|
w = a[0];
|
|
assert(w[0] == 7);
|
|
w[0 .. $] = 5;
|
|
assert(a[0] != [7, 7]);
|
|
assert(a[0] == [5, 5]);
|
|
assert(b[0] == [5, 5]);
|
|
return a;
|
|
}
|
|
int[2][2] indexref2()
|
|
{
|
|
int[2][2] a = 2;
|
|
a[0] = 7;
|
|
|
|
int[][2] b = null;
|
|
b[0 .. $] = a[0];
|
|
assert(b[0][0] == 7);
|
|
assert(b[0][1] == 7);
|
|
assert(b == [[7, 7], [7, 7]]);
|
|
int[] w;
|
|
w = a[0];
|
|
assert(w[0] == 7);
|
|
w[0 .. $] = 5;
|
|
assert(a[0] != [7, 7]);
|
|
assert(a[0] == [5, 5]);
|
|
assert(b[0] == [5, 5]);
|
|
return a;
|
|
}
|
|
int[2][2] indexref3()
|
|
{
|
|
int[2][2] a = 2;
|
|
a[0]=7;
|
|
|
|
int[][2] b = [null, null];
|
|
b[0 .. $] = a[0];
|
|
assert(b[0][0] == 7);
|
|
assert(b[0][1] == 7);
|
|
int[] w;
|
|
w = a[0];
|
|
assert(w[0] == 7);
|
|
w[0 .. $] = 5;
|
|
assert(a[0] != [7, 7]);
|
|
assert(a[0] == [5, 5]);
|
|
assert(b[0] == [5, 5]);
|
|
return a;
|
|
}
|
|
int[2][2] indexref4()
|
|
{
|
|
int[2][2] a = 2;
|
|
a[0] = 7;
|
|
|
|
int[][2] b =[[1, 2, 3], [1, 2, 3]]; // wrong code
|
|
b[0] = a[0];
|
|
assert(b[0][0] == 7);
|
|
assert(b[0][1] == 7);
|
|
int[] w;
|
|
w = a[0]; //[0 .. $];
|
|
assert(w[0] == 7);
|
|
w[0 .. $] = 5;
|
|
assert(a[0] != [7, 7]);
|
|
assert(a[0] == [5, 5]);
|
|
assert(b[0] == [5, 5]);
|
|
return a;
|
|
}
|
|
static assert(indexref1() == [[5, 5], [2, 2]]);
|
|
static assert(indexref2() == [[5, 5], [2, 2]]);
|
|
static assert(indexref3() == [[5, 5], [2, 2]]);
|
|
static assert(indexref4() == [[5, 5], [2, 2]]);
|
|
|
|
int staticdynamic()
|
|
{
|
|
int[2][1] a = 2;
|
|
assert(a == [[2, 2]]);
|
|
|
|
int[][1] b = a[0][0 .. 1];
|
|
assert(b[0] == [2]);
|
|
auto k = b[0];
|
|
auto m = a[0][0 .. 1];
|
|
assert(k == [2]);
|
|
assert(m == k);
|
|
return 0;
|
|
}
|
|
static assert(staticdynamic() == 0);
|
|
|
|
int chainassign()
|
|
{
|
|
int[4] x = 6;
|
|
int[] y = new int[4];
|
|
auto k = (y[] = (x[] = 2));
|
|
return k[0];
|
|
}
|
|
static assert(chainassign() == 2);
|
|
|
|
// index assignment
|
|
struct S3801
|
|
{
|
|
char c;
|
|
int[3] arr;
|
|
|
|
this(int x, int y)
|
|
{
|
|
c = 'x';
|
|
arr[0] = x;
|
|
arr[1] = y;
|
|
}
|
|
}
|
|
|
|
int bug3801()
|
|
{
|
|
S3801 xxx = S3801(17, 67);
|
|
int[] w = xxx.arr;
|
|
xxx.arr[1] = 89;
|
|
assert(xxx.arr[0] == 17);
|
|
assert(w[1] == 89);
|
|
assert(w == [17, 89, 0]);
|
|
return xxx.arr[1];
|
|
}
|
|
|
|
enum : S3801 { bug3801e = S3801(17, 18) }
|
|
static assert(bug3801e.arr == [17, 18, 0]);
|
|
|
|
immutable S3801 bug3801u = S3801(17, 18);
|
|
static assert(bug3801u.arr == [17, 18, 0]);
|
|
static assert(bug3801() == 89);
|
|
|
|
int bug3835()
|
|
{
|
|
int[4] arr;
|
|
arr[] = 19;
|
|
arr[0] = 4;
|
|
int kk;
|
|
foreach (ref el; arr)
|
|
{
|
|
el += 10;
|
|
kk = el;
|
|
}
|
|
assert(arr[2] == 29);
|
|
arr[0] += 3;
|
|
return arr[0];
|
|
}
|
|
static assert(bug3835() == 17);
|
|
|
|
auto bug5852(const(string) s)
|
|
{
|
|
string[] r;
|
|
r ~= s;
|
|
assert(r.length == 1);
|
|
return r[0].length;
|
|
}
|
|
static assert(bug5852("abc") == 3);
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=7217
|
|
|
|
struct S7217 { int[] arr; }
|
|
|
|
bool f7217()
|
|
{
|
|
auto s = S7217();
|
|
auto t = s.arr;
|
|
return true;
|
|
}
|
|
static assert(f7217());
|
|
|
|
/*******************************************
|
|
Set array length
|
|
*******************************************/
|
|
|
|
static assert(
|
|
{
|
|
struct W { int[] z; }
|
|
W w;
|
|
w.z.length = 2;
|
|
assert(w.z.length == 2);
|
|
w.z.length = 6;
|
|
assert(w.z.length == 6);
|
|
return true;
|
|
}());
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=7185
|
|
// char[].length = n
|
|
|
|
bool bug7185()
|
|
{
|
|
auto arr = new char[2];
|
|
auto arr2 = new char[2];
|
|
arr2[] = "ab";
|
|
arr.length = 1;
|
|
arr2.length = 7;
|
|
assert(arr.length == 1);
|
|
assert(arr2.length == 7);
|
|
assert(arr2[0 .. 2] == "ab");
|
|
return true;
|
|
}
|
|
static assert(bug7185());
|
|
|
|
bool bug9908()
|
|
{
|
|
static const int[3] sa = 1;
|
|
return sa == [1, 1, 1];
|
|
}
|
|
static assert(bug9908());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6934
|
|
|
|
struct Struct6934
|
|
{
|
|
int[] x = [1, 2];
|
|
}
|
|
|
|
void bar6934(ref int[] p)
|
|
{
|
|
p[0] = 12;
|
|
assert(p[0] == 12);
|
|
p[0 .. 1] = 17;
|
|
assert(p[0] == 17);
|
|
p = p[1 .. $];
|
|
}
|
|
|
|
int bug6934()
|
|
{
|
|
Struct6934 q;
|
|
bar6934(q.x);
|
|
int[][] y = [[2, 5], [3, 6, 8]];
|
|
bar6934(y[0]);
|
|
return 1;
|
|
}
|
|
static assert(bug6934());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5671
|
|
|
|
static assert(['a', 'b'] ~ "c" == "abc");
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8624
|
|
|
|
int evil8624()
|
|
{
|
|
long m = 0x1_0000_0000L;
|
|
assert(m != 0);
|
|
long[] a = [0x1_0000_0000L];
|
|
long[] b = [0x4_0000_0000L];
|
|
assert(a[] != b[]);
|
|
return 1;
|
|
}
|
|
static assert(evil8624());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8644
|
|
// array literal >,<
|
|
|
|
int bug8644()
|
|
{
|
|
auto m = "a";
|
|
auto z = ['b'];
|
|
auto c = "b7";
|
|
auto d = ['b', '6'];
|
|
assert(m < z);
|
|
assert(z > m);
|
|
assert(z <= c);
|
|
assert(c > z);
|
|
assert(c > d);
|
|
assert(d >= d);
|
|
return true;
|
|
}
|
|
static assert(bug8644());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6159
|
|
|
|
struct A6159 {}
|
|
|
|
static assert({ return A6159.init is A6159.init; }());
|
|
static assert({ return [1] is [1]; }());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5685
|
|
|
|
string bug5685()
|
|
{
|
|
return "xxx";
|
|
}
|
|
struct Bug5865
|
|
{
|
|
void test1()
|
|
{
|
|
enum file2 = (bug5685())[0 .. $];
|
|
}
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6235
|
|
// Regression ICE on $ in template
|
|
|
|
struct Bug6235(R)
|
|
{
|
|
enum XXX = is(typeof(R.init[0 .. $]) : const ubyte[]);
|
|
}
|
|
|
|
Bug6235!(ubyte[]) bug6235;
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8673
|
|
// ICE
|
|
|
|
enum dollar8673 = [0][(() => $ - 1)()];
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5840
|
|
|
|
struct Bug5840
|
|
{
|
|
string g;
|
|
int w;
|
|
}
|
|
|
|
int bug5840(int u)
|
|
{
|
|
// check for clobbering
|
|
Bug5840 x = void;
|
|
x.w = 4;
|
|
x.g = "3gs";
|
|
if (u == 1)
|
|
bug5840(2);
|
|
if (u == 2)
|
|
{
|
|
x.g = "abc";
|
|
x.w = 3465;
|
|
}
|
|
else
|
|
{
|
|
assert(x.g == "3gs");
|
|
assert(x.w == 4);
|
|
}
|
|
return 56;
|
|
}
|
|
static assert(bug5840(1) == 56);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7810
|
|
|
|
int bug7810()
|
|
{
|
|
int[1][3] x = void;
|
|
x[0] = [2];
|
|
x[1] = [7];
|
|
assert(x[0][0] == 2);
|
|
|
|
char[1][3] y = void;
|
|
y[0] = "a";
|
|
y[1] = "b";
|
|
assert(y[0][0] == 'a');
|
|
|
|
return 1;
|
|
}
|
|
static assert(bug7810());
|
|
|
|
struct Bug7810
|
|
{
|
|
int w;
|
|
}
|
|
int bug7810b(T)(T[] items...)
|
|
{
|
|
assert(items[0] == Bug7810(20));
|
|
return 42;
|
|
}
|
|
static assert(bug7810b(Bug7810(20), Bug7810(10)) == 42);
|
|
|
|
/*******************************************
|
|
std.datetime ICE (30 April 2011)
|
|
*******************************************/
|
|
|
|
struct TimeOfDayZ
|
|
{
|
|
public:
|
|
this(int hour) { }
|
|
invariant() { }
|
|
}
|
|
const testTODsThrownZ = TimeOfDayZ(0);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5954
|
|
|
|
struct Bug5954
|
|
{
|
|
int x;
|
|
this(int xx)
|
|
{
|
|
this.x = xx;
|
|
}
|
|
}
|
|
void bug5954()
|
|
{
|
|
enum f = Bug5954(10);
|
|
static assert(f.x == 10);
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5972
|
|
|
|
int bug5972()
|
|
{
|
|
char[] z = "abc".dup;
|
|
char[][] a = [null, null];
|
|
a[0] = z[0 .. 2];
|
|
char[] b = a[0];
|
|
assert(b == "ab");
|
|
a[0][1] = 'q';
|
|
assert(a[0] == "aq");
|
|
assert(b == "aq");
|
|
assert(b[1] == 'q');
|
|
//a[0][0 .. $ - 1][0 .. $] = a[0][0 .. $ - 1][0 .. $]; // overlap
|
|
return 56;
|
|
}
|
|
static assert(bug5972() == 56);
|
|
|
|
/*******************************************
|
|
2.053beta [CTFE]ICE 'global errors'
|
|
*******************************************/
|
|
|
|
int wconcat(wstring replace)
|
|
{
|
|
wstring value;
|
|
value = "A"w;
|
|
value = value ~ replace;
|
|
return 1;
|
|
}
|
|
static assert(wconcat("X"w));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10397
|
|
// string concat
|
|
|
|
static assert(!is(typeof(compiles!("abc" ~ undefined))));
|
|
static assert(!is(typeof(compiles!(otherundefined ~ "abc"))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9634
|
|
// struct concat
|
|
|
|
struct Bug9634
|
|
{
|
|
int raw;
|
|
}
|
|
|
|
bool bug9634()
|
|
{
|
|
Bug9634[] jr = [Bug9634(42)];
|
|
|
|
Bug9634[] ir = null ~ jr;
|
|
Bug9634[] kr = jr ~ null;
|
|
Bug9634[] mr = jr ~ jr;
|
|
|
|
jr[0].raw = 6;
|
|
assert(ir[0].raw == 42);
|
|
assert(kr[0].raw == 42);
|
|
assert(jr[0].raw == 6);
|
|
assert(&mr[0] != &mr[1]);
|
|
return true;
|
|
}
|
|
|
|
static assert(bug9634());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4001: A Space Oddity
|
|
|
|
int space() { return 4001; }
|
|
|
|
void oddity4001(int q)
|
|
{
|
|
const int bowie = space();
|
|
static assert(space() == 4001);
|
|
static assert(bowie == 4001);
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=3779
|
|
|
|
static const bug3779 = ["123"][0][$ - 1];
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8893
|
|
// ICE with bad struct literal
|
|
|
|
struct Foo8893
|
|
{
|
|
char[3] data;
|
|
}
|
|
int bar8893(Foo8893 f)
|
|
{
|
|
return f.data[0];
|
|
}
|
|
static assert(!is(typeof(compiles!(bar8893(Foo8893(['a','b']))))));
|
|
|
|
/*******************************************
|
|
non-Cow struct literals
|
|
*******************************************/
|
|
|
|
struct Zadok
|
|
{
|
|
int[3] z;
|
|
char[4] s = void;
|
|
ref int[] fog(return ref int[] q) { return q; }
|
|
int bfg()
|
|
{
|
|
z[0] = 56;
|
|
auto zs = z[];
|
|
fog(zs) = [56, 6, 8];
|
|
|
|
assert(z[0] == 56);
|
|
assert(z[1] == 61);
|
|
assert(z[2] == 61);
|
|
|
|
assert(zs[0] == 56);
|
|
assert(zs[1] == 6);
|
|
return zs[2];
|
|
}
|
|
}
|
|
|
|
struct Vug
|
|
{
|
|
Zadok p;
|
|
int[] other;
|
|
}
|
|
|
|
int quop()
|
|
{
|
|
int[] heap = new int[5];
|
|
heap[] = 738;
|
|
Zadok pong;
|
|
pong.z = 3;
|
|
int[] w = pong.z;
|
|
assert(w[0] == 3);
|
|
Zadok phong;
|
|
phong.z = 61;
|
|
pong = phong;
|
|
assert(w[0] == 61);
|
|
Vug b = Vug(Zadok(17, "abcd"));
|
|
b = Vug(Zadok(17, "abcd"), heap);
|
|
b.other[2] = 78;
|
|
assert(heap[2] == 78);
|
|
char[] y = b.p.s;
|
|
assert(y[2] == 'c');
|
|
phong.s = ['z','x','f', 'g'];
|
|
w = b.p.z;
|
|
assert(y[2] == 'c');
|
|
assert(w[0] == 17);
|
|
b.p = phong;
|
|
assert(y[2] == 'f');
|
|
|
|
Zadok wok = Zadok(6, "xyzw");
|
|
b.p = wok;
|
|
assert(y[2] == 'z');
|
|
b.p = phong;
|
|
assert(w[0] == 61);
|
|
Vug q;
|
|
q.p = pong;
|
|
return pong.bfg();
|
|
}
|
|
|
|
static assert(quop() == 8);
|
|
static assert(quop() == 8); // check for clobbering
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5676
|
|
// tuple assign of struct that has void opAssign
|
|
|
|
struct S5676
|
|
{
|
|
int x;
|
|
void opAssign(S5676 rhs) { x = rhs.x; }
|
|
}
|
|
|
|
struct Tup5676(E...)
|
|
{
|
|
E g;
|
|
void foo(E values) { g = values; }
|
|
}
|
|
|
|
bool ice5676()
|
|
{
|
|
Tup5676!(S5676) q;
|
|
q.foo(S5676(3));
|
|
assert(q.g[0].x == 3);
|
|
return true;
|
|
}
|
|
|
|
static assert(ice5676());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5682
|
|
// Wrong CTFE with operator overloading
|
|
|
|
struct A
|
|
{
|
|
int n;
|
|
auto opBinary(string op : "*")(A rhs)
|
|
{
|
|
return A(n * rhs.n);
|
|
}
|
|
}
|
|
|
|
A foo(A[] lhs, A[] rhs)
|
|
{
|
|
A current;
|
|
for (size_t k = 0; k < rhs.length; ++k)
|
|
{
|
|
current = lhs[k] * rhs[k];
|
|
}
|
|
return current;
|
|
}
|
|
|
|
auto test()
|
|
{
|
|
return foo([A(1), A(2)], [A(3), A(4)]);
|
|
}
|
|
|
|
static assert(test().n == 8);
|
|
|
|
/**************************************************
|
|
Attempt to modify a read-only string literal
|
|
**************************************************/
|
|
struct Xarg
|
|
{
|
|
char[] s;
|
|
}
|
|
|
|
int zfs(int n)
|
|
{
|
|
char[] m = "exy".dup;
|
|
if (n == 1)
|
|
{
|
|
// it's OK to cast to const, then cast back
|
|
string ss = cast(string)m;
|
|
m = cast(char[])ss;
|
|
m[2]='q';
|
|
return 56;
|
|
}
|
|
auto q = Xarg(cast(char[])"abc");
|
|
assert(q.s[1] == 'b');
|
|
if (n == 2)
|
|
q.s[1] = 'p';
|
|
else if (n == 3)
|
|
q.s[0 .. $] = 'p';
|
|
char* w = &q.s[2];
|
|
if (n == 4)
|
|
*w = 'z';
|
|
return 76;
|
|
}
|
|
|
|
static assert(!is(typeof(compiles!(zfs(2)))));
|
|
static assert(!is(typeof(compiles!(zfs(3)))));
|
|
static assert(!is(typeof(compiles!(zfs(4)))));
|
|
static assert( is(typeof(compiles!(zfs(1)))));
|
|
static assert( is(typeof(compiles!(zfs(5)))));
|
|
|
|
/**************************************************
|
|
.dup must protect string literals
|
|
**************************************************/
|
|
|
|
string mutateTheImmutable(immutable string _s)
|
|
{
|
|
char[] s = _s.dup;
|
|
foreach (ref c; s)
|
|
c = 'x';
|
|
return s.idup;
|
|
}
|
|
|
|
string doharm(immutable string _name)
|
|
{
|
|
return mutateTheImmutable(_name[2 .. $].idup);
|
|
}
|
|
|
|
enum victimLiteral = "CL_INVALID_CONTEXT";
|
|
|
|
enum thug = doharm(victimLiteral);
|
|
static assert(victimLiteral == "CL_INVALID_CONTEXT");
|
|
|
|
/**************************************************
|
|
Use $ in a slice of a dotvar slice
|
|
**************************************************/
|
|
|
|
int sliceDollar()
|
|
{
|
|
Xarg z;
|
|
z.s = new char[20];
|
|
z.s[] = 'b';
|
|
z.s = z.s[2 .. $ - 2];
|
|
z.s[$ - 2] = 'c';
|
|
return z.s[$ - 2];
|
|
}
|
|
static assert(sliceDollar() == 'c');
|
|
|
|
/**************************************************
|
|
Variation of 5972 which caused segfault
|
|
**************************************************/
|
|
|
|
int bug5972crash()
|
|
{
|
|
char[] z = "abc".dup;
|
|
char[][] a = [null, null];
|
|
a[0] = z[0 .. 2];
|
|
a[0][1] = 'q';
|
|
return 56;
|
|
}
|
|
static assert(bug5972crash() == 56);
|
|
|
|
/**************************************************
|
|
String slice assignment through ref parameter
|
|
**************************************************/
|
|
|
|
void popft(A)(ref A a)
|
|
{
|
|
a = a[1 .. $];
|
|
}
|
|
|
|
int sdfgasf()
|
|
{
|
|
auto scp = "abc".dup;
|
|
popft(scp);
|
|
return 1;
|
|
}
|
|
static assert(sdfgasf() == 1);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8830
|
|
// slice of slice.ptr
|
|
|
|
string bug8830(string s)
|
|
{
|
|
auto ss = s[1 .. $];
|
|
return ss.ptr[0 .. 2];
|
|
}
|
|
static assert(bug8830("hello") == "el");
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8608
|
|
// ICE
|
|
|
|
void bug8608(ref int m) {}
|
|
void test8608()
|
|
{
|
|
int z;
|
|
int foo(bool b)
|
|
{
|
|
if (b)
|
|
bug8608(z);
|
|
return 1;
|
|
}
|
|
static assert( is(typeof(compiles!(foo(false)))));
|
|
static assert(!is(typeof(compiles!(foo(true) ))));
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7770
|
|
|
|
immutable char[] foo7770 = "abcde";
|
|
|
|
int bug7770a(string a)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
bool bug7770b(char c)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static assert(bug7770a(foo7770[0 .. $]));
|
|
static assert(bug7770b(foo7770[$ - 2]));
|
|
|
|
void baz7770()
|
|
{
|
|
static assert(bug7770a(foo7770[0 .. $]));
|
|
static assert(bug7770b(foo7770[$ - 2]));
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8601
|
|
// ICE
|
|
|
|
dchar bug8601(dstring s)
|
|
{
|
|
dstring w = s[1 .. $];
|
|
return w[0];
|
|
}
|
|
|
|
enum dstring e8601 = [cast(dchar)'o', 'n'];
|
|
static assert(bug8601(e8601) == 'n');
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6015
|
|
|
|
struct Foo6015
|
|
{
|
|
string field;
|
|
}
|
|
|
|
bool func6015(string input)
|
|
{
|
|
Foo6015 foo;
|
|
foo.field = input[0 .. $];
|
|
assert(foo.field == "test");
|
|
foo.field = "test2";
|
|
assert(foo.field != "test");
|
|
assert(foo.field == "test2");
|
|
return true;
|
|
}
|
|
|
|
static assert(func6015("test"));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6001
|
|
|
|
void bug6001e(ref int[] s)
|
|
{
|
|
int[] r = s;
|
|
s ~= 0;
|
|
}
|
|
bool bug6001f()
|
|
{
|
|
int[] s;
|
|
bug6001e(s);
|
|
return true;
|
|
}
|
|
static assert(bug6001f());
|
|
|
|
// Assignment to AAs
|
|
|
|
void blah(int[char] as)
|
|
{
|
|
auto k = [6: as];
|
|
as = k[6];
|
|
}
|
|
int blaz()
|
|
{
|
|
int[char] q;
|
|
blah(q);
|
|
return 67;
|
|
}
|
|
static assert(blaz() == 67);
|
|
|
|
void bug6001g(ref int[] w)
|
|
{
|
|
w = [88];
|
|
bug6001e(w);
|
|
w[0] = 23;
|
|
}
|
|
|
|
bool bug6001h()
|
|
{
|
|
int[] s;
|
|
bug6001g(s);
|
|
assert(s.length == 2);
|
|
assert(s[1] == 0);
|
|
assert(s[0] == 23);
|
|
return true;
|
|
}
|
|
static assert(bug6001h());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10243
|
|
// wrong code *&arr as ref parameter
|
|
// https://issues.dlang.org/show_bug.cgi?id=10551
|
|
// wrong code (&arr)[0] as ref parameter
|
|
|
|
void bug10243(ref int n)
|
|
{
|
|
n = 3;
|
|
}
|
|
|
|
void bug10551(int* p)
|
|
{
|
|
bug10243(p[0]);
|
|
}
|
|
|
|
bool test10243()
|
|
{
|
|
int[1] arr;
|
|
bug10243(*arr.ptr);
|
|
assert(arr[0] == 3);
|
|
int[1] arr2;
|
|
bug10551(arr2.ptr);
|
|
assert(arr2[0] == 3);
|
|
int v;
|
|
bug10551(&v);
|
|
assert(v == 3);
|
|
return true;
|
|
}
|
|
|
|
static assert(test10243());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4910
|
|
|
|
int bug4910(int a)
|
|
{
|
|
return a;
|
|
}
|
|
|
|
static int var4910;
|
|
static assert(!is(typeof(Compiles!(bug4910(var4910)))));
|
|
|
|
static assert(bug4910(123));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5845
|
|
// Regression(2.041)
|
|
|
|
void test5845(ulong cols) {}
|
|
|
|
uint solve(bool niv, ref ulong cols)
|
|
{
|
|
if (niv)
|
|
solve(false, cols);
|
|
else
|
|
test5845(cols);
|
|
return 65;
|
|
}
|
|
|
|
ulong nqueen(int n)
|
|
{
|
|
ulong cols = 0;
|
|
return solve(true, cols);
|
|
}
|
|
|
|
static assert(nqueen(2) == 65);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5258
|
|
|
|
struct Foo5258 { int x; }
|
|
void bar5258(int n, ref Foo5258 fong)
|
|
{
|
|
if (n)
|
|
bar5258(n - 1, fong);
|
|
else
|
|
fong.x++;
|
|
}
|
|
int bug5258()
|
|
{
|
|
Foo5258 foo5258 = Foo5258();
|
|
bar5258(1, foo5258);
|
|
return 45;
|
|
}
|
|
static assert(bug5258() == 45);
|
|
|
|
struct Foo5258b { int[2] r; }
|
|
void baqopY(int n, ref int[2] fongo)
|
|
{
|
|
if (n)
|
|
baqopY(n - 1, fongo);
|
|
else
|
|
fongo[0]++;
|
|
}
|
|
int bug5258b()
|
|
{
|
|
Foo5258b qq;
|
|
baqopY(1, qq.r);
|
|
return 618;
|
|
}
|
|
static assert(bug5258b() == 618);
|
|
|
|
// Notice that this case involving reassigning the dynamic array
|
|
struct Foo5258c { int[] r; }
|
|
void baqop(int n, ref int[] fongo)
|
|
{
|
|
if (n)
|
|
baqop(n - 1, fongo);
|
|
else
|
|
{
|
|
fongo = new int[20];
|
|
fongo[0]++;
|
|
}
|
|
}
|
|
size_t bug5258c()
|
|
{
|
|
Foo5258c qq;
|
|
qq.r = new int[30];
|
|
baqop(1, qq.r);
|
|
return qq.r.length;
|
|
}
|
|
static assert(bug5258c() == 20);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6049
|
|
|
|
struct Bug6049
|
|
{
|
|
int m;
|
|
this(int x) { m = x; }
|
|
invariant() { }
|
|
}
|
|
|
|
const Bug6049[] foo6049 = [Bug6049(6), Bug6049(17)];
|
|
|
|
static assert(foo6049[0].m == 6);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6052
|
|
|
|
struct Bug6052
|
|
{
|
|
int a;
|
|
}
|
|
|
|
bool bug6052()
|
|
{
|
|
Bug6052[2] arr;
|
|
for (int i = 0; i < 2; ++ i)
|
|
{
|
|
Bug6052 el = {i};
|
|
Bug6052 ek = el;
|
|
arr[i] = el;
|
|
el.a = i + 2;
|
|
assert(ek.a == i); // ok
|
|
assert(arr[i].a == i); // fail
|
|
}
|
|
assert(arr[1].a == 1); // ok
|
|
assert(arr[0].a == 0); // fail
|
|
return true;
|
|
}
|
|
|
|
static assert(bug6052());
|
|
|
|
bool bug6052b()
|
|
{
|
|
int[][1] arr;
|
|
int[1] z = [7];
|
|
arr[0] = z;
|
|
assert(arr[0][0] == 7);
|
|
arr[0] = z;
|
|
z[0] = 3;
|
|
assert(arr[0][0] == 3);
|
|
return true;
|
|
}
|
|
|
|
static assert(bug6052b());
|
|
|
|
struct Bug6052c
|
|
{
|
|
int x;
|
|
this(int a) { x = a; }
|
|
}
|
|
|
|
int bug6052c()
|
|
{
|
|
Bug6052c[] pieces = [];
|
|
for (int c = 0; c < 2; ++ c)
|
|
pieces ~= Bug6052c(c);
|
|
assert(pieces[1].x == 1);
|
|
assert(pieces[0].x == 0);
|
|
return 1;
|
|
}
|
|
static assert(bug6052c() == 1);
|
|
static assert(bug6052c() == 1);
|
|
|
|
|
|
static assert({
|
|
Bug6052c[] pieces = [];
|
|
pieces.length = 2;
|
|
int c = 0;
|
|
pieces[0] = Bug6052c(c);
|
|
++c;
|
|
pieces[1] = Bug6052c(c);
|
|
assert(pieces[0].x == 0);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int[1][] pieces = [];
|
|
pieces.length = 2;
|
|
for (int c = 0; c < 2; ++ c)
|
|
pieces[c][0] = c;
|
|
assert(pieces[1][0] == 1);
|
|
assert(pieces[0][0] == 0);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
Bug6052c[] pieces = [];
|
|
for (int c = 0; c < 2; ++ c)
|
|
pieces ~= Bug6052c(c);
|
|
assert(pieces[1].x == 1);
|
|
assert(pieces[0].x == 0);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int[1] z = 7;
|
|
int[1][] pieces = [z,z];
|
|
pieces[1][0]=3;
|
|
assert(pieces[0][0] == 7);
|
|
pieces = pieces ~ [z,z];
|
|
pieces[3][0] = 16;
|
|
assert(pieces[2][0] == 7);
|
|
pieces = [z,z] ~ pieces;
|
|
pieces[5][0] = 16;
|
|
assert(pieces[4][0] == 7);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6749
|
|
|
|
struct CtState
|
|
{
|
|
string code;
|
|
}
|
|
|
|
CtState bug6749()
|
|
{
|
|
CtState[] pieces;
|
|
CtState r = CtState("correct");
|
|
pieces ~= r;
|
|
r = CtState("clobbered");
|
|
return pieces[0];
|
|
}
|
|
static assert(bug6749().code == "correct");
|
|
|
|
/**************************************************
|
|
Index + slice assign to function returns
|
|
**************************************************/
|
|
|
|
int[] funcRetArr(int[] a)
|
|
{
|
|
return a;
|
|
}
|
|
|
|
int testFuncRetAssign()
|
|
{
|
|
int[] x = new int[20];
|
|
funcRetArr(x)[2] = 4;
|
|
assert(x[2] == 4);
|
|
funcRetArr(x)[] = 27;
|
|
assert(x[15] == 27);
|
|
return 5;
|
|
}
|
|
static assert(testFuncRetAssign() == 5);
|
|
|
|
int keyAssign()
|
|
{
|
|
int[int] pieces;
|
|
pieces[3] = 1;
|
|
pieces.keys[0] = 4;
|
|
pieces.values[0] = 27;
|
|
assert(pieces[3] == 1);
|
|
return 5;
|
|
}
|
|
static assert(keyAssign() == 5);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6054
|
|
// AA literals
|
|
|
|
enum x6054 = {
|
|
auto p = {
|
|
int[string] pieces;
|
|
pieces[['a'].idup] = 1;
|
|
return pieces;
|
|
}();
|
|
return p;
|
|
}();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6077
|
|
|
|
enum bug6077 = {
|
|
string s;
|
|
string t;
|
|
return s ~ t;
|
|
}();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6078
|
|
// Pass null array by ref
|
|
|
|
struct Foo6078
|
|
{
|
|
int[] bar;
|
|
}
|
|
|
|
static assert({
|
|
Foo6078 f;
|
|
int i;
|
|
foreach (ref e; f.bar)
|
|
{
|
|
i += e;
|
|
}
|
|
return i;
|
|
}() == 0);
|
|
|
|
int bug6078(ref int[] z)
|
|
{
|
|
int[] q = z;
|
|
return 2;
|
|
}
|
|
|
|
static assert({
|
|
Foo6078 f;
|
|
return bug6078(f.bar);
|
|
}() == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6079
|
|
// Array bounds checking
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
int[] x = [1, 2, 3, 4];
|
|
x[4] = 1;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6100
|
|
|
|
struct S6100
|
|
{
|
|
int a;
|
|
}
|
|
|
|
S6100 init6100(int x)
|
|
{
|
|
S6100 s = S6100(x);
|
|
return s;
|
|
}
|
|
|
|
static const S6100[2] s6100a = [init6100(1), init6100(2)];
|
|
static assert(s6100a[0].a == 1);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4825
|
|
// failed with -inline
|
|
|
|
int a4825()
|
|
{
|
|
int r;
|
|
return r;
|
|
}
|
|
|
|
int b4825()
|
|
{
|
|
return a4825();
|
|
}
|
|
|
|
void c4825()
|
|
{
|
|
void d()
|
|
{
|
|
auto e = b4825();
|
|
}
|
|
static const int f = b4825();
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5708
|
|
// failed with -inline
|
|
|
|
string b5708(string s) { return s; }
|
|
string a5708(string s) { return b5708(s); }
|
|
|
|
void bug5708()
|
|
{
|
|
void m() { a5708("lit"); }
|
|
static assert(a5708("foo") == "foo");
|
|
static assert(a5708("bar") == "bar");
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6120
|
|
// failed with -inline
|
|
|
|
struct Bug6120(T)
|
|
{
|
|
this(int x) { }
|
|
}
|
|
static assert({
|
|
auto s = Bug6120!int(0);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6123
|
|
// failed with -inline
|
|
|
|
struct Bug6123(T)
|
|
{
|
|
void f() {}
|
|
// can also trigger if the struct is normal but f is template
|
|
}
|
|
static assert({
|
|
auto piece = Bug6123!int();
|
|
piece.f();
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6053
|
|
// ICE involving pointers
|
|
|
|
static assert({
|
|
int* a = null;
|
|
assert(a is null);
|
|
assert(a == null);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int b;
|
|
int* a = &b;
|
|
assert(a !is null);
|
|
*a = 7;
|
|
assert(b == 7);
|
|
assert(*a == 7);
|
|
return true;
|
|
}());
|
|
|
|
int dontbreak6053()
|
|
{
|
|
auto q = &dontbreak6053;
|
|
void caz() {}
|
|
auto tr = &caz;
|
|
return 5;
|
|
}
|
|
static assert(dontbreak6053());
|
|
|
|
static assert({
|
|
int a;
|
|
*(&a) = 15;
|
|
assert(a == 15);
|
|
assert(*(&a) == 15);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int a = 5, b = 6, c = 2;
|
|
assert(*(c ? &a : &b) == 5);
|
|
assert(*(!c ? &a : &b) == 6);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int a, b, c;
|
|
(c ? a : b) = 1;
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int a, b, c = 1;
|
|
int* p = &a;
|
|
(c ? *p : b) = 51;
|
|
assert(a == 51);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************
|
|
Pointer arithmetic, dereference, and comparison
|
|
**************************************************/
|
|
|
|
// dereference null pointer
|
|
static assert(!is(typeof(compiles!({
|
|
int a, b, c = 1;
|
|
int* p;
|
|
(c ? *p : b) = 51;
|
|
return 6;
|
|
}()
|
|
))));
|
|
static assert(!is(typeof(compiles!({
|
|
int* a = null;
|
|
assert(*a != 6);
|
|
return 72;
|
|
}()
|
|
))));
|
|
|
|
// cannot <, > compare pointers to different arrays
|
|
static assert(!is(typeof(compiles!({
|
|
int[5] a, b;
|
|
bool c = (&a[0] > &b[0]);
|
|
return 72;
|
|
}()
|
|
))));
|
|
|
|
// can ==, is, !is, != compare pointers for different arrays
|
|
static assert({
|
|
int[5] a;
|
|
int[5] b;
|
|
assert(!(&a[0] == &b[0]));
|
|
assert(&a[0] != &b[0]);
|
|
assert(!(&a[0] is &b[0]));
|
|
assert(&a[0] !is &b[0]);
|
|
return 72;
|
|
}());
|
|
|
|
static assert({
|
|
int[5] a;
|
|
a[0] = 25;
|
|
a[1] = 5;
|
|
int* b = &a[1];
|
|
assert(*b == 5);
|
|
*b = 34;
|
|
int c = *b;
|
|
*b += 6;
|
|
assert(b == &a[1]);
|
|
assert(b != &a[0]);
|
|
assert(&a[0] < &a[1]);
|
|
assert(&a[0] <= &a[1]);
|
|
assert(!(&a[0] >= &a[1]));
|
|
assert(&a[4] > &a[0]);
|
|
assert(c == 34);
|
|
assert(*b == 40);
|
|
assert(a[1] == 40);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
int[12] x;
|
|
int* p = &x[10];
|
|
int* q = &x[4];
|
|
return p - q;
|
|
}() == 6);
|
|
|
|
static assert({
|
|
int[12] x;
|
|
int* p = &x[10];
|
|
int* q = &x[4];
|
|
q = p;
|
|
assert(p == q);
|
|
q = &x[4];
|
|
assert(p != q);
|
|
q = q + 6;
|
|
assert(q is p);
|
|
return 6;
|
|
}() == 6);
|
|
|
|
static assert({
|
|
int[12] x;
|
|
int[] y = x[2 .. 8];
|
|
int* p = &y[4];
|
|
int* q = &x[6];
|
|
assert(p == q);
|
|
p = &y[5];
|
|
assert(p > q);
|
|
p = p + 5; // OK, as long as we don't dereference
|
|
assert(p > q);
|
|
return 6;
|
|
}() == 6);
|
|
|
|
static assert({
|
|
char[12] x;
|
|
const(char)* p = "abcdef";
|
|
const (char)* q = p;
|
|
q = q + 2;
|
|
assert(*q == 'c');
|
|
assert(q > p);
|
|
assert(q - p == 2);
|
|
assert(p - q == -2);
|
|
q = &x[7];
|
|
p = &x[1];
|
|
assert(q>p);
|
|
return 6;
|
|
}() == 6);
|
|
|
|
// Relations involving null pointers
|
|
bool nullptrcmp()
|
|
{
|
|
// null tests
|
|
void* null1 = null, null2 = null;
|
|
int x = 2;
|
|
void* p = &x;
|
|
assert(null1 == null2);
|
|
assert(null1 is null2);
|
|
assert(null1 <= null2);
|
|
assert(null1 >= null2);
|
|
assert(!(null1 > null2));
|
|
assert(!(null2 > null1));
|
|
assert(null1 != p);
|
|
assert(null1 !is p);
|
|
assert(p != null1);
|
|
assert(p !is null1);
|
|
assert(null1 <= p);
|
|
assert(p >= null2);
|
|
assert(p > null1);
|
|
assert(!(null1 > p));
|
|
return true;
|
|
}
|
|
static assert(nullptrcmp());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10840
|
|
// null pointer in dotvar
|
|
|
|
struct Data10840
|
|
{
|
|
bool xxx;
|
|
}
|
|
|
|
struct Bug10840
|
|
{
|
|
Data10840* _data;
|
|
}
|
|
|
|
enum bug10840 = (int n)
|
|
{
|
|
Bug10840 stack;
|
|
if (n == 1)
|
|
{
|
|
// detect deref through null pointer
|
|
return stack._data.xxx;
|
|
}
|
|
// Wrong-code for ?:
|
|
return stack._data ? false : true;
|
|
};
|
|
|
|
static assert(bug10840(0));
|
|
static assert(!is(typeof(Compileable!(bug10840(1)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8216
|
|
// ptr inside a pointer range
|
|
|
|
// Four-pointer relations. Return true if [p1 .. p2] points inside [q1 .. q2]
|
|
// (where the end points don't coincide).
|
|
bool ptr4cmp(void* p1, void* p2, void* q1, void* q2)
|
|
{
|
|
// Each compare can be written with <, <=, >, or >=.
|
|
// Either && or || can be used, giving 32 permutations.
|
|
// Additionally each compare can be negated with !, yielding 128 in total.
|
|
bool b1 = (p1 > q1 && p2 <= q2);
|
|
bool b2 = (p1 > q1 && p2 < q2);
|
|
bool b3 = (p1 >= q1 && p2 <= q2);
|
|
bool b4 = (p1 >= q1 && p2 < q2);
|
|
|
|
bool b5 = (q1 <= p1 && q2 > p2);
|
|
bool b6 = (q1 <= p1 && q2 >= p2);
|
|
bool b7 = (p2 <= q2 && p1 > q1);
|
|
bool b8 = (!(p1 <= q1) && p2 <= q2);
|
|
bool b9 = (!(p1 <= q1) && !(p2 > q2));
|
|
bool b10 = (!!!(p1 <= q1) && !(p2 > q2));
|
|
|
|
assert(b1 == b2 && b1 == b3 && b1 == b4 && b1 == b5 && b1 == b6);
|
|
assert(b1 == b7 && b1 == b8 && b1 == b9 && b1 == b10);
|
|
|
|
bool c1 = (p1 <= q1 || p2 > q2);
|
|
assert(c1 == !b1);
|
|
bool c2 = (p1 < q1 || p2 >= q2);
|
|
bool c3 = (!(q1 <= p1) || !(q2 >= p2));
|
|
assert(c1 == c2 && c1 == c3);
|
|
return b1;
|
|
}
|
|
|
|
bool bug8216()
|
|
{
|
|
int[4] a;
|
|
int[13] b;
|
|
int v;
|
|
int* p = &v;
|
|
assert(!ptr4cmp(&a[0], &a[3], p, p));
|
|
assert(!ptr4cmp(&b[2], &b[9], &a[1], &a[2]));
|
|
assert(!ptr4cmp(&b[1], &b[9], &b[2], &b[8]));
|
|
assert( ptr4cmp(&b[2], &b[8], &b[1], &b[9]));
|
|
return 1;
|
|
}
|
|
static assert(bug8216());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6517
|
|
// ptr++, ptr--
|
|
|
|
int bug6517()
|
|
{
|
|
int[] arr = [1, 2, 3];
|
|
auto startp = arr.ptr;
|
|
auto endp = arr.ptr + arr.length;
|
|
|
|
for (; startp < endp; startp++) {}
|
|
startp = arr.ptr;
|
|
assert(startp++ == arr.ptr);
|
|
assert(startp != arr.ptr);
|
|
assert(startp-- != arr.ptr);
|
|
assert(startp == arr.ptr);
|
|
|
|
return 84;
|
|
}
|
|
static assert(bug6517() == 84);
|
|
|
|
/**************************************************
|
|
Out-of-bounds pointer assignment and deference
|
|
**************************************************/
|
|
|
|
int ptrDeref(int ofs, bool wantDeref)
|
|
{
|
|
int[5] a;
|
|
int* b = &a[0];
|
|
b = b + ofs; // OK
|
|
if (wantDeref)
|
|
return *b; // out of bounds
|
|
return 72;
|
|
}
|
|
|
|
static assert(!is(typeof(compiles!(ptrDeref(-1, true)))));
|
|
static assert( is(typeof(compiles!(ptrDeref(4, true)))));
|
|
static assert( is(typeof(compiles!(ptrDeref(5, false)))));
|
|
static assert(!is(typeof(compiles!(ptrDeref(5, true)))));
|
|
static assert(!is(typeof(compiles!(ptrDeref(6, false)))));
|
|
static assert(!is(typeof(compiles!(ptrDeref(6, true)))));
|
|
|
|
/**************************************************
|
|
Pointer +=
|
|
**************************************************/
|
|
static assert({
|
|
int[12] x;
|
|
int zzz;
|
|
assert(&zzz);
|
|
int* p = &x[10];
|
|
int* q = &x[4];
|
|
q = p;
|
|
assert(p == q);
|
|
q = &x[4];
|
|
assert(p != q);
|
|
q += 4;
|
|
assert(q == &x[8]);
|
|
q = q - 2;
|
|
q = q + 4;
|
|
assert(q is p);
|
|
return 6;
|
|
}() == 6);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5615
|
|
|
|
const(char)[] passthrough(const(char)[] x)
|
|
{
|
|
return x;
|
|
}
|
|
|
|
ptrdiff_t checkPass(Char1)(const(Char1)[] s)
|
|
{
|
|
const(Char1)[] balance = s[1 .. $];
|
|
return passthrough(balance).ptr - s.ptr;
|
|
}
|
|
static assert(checkPass("foobar") == 1);
|
|
|
|
/**************************************************
|
|
Pointers must not escape from CTFE
|
|
**************************************************/
|
|
|
|
struct Toq
|
|
{
|
|
char* m;
|
|
}
|
|
|
|
Toq ptrRet(bool b)
|
|
{
|
|
char[] x = "abc".dup;
|
|
return Toq(b ? x[0 .. 1].ptr : null);
|
|
}
|
|
|
|
static assert(is(typeof(compiles!({
|
|
enum Toq boz = ptrRet(false); // OK - ptr is null
|
|
Toq z = ptrRet(true); // OK -- ptr doesn't escape
|
|
return 4;
|
|
}()
|
|
))));
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
enum Toq boz = ptrRet(true); // fail - ptr escapes
|
|
return 4;
|
|
}()
|
|
))));
|
|
|
|
/**************************************************
|
|
Pointers to struct members
|
|
**************************************************/
|
|
|
|
struct Qoz
|
|
{
|
|
int w;
|
|
int[3] yof;
|
|
}
|
|
|
|
static assert({
|
|
int[3] gaz;
|
|
gaz[2] = 3156;
|
|
Toq z = ptrRet(true);
|
|
auto p = z.m;
|
|
assert(*z.m == 'a');
|
|
assert(*p == 'a');
|
|
auto q = &z.m;
|
|
assert(*q == p);
|
|
assert(**q == 'a');
|
|
Qoz g = Qoz(2, [5, 6, 7]);
|
|
auto r = &g.w;
|
|
assert(*r == 2);
|
|
r = &g.yof[1];
|
|
assert(*r == 6);
|
|
g.yof[0] = 15;
|
|
++r;
|
|
assert(*r == 7);
|
|
r -= 2;
|
|
assert(*r == 15);
|
|
r = &gaz[0];
|
|
r += 2;
|
|
assert(*r == 3156);
|
|
return *p;
|
|
}() == 'a');
|
|
|
|
struct AList
|
|
{
|
|
AList* next;
|
|
int value;
|
|
static AList* newList()
|
|
{
|
|
AList[] z = new AList[1];
|
|
return &z[0];
|
|
}
|
|
static AList* make(int i, int j)
|
|
{
|
|
auto r = newList();
|
|
r.next = (new AList[1]).ptr;
|
|
r.value = 1;
|
|
AList* z = r.next;
|
|
(*z).value = 2;
|
|
r.next.value = j;
|
|
assert(r.value == 1);
|
|
assert(r.next.value == 2);
|
|
r.next.next = &(new AList[1])[0];
|
|
assert(r.next.next != null);
|
|
assert(r.next.next);
|
|
r.next.next.value = 3;
|
|
assert(r.next.next.value == 3);
|
|
r.next.next = newList();
|
|
r.next.next.value = 9;
|
|
return r;
|
|
}
|
|
static int checkList()
|
|
{
|
|
auto r = make(1,2);
|
|
assert(r.value == 1);
|
|
assert(r.next.value == 2);
|
|
assert(r.next.next.value == 9);
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
static assert(AList.checkList() == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7194
|
|
// pointers as struct members
|
|
|
|
struct S7194 { int* p, p2; }
|
|
|
|
int f7194()
|
|
{
|
|
assert(S7194().p == null);
|
|
assert(!S7194().p);
|
|
assert(S7194().p == S7194().p2);
|
|
S7194 s = S7194();
|
|
assert(!s.p);
|
|
assert(s.p == null);
|
|
assert(s.p == s.p2);
|
|
int x;
|
|
s.p = &x;
|
|
s.p2 = s.p;
|
|
assert(s.p == &x);
|
|
return 0;
|
|
}
|
|
|
|
int g7194()
|
|
{
|
|
auto s = S7194();
|
|
assert(s.p); // should fail
|
|
return 0;
|
|
}
|
|
|
|
static assert(f7194() == 0);
|
|
static assert(!is(typeof(compiles!(g7194()))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7248
|
|
// recursive struct pointers in array
|
|
|
|
struct S7248 { S7248* ptr; }
|
|
|
|
bool bug7248()
|
|
{
|
|
S7248[2] sarr;
|
|
sarr[0].ptr = &sarr[1];
|
|
sarr[0].ptr = null;
|
|
S7248* t = sarr[0].ptr;
|
|
return true;
|
|
}
|
|
static assert(bug7248());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7216
|
|
// calling a struct pointer member
|
|
|
|
struct S7216
|
|
{
|
|
S7216* p;
|
|
int t;
|
|
|
|
void f() { }
|
|
void g() { ++t; }
|
|
}
|
|
|
|
bool bug7216()
|
|
{
|
|
S7216 s0, s1;
|
|
s1.t = 6;
|
|
s0.p = &s1;
|
|
s0.p.f();
|
|
s0.p.g();
|
|
assert(s1.t == 7);
|
|
return true;
|
|
}
|
|
|
|
static assert(bug7216());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10858
|
|
// Wrong code with array of pointers
|
|
|
|
bool bug10858()
|
|
{
|
|
int*[4] x;
|
|
x[0] = null;
|
|
assert(x[0] == null);
|
|
return true;
|
|
}
|
|
static assert(bug10858());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12528
|
|
// painting inout type for value type literals
|
|
|
|
inout(T)[] dup12528(T)(inout(T)[] a)
|
|
{
|
|
inout(T)[] res;
|
|
foreach (ref e; a)
|
|
res ~= e;
|
|
return res;
|
|
}
|
|
|
|
enum arr12528V1 = dup12528([0]);
|
|
enum arr12528V2 = dup12528([0, 1]);
|
|
static assert(arr12528V1 == [0]);
|
|
static assert(arr12528V2 == [0, 1]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9745
|
|
// Allow pointers to static variables
|
|
|
|
shared int x9745;
|
|
shared int[5] y9745;
|
|
|
|
shared(int)* bug9745(int m)
|
|
{
|
|
auto k = &x9745;
|
|
auto j = &x9745;
|
|
auto p = &y9745[0];
|
|
auto q = &y9745[3];
|
|
assert(j - k == 0);
|
|
assert(j == k);
|
|
assert(q - p == 3);
|
|
--q;
|
|
int a = 0;
|
|
assert(p + 2 == q);
|
|
if (m == 7)
|
|
{
|
|
auto z1 = y9745[0 .. 2]; // slice global pointer
|
|
}
|
|
if (m == 8)
|
|
p[1] = 7; // modify through a pointer
|
|
if (m == 9)
|
|
a = p[1]; // read from a pointer
|
|
if (m == 0)
|
|
return &x9745;
|
|
return &y9745[1];
|
|
}
|
|
|
|
int test9745(int m)
|
|
{
|
|
bug9745(m);
|
|
// type painting
|
|
shared int* w = bug9745(0);
|
|
return 1;
|
|
}
|
|
|
|
shared int* w9745a = bug9745(0);
|
|
shared int* w9745b = bug9745(1);
|
|
static assert( is(typeof(compiles!(test9745(6)))));
|
|
static assert(!is(typeof(compiles!(test9745(7)))));
|
|
static assert(!is(typeof(compiles!(test9745(8)))));
|
|
static assert(!is(typeof(compiles!(test9745(9)))));
|
|
|
|
// pointers cast from an absolute address
|
|
// (mostly applies to fake pointers, eg Windows HANDLES)
|
|
bool test9745b()
|
|
{
|
|
void* b6 = cast(void*)0xFEFEFEFE;
|
|
void* b7 = cast(void*)0xFEFEFEFF;
|
|
assert(b6 is b6);
|
|
assert(b7 != b6);
|
|
return true;
|
|
}
|
|
static assert(test9745b());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9364
|
|
// ICE with pointer to local struct
|
|
|
|
struct S9364
|
|
{
|
|
int i;
|
|
}
|
|
|
|
bool bug9364()
|
|
{
|
|
S9364 s;
|
|
auto k = (&s).i;
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug9364());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10251
|
|
// Pointers to const globals
|
|
|
|
static const int glob10251 = 7;
|
|
|
|
const(int)* bug10251()
|
|
{
|
|
return &glob10251;
|
|
}
|
|
|
|
static a10251 = &glob10251; // OK
|
|
static b10251 = bug10251();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4065
|
|
// [CTFE] AA "in" operator doesn't work
|
|
|
|
bool bug4065(string s)
|
|
{
|
|
enum int[string] aa = ["aa":14, "bb":2];
|
|
int* p = s in aa;
|
|
if (s == "aa")
|
|
assert(*p == 14);
|
|
else if (s == "bb")
|
|
assert(*p == 2);
|
|
else
|
|
assert(!p);
|
|
int[string] zz;
|
|
assert(!("xx" in zz));
|
|
bool c = !p;
|
|
return cast(bool)(s in aa);
|
|
}
|
|
|
|
static assert(!bug4065("xx"));
|
|
static assert( bug4065("aa"));
|
|
static assert( bug4065("bb"));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12689
|
|
// assigning via pointer from 'in' expression
|
|
|
|
int g12689()
|
|
{
|
|
int[int] aa;
|
|
aa[1] = 13;
|
|
assert(*(1 in aa) == 13);
|
|
*(1 in aa) = 42;
|
|
return aa[1];
|
|
}
|
|
static assert(g12689() == 42);
|
|
|
|
/**************************************************
|
|
Pointers in ? :
|
|
**************************************************/
|
|
|
|
static assert({
|
|
int[2] x;
|
|
int* p = &x[1];
|
|
return p ? true: false;
|
|
}());
|
|
|
|
/**************************************************
|
|
Pointer slicing
|
|
**************************************************/
|
|
|
|
int ptrSlice()
|
|
{
|
|
auto arr = new int[5];
|
|
int* x = &arr[0];
|
|
int[] y = x[0 .. 5];
|
|
x[1 .. 3] = 6;
|
|
++x;
|
|
x[1 .. 3] = 14;
|
|
assert(arr[1] == 6);
|
|
assert(arr[2] == 14);
|
|
//x[-1 .. 4] = 5; // problematic because negative lower boundary will throw RangeError in runtime
|
|
(x - 1)[0 .. 3] = 5;
|
|
int[] z = arr[1 .. 2];
|
|
z.length = 4;
|
|
z[$ - 1] = 17;
|
|
assert(arr.length == 5);
|
|
return 2;
|
|
}
|
|
static assert(ptrSlice() == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6344
|
|
// create empty slice from null pointer
|
|
|
|
static assert({
|
|
char* c = null;
|
|
auto m = c[0 .. 0];
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8365
|
|
// block assignment of enum arrays
|
|
|
|
enum E8365 { first = 7, second, third, fourth }
|
|
static assert({ E8365[2] x; return x[0]; }() == E8365.first);
|
|
static assert({ E8365[2][2] x; return x[0][0]; }() == E8365.first);
|
|
static assert({ E8365[2][2][2] x; return x[0][0][0]; }() == E8365.first);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4448
|
|
// labelled break + continue
|
|
|
|
int bug4448()
|
|
{
|
|
int n = 2;
|
|
L1:
|
|
do
|
|
{
|
|
switch(n)
|
|
{
|
|
case 5:
|
|
return 7;
|
|
default:
|
|
n = 5;
|
|
break L1;
|
|
}
|
|
int w = 7;
|
|
} while (0);
|
|
return 3;
|
|
}
|
|
static assert(bug4448() == 3);
|
|
|
|
int bug4448b()
|
|
{
|
|
int n = 2;
|
|
L1:
|
|
for (n = 2; n < 5; ++n)
|
|
{
|
|
for (int m = 1; m < 6; ++m)
|
|
{
|
|
if (n < 3)
|
|
{
|
|
assert(m == 1);
|
|
continue L1;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return 3;
|
|
}
|
|
static assert(bug4448b() == 3);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6985
|
|
// Formerly, non-constant case, but switch cases with mutable cases now error
|
|
// Currently: run-time constant variable case
|
|
|
|
int bug6985(int z)
|
|
{
|
|
const int q = z * 2 - 6;
|
|
switch(z)
|
|
{
|
|
case q:
|
|
return 87;
|
|
default:
|
|
}
|
|
return q;
|
|
}
|
|
static assert(bug6985(6) == 87);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6281
|
|
// [CTFE] A null pointer '!is null' returns 'true'
|
|
|
|
static assert(!{
|
|
auto p = null;
|
|
return p !is null;
|
|
}());
|
|
|
|
static assert(!{
|
|
auto p = null;
|
|
return p != null;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6331
|
|
// evaluate SliceExp on if condition
|
|
|
|
bool bug6331(string s)
|
|
{
|
|
if (s[0 .. 1])
|
|
return true;
|
|
return false;
|
|
}
|
|
static assert(bug6331("str"));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6283
|
|
// assign to AA with slice as index
|
|
|
|
static assert({
|
|
immutable p = "pp";
|
|
int[string] pieces = [p: 0];
|
|
pieces["qq"] = 1;
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
immutable renames = [0: "pp"];
|
|
int[string] pieces;
|
|
pieces[true ? renames[0] : "qq"] = 1;
|
|
pieces["anything"] = 1;
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
immutable qq = "qq";
|
|
string q = qq;
|
|
int[string] pieces = ["a":1];
|
|
pieces[q] = 0;
|
|
string w = "ab";
|
|
int z = pieces[w[0 .. 1]];
|
|
assert(z == 1);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6282
|
|
// dereference 'in' of an AA
|
|
|
|
static assert({
|
|
int[] w = new int[4];
|
|
w[2] = 6;
|
|
auto c = [5: w];
|
|
auto kk = (*(5 in c))[2];
|
|
(*(5 in c))[2] = 8;
|
|
(*(5 in c))[1 .. $ - 2] = 4;
|
|
auto a = [4:"1"];
|
|
auto n = *(4 in a);
|
|
return n;
|
|
}() == "1");
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6337
|
|
// member function call on struct literal
|
|
|
|
struct Bug6337
|
|
{
|
|
int k;
|
|
void six()
|
|
{
|
|
k = 6;
|
|
}
|
|
int ctfe()
|
|
{
|
|
six();
|
|
return k;
|
|
}
|
|
}
|
|
static assert(Bug6337().ctfe() == 6);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6603
|
|
// call manifest function pointer
|
|
|
|
int f6603(int a) { return a + 5; }
|
|
enum bug6603 = &f6603;
|
|
static assert(bug6603(6) == 11);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6375
|
|
|
|
struct D6375
|
|
{
|
|
int[] arr;
|
|
}
|
|
A6375 a6375(int[] array)
|
|
{
|
|
return A6375(array);
|
|
}
|
|
struct A6375
|
|
{
|
|
D6375* _data;
|
|
this(int[] arr)
|
|
{
|
|
_data = new D6375;
|
|
_data.arr = arr;
|
|
}
|
|
int[] data()
|
|
{
|
|
return _data.arr;
|
|
}
|
|
}
|
|
static assert({
|
|
int[] a = [1, 2];
|
|
auto app2 = a6375(a);
|
|
auto data = app2.data();
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6280
|
|
// Converting pointers to bool
|
|
|
|
static assert({
|
|
if ((0 in [0:0])) {}
|
|
if ((0 in [0:0]) && (0 in [0:0])) {}
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6276
|
|
// ~=
|
|
|
|
struct Bug6276
|
|
{
|
|
int[] i;
|
|
}
|
|
static assert({
|
|
Bug6276 foo;
|
|
foo.i ~= 1;
|
|
foo.i ~= 2;
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6374
|
|
// ptr[n] = x, x = ptr[n]
|
|
|
|
static assert({
|
|
int[] arr = [1];
|
|
arr.ptr[0] = 2;
|
|
auto k = arr.ptr[0];
|
|
assert(k == 2);
|
|
return arr[0];
|
|
}() == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6306
|
|
// recursion and local variables
|
|
|
|
void recurse6306()
|
|
{
|
|
bug6306(false);
|
|
}
|
|
|
|
bool bug6306(bool b)
|
|
{
|
|
int x = 0;
|
|
if (b)
|
|
recurse6306();
|
|
assert(x == 0);
|
|
x = 1;
|
|
return true;
|
|
}
|
|
static assert(bug6306(true));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6386
|
|
// ICE on unsafe pointer cast
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
int x = 123;
|
|
int* p = &x;
|
|
float z;
|
|
float* q = cast(float*)p;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
static assert({
|
|
int[] x = [123, 456];
|
|
int* p = &x[0];
|
|
auto m = cast(const(int)*)p;
|
|
auto q = p;
|
|
return *q;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6420
|
|
// ICE on dereference of invalid pointer
|
|
|
|
static assert({
|
|
// Should compile, but pointer can't be dereferenced
|
|
int x = 123;
|
|
int* p = cast(int*)x;
|
|
auto q = cast(char*)x;
|
|
auto r = cast(char*)323;
|
|
// Valid const-changing cast
|
|
const float *m = cast(immutable float*)[1.2f,2.4f,3f];
|
|
return true;
|
|
}()
|
|
);
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
int x = 123;
|
|
int* p = cast(int*)x;
|
|
int a = *p;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
int* p = cast(int*)123;
|
|
int a = *p;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
auto k = cast(int*)45;
|
|
*k = 1;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
*cast(float*)"a" = 4.0;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
float f = 2.8;
|
|
long *p = &f;
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
static assert(!is(typeof(compiles!({
|
|
long *p = cast(long*)[1.2f, 2.4f, 3f];
|
|
return true;
|
|
}()
|
|
))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6250
|
|
// deref pointers to array
|
|
|
|
int[]* simple6250(int[]* x) { return x; }
|
|
|
|
void swap6250(int[]* lhs, int[]* rhs)
|
|
{
|
|
int[] kk = *lhs;
|
|
assert(simple6250(lhs) == lhs);
|
|
lhs = simple6250(lhs);
|
|
assert(kk[0] == 18);
|
|
assert((*lhs)[0] == 18);
|
|
assert((*rhs)[0] == 19);
|
|
*lhs = *rhs;
|
|
assert((*lhs)[0] == 19);
|
|
*rhs = kk;
|
|
assert(*rhs == kk);
|
|
assert(kk[0] == 18);
|
|
assert((*rhs)[0] == 18);
|
|
}
|
|
|
|
int ctfeSort6250()
|
|
{
|
|
int[][2] x;
|
|
int[3] a = [17, 18, 19];
|
|
x[0] = a[1 .. 2];
|
|
x[1] = a[2 .. $];
|
|
assert(x[0][0] == 18);
|
|
assert(x[0][1] == 19);
|
|
swap6250(&x[0], &x[1]);
|
|
assert(x[0][0] == 19);
|
|
assert(x[1][0] == 18);
|
|
a[1] = 57;
|
|
assert(x[0][0] == 19);
|
|
return x[1][0];
|
|
}
|
|
|
|
static assert(ctfeSort6250() == 57);
|
|
|
|
/**************************************************/
|
|
|
|
long[]* simple6250b(long[]* x) { return x; }
|
|
|
|
void swap6250b(long[]* lhs, long[]* rhs)
|
|
{
|
|
long[] kk = *lhs;
|
|
assert(simple6250b(lhs) == lhs);
|
|
lhs = simple6250b(lhs);
|
|
assert(kk[0] == 18);
|
|
assert((*lhs)[0] == 18);
|
|
assert((*rhs)[0] == 19);
|
|
*lhs = *rhs;
|
|
assert((*lhs)[0] == 19);
|
|
*rhs = kk;
|
|
assert(*rhs == kk);
|
|
assert(kk[0] == 18);
|
|
assert((*rhs)[0] == 18);
|
|
}
|
|
|
|
long ctfeSort6250b()
|
|
{
|
|
long[][2] x;
|
|
long[3] a = [17, 18, 19];
|
|
x[0] = a[1 .. 2];
|
|
x[1] = a[2 .. $];
|
|
assert(x[0][0] == 18);
|
|
assert(x[0][1] == 19);
|
|
swap6250b(&x[0], &x[1]);
|
|
assert(x[0][0] == 19);
|
|
assert(x[1][0] == 18);
|
|
a[1] = 57;
|
|
assert(x[0][0] == 19);
|
|
return x[1][0];
|
|
}
|
|
|
|
static assert(ctfeSort6250b() == 57);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6672
|
|
// circular references in array
|
|
|
|
void bug6672(ref string lhs, ref string rhs)
|
|
{
|
|
auto tmp = lhs;
|
|
lhs = rhs;
|
|
rhs = tmp;
|
|
}
|
|
|
|
static assert({
|
|
auto kw = ["a"];
|
|
bug6672(kw[0], kw[0]);
|
|
return true;
|
|
}());
|
|
|
|
void slice6672(ref string[2] agg, ref string lhs)
|
|
{
|
|
agg[0 .. $] = lhs;
|
|
}
|
|
|
|
static assert({
|
|
string[2] kw = ["a", "b"];
|
|
slice6672(kw, kw[0]);
|
|
assert(kw[0] == "a");
|
|
assert(kw[1] == "a");
|
|
return true;
|
|
}());
|
|
|
|
// an unrelated rejects-valid bug
|
|
static assert({
|
|
string[2] kw = ["a", "b"];
|
|
kw[0 .. 2] = "x";
|
|
return true;
|
|
}());
|
|
|
|
void bug6672b(ref string lhs, ref string rhs)
|
|
{
|
|
auto tmp = lhs;
|
|
assert(tmp == "a");
|
|
lhs = rhs;
|
|
assert(tmp == "a");
|
|
rhs = tmp;
|
|
}
|
|
|
|
static assert({
|
|
auto kw=["a", "b"];
|
|
bug6672b(kw[0], kw[1]);
|
|
assert(kw[0] == "b");
|
|
assert(kw[1] == "a");
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6399
|
|
// (*p).length = n
|
|
|
|
struct A6399
|
|
{
|
|
int[] arr;
|
|
int subLen()
|
|
{
|
|
arr = [1, 2, 3, 4, 5];
|
|
arr.length -= 1;
|
|
return cast(int)arr.length;
|
|
}
|
|
}
|
|
|
|
static assert({
|
|
A6399 a;
|
|
return a.subLen();
|
|
}() == 4);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7789
|
|
// (*p).length++ where *p is null
|
|
|
|
struct S7789
|
|
{
|
|
size_t foo()
|
|
{
|
|
_ary.length += 1;
|
|
return _ary.length;
|
|
}
|
|
|
|
int[] _ary;
|
|
}
|
|
|
|
static assert(S7789().foo());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6418
|
|
// member named 'length'
|
|
|
|
struct Bug6418
|
|
{
|
|
size_t length() { return 189; }
|
|
}
|
|
static assert(Bug6418.init.length == 189);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4021
|
|
// rehash
|
|
|
|
bool bug4021()
|
|
{
|
|
int[int] aa = [1: 1];
|
|
aa.rehash;
|
|
return true;
|
|
}
|
|
static assert(bug4021());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11629
|
|
// crash on AA.rehash
|
|
|
|
struct Base11629
|
|
{
|
|
alias T = ubyte, Char = char;
|
|
alias String = immutable(Char)[];
|
|
|
|
const Char[T] toChar;
|
|
|
|
this(int _dummy)
|
|
{
|
|
Char[T] toCharTmp = [0:'A'];
|
|
|
|
toChar = toCharTmp.rehash;
|
|
}
|
|
}
|
|
enum ct11629 = Base11629(4);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=3512
|
|
// foreach (dchar; string)
|
|
// https://issues.dlang.org/show_bug.cgi?id=6558
|
|
// foreach (int, dchar; string)
|
|
|
|
bool test3512()
|
|
{
|
|
string s = "öhai";
|
|
int q = 0;
|
|
|
|
foreach (wchar c; s)
|
|
{
|
|
if (q == 2)
|
|
assert(c == 'a');
|
|
++q;
|
|
}
|
|
assert(q == 4);
|
|
|
|
// _aApplycd1
|
|
foreach (dchar c; s)
|
|
{
|
|
++q;
|
|
if (c == 'h')
|
|
break;
|
|
}
|
|
assert(q == 6);
|
|
|
|
// _aApplycw2
|
|
foreach (ptrdiff_t i, wchar c; s)
|
|
{
|
|
assert(i >= 0 && i < s.length);
|
|
}
|
|
|
|
// _aApplycd2
|
|
foreach (ptrdiff_t i, dchar c; s)
|
|
{
|
|
assert(i >= 0 && i < s.length);
|
|
}
|
|
|
|
wstring w = "xüm";
|
|
|
|
// _aApplywc1
|
|
foreach (char c; w)
|
|
{
|
|
++q;
|
|
}
|
|
assert(q == 10);
|
|
|
|
// _aApplywd1
|
|
foreach (dchar c; w)
|
|
{
|
|
++q;
|
|
}
|
|
assert(q == 13);
|
|
|
|
// _aApplywc2
|
|
foreach (ptrdiff_t i, char c; w)
|
|
{
|
|
assert(i >= 0 && i < w.length);
|
|
}
|
|
|
|
// _aApplywd2
|
|
foreach (ptrdiff_t i, dchar c; w)
|
|
{
|
|
assert(i >= 0 && i < w.length);
|
|
}
|
|
|
|
dstring d = "yäq";
|
|
|
|
// _aApplydc1
|
|
q = 0;
|
|
foreach (char c; d)
|
|
{
|
|
++q;
|
|
}
|
|
assert(q == 4);
|
|
|
|
// _aApplydw1
|
|
q = 0;
|
|
foreach (wchar c; d)
|
|
{
|
|
++q;
|
|
}
|
|
assert(q == 3);
|
|
|
|
// _aApplydc2
|
|
foreach (ptrdiff_t i, char c; d)
|
|
{
|
|
assert(i >= 0 && i < d.length);
|
|
}
|
|
// _aApplydw2
|
|
foreach (ptrdiff_t i, wchar c; d)
|
|
{
|
|
assert(i >= 0 && i < d.length);
|
|
}
|
|
|
|
dchar[] dr = "squop"d.dup;
|
|
|
|
foreach (ptrdiff_t n, char c; dr)
|
|
{
|
|
if (n == 2)
|
|
break;
|
|
assert(c != 'o');
|
|
}
|
|
|
|
// _aApplyRdc1
|
|
foreach_reverse (char c; dr)
|
|
{}
|
|
|
|
// _aApplyRdw1
|
|
foreach_reverse (wchar c; dr)
|
|
{}
|
|
|
|
// _aApplyRdc2
|
|
foreach_reverse (ptrdiff_t n, char c; dr)
|
|
{
|
|
if (n == 4)
|
|
break;
|
|
assert(c != 'o');
|
|
}
|
|
|
|
// _aApplyRdw2
|
|
foreach_reverse (ptrdiff_t i, wchar c; dr)
|
|
{
|
|
assert(i >= 0 && i < dr.length);
|
|
}
|
|
|
|
q = 0;
|
|
wstring w2 = ['x', 'ü', 'm']; // foreach over array literals
|
|
foreach_reverse (ptrdiff_t n, char c; w2)
|
|
{
|
|
++q;
|
|
if (c == 'm') assert(n == 2 && q == 1);
|
|
if (c == 'x') assert(n == 0 && q == 4);
|
|
}
|
|
return true;
|
|
}
|
|
static assert(test3512());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6510
|
|
// ICE only with -inline
|
|
|
|
struct Stack6510
|
|
{
|
|
struct Proxy
|
|
{
|
|
void shrink() {}
|
|
}
|
|
Proxy stack;
|
|
void pop()
|
|
{
|
|
stack.shrink();
|
|
}
|
|
}
|
|
|
|
int bug6510()
|
|
{
|
|
static int used()
|
|
{
|
|
Stack6510 junk;
|
|
junk.pop();
|
|
return 3;
|
|
}
|
|
return used();
|
|
}
|
|
|
|
void test6510()
|
|
{
|
|
static assert(bug6510() == 3);
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6511
|
|
// arr[] shouldn't make a copy
|
|
|
|
T bug6511(T)()
|
|
{
|
|
T[1] a = [1];
|
|
a[] += a[];
|
|
return a[0];
|
|
}
|
|
static assert(bug6511!ulong() == 2);
|
|
static assert(bug6511!long() == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6512
|
|
// new T[][]
|
|
|
|
bool bug6512(int m)
|
|
{
|
|
auto x = new int[2][][](m, 5);
|
|
assert(x.length == m);
|
|
assert(x[0].length == 5);
|
|
assert(x[0][0].length == 2);
|
|
foreach (i; 0.. m)
|
|
foreach (j; 0 .. 5)
|
|
foreach (k; 0 .. 2)
|
|
x[i][j][k] = k + j*10 + i*100;
|
|
foreach (i; 0.. m)
|
|
foreach (j; 0 .. 5)
|
|
foreach (k; 0 .. 2)
|
|
assert(x[i][j][k] == k + j*10 + i*100);
|
|
return true;
|
|
}
|
|
static assert(bug6512(3));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6516
|
|
// ICE(constfold.c)
|
|
|
|
dstring bug6516()
|
|
{
|
|
return cast(dstring)new dchar[](0);
|
|
}
|
|
|
|
static assert(bug6516() == ""d);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6727
|
|
// ICE(interpret.c)
|
|
|
|
const(char)* ice6727(const(char)* z) { return z; }
|
|
static assert({
|
|
auto q = ice6727("a".dup.ptr);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6721
|
|
// Cannot get pointer to start of char[]
|
|
|
|
static assert({
|
|
char[] c1 = "".dup;
|
|
auto p = c1.ptr;
|
|
string c2 = "";
|
|
auto p2 = c2.ptr;
|
|
return 6;
|
|
}() == 6);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6693
|
|
// Assign to null AA
|
|
|
|
struct S6693
|
|
{
|
|
int[int] m;
|
|
}
|
|
|
|
static assert({
|
|
int[int][int] aaa;
|
|
aaa[3][1] = 4;
|
|
int[int][3] aab;
|
|
aab[2][1] = 4;
|
|
S6693 s;
|
|
s.m[2] = 4;
|
|
return 6693;
|
|
}() == 6693);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7602
|
|
// Segfault AA.keys on null AA
|
|
|
|
string[] test7602()
|
|
{
|
|
int[string] array;
|
|
return array.keys;
|
|
}
|
|
|
|
enum bug7602 = test7602();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6739
|
|
// Nested AA assignment
|
|
|
|
static assert({
|
|
int[int][int][int] aaa;
|
|
aaa[3][1][6] = 14;
|
|
return aaa[3][1][6];
|
|
}() == 14);
|
|
|
|
static assert({
|
|
int[int][int] aaa;
|
|
aaa[3][1] = 4;
|
|
aaa[3][3] = 3;
|
|
aaa[1][5] = 9;
|
|
auto kk = aaa[1][5];
|
|
return kk;
|
|
}() == 9);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6751
|
|
// ref AA assignment
|
|
|
|
void bug6751(ref int[int] aa)
|
|
{
|
|
aa[1] = 2;
|
|
}
|
|
|
|
static assert({
|
|
int[int] aa;
|
|
bug6751(aa);
|
|
assert(aa[1] == 2);
|
|
return true;
|
|
}());
|
|
|
|
void bug6751b(ref int[int][int] aa)
|
|
{
|
|
aa[1][17] = 2;
|
|
}
|
|
|
|
struct S6751
|
|
{
|
|
int[int][int] aa;
|
|
int[int] bb;
|
|
}
|
|
|
|
static assert({
|
|
S6751 s;
|
|
bug6751b(s.aa);
|
|
assert(s.aa[1][17] == 2);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
S6751 s;
|
|
s.aa[7][56] = 57;
|
|
bug6751b(s.aa);
|
|
assert(s.aa[1][17] == 2);
|
|
assert(s.aa[7][56] == 57);
|
|
bug6751c(s.aa);
|
|
assert(s.aa.keys.length == 1);
|
|
assert(s.aa.values.length == 1);
|
|
return true;
|
|
}());
|
|
|
|
static assert({
|
|
S6751 s;
|
|
s.bb[19] = 97;
|
|
bug6751(s.bb);
|
|
assert(s.bb[1] == 2);
|
|
assert(s.bb[19] == 97);
|
|
return true;
|
|
}());
|
|
|
|
void bug6751c(ref int[int][int] aa)
|
|
{
|
|
aa = [38: [56 : 77]];
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7790
|
|
// AA foreach ref
|
|
|
|
struct S7790
|
|
{
|
|
size_t id;
|
|
}
|
|
|
|
size_t bug7790(S7790[string] tree)
|
|
{
|
|
foreach (k, ref v; tree)
|
|
v.id = 1;
|
|
return tree["a"].id;
|
|
}
|
|
|
|
static assert(bug7790(["a":S7790(0)]) == 1);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6765
|
|
// null AA.length
|
|
|
|
static assert({
|
|
int[int] w;
|
|
return w.length;
|
|
}() == 0);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6769
|
|
// AA.keys, AA.values with -inline
|
|
|
|
static assert({
|
|
double[char[3]] w = ["abc" : 2.3];
|
|
double[] z = w.values;
|
|
return w.keys.length;
|
|
}() == 1);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=4022
|
|
// AA.get
|
|
|
|
static assert({
|
|
int[int] aa = [58: 13];
|
|
int r = aa.get(58, 1000);
|
|
assert(r == 13);
|
|
r = aa.get(59, 1000);
|
|
return r;
|
|
}() == 1000);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6775
|
|
// AA.opApply
|
|
|
|
static assert({
|
|
int[int] aa = [58: 17, 45:6];
|
|
int valsum = 0;
|
|
int keysum = 0;
|
|
foreach (m; aa) // aaApply
|
|
{
|
|
valsum += m;
|
|
}
|
|
assert(valsum == 17 + 6);
|
|
valsum = 0;
|
|
foreach (n, m; aa) // aaApply2
|
|
{
|
|
valsum += m;
|
|
keysum += n;
|
|
}
|
|
assert(valsum == 17 + 6);
|
|
assert(keysum == 58 + 45);
|
|
// Check empty AA
|
|
valsum = 0;
|
|
int[int] bb;
|
|
foreach (m; bb)
|
|
{
|
|
++valsum;
|
|
}
|
|
assert(valsum == 0);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7890
|
|
// segfault struct with AA field
|
|
|
|
struct S7890
|
|
{
|
|
int[int] tab;
|
|
}
|
|
|
|
S7890 bug7890()
|
|
{
|
|
S7890 foo;
|
|
foo.tab[0] = 0;
|
|
return foo;
|
|
}
|
|
|
|
enum e7890 = bug7890();
|
|
|
|
/**************************************************
|
|
AA.remove
|
|
**************************************************/
|
|
|
|
static assert({
|
|
int[int] aa = [58: 17, 45:6];
|
|
aa.remove(45);
|
|
assert(aa.length == 1);
|
|
aa.remove(7);
|
|
assert(aa.length == 1);
|
|
aa.remove(58);
|
|
assert(aa.length == 0);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************
|
|
try, finally
|
|
**************************************************/
|
|
|
|
static assert({
|
|
int n = 0;
|
|
|
|
try
|
|
{
|
|
n = 1;
|
|
}
|
|
catch (Exception e)
|
|
{}
|
|
assert(n == 1);
|
|
|
|
try
|
|
{
|
|
n = 2;
|
|
}
|
|
catch (Exception e)
|
|
{}
|
|
finally
|
|
{
|
|
assert(n == 2);
|
|
n = 3;
|
|
}
|
|
assert(n == 3);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6800
|
|
// bad pointer casts
|
|
|
|
bool badpointer(int k)
|
|
{
|
|
int m = 6;
|
|
int* w = &m;
|
|
assert(*w == 6);
|
|
int[3] a = [17, 2, 21];
|
|
int* w2 = &a[2];
|
|
assert(*w2 == 21);
|
|
|
|
// cast int* to uint* is OK
|
|
uint* u1 = cast(uint*)w;
|
|
assert(*u1 == 6);
|
|
uint* u2 = cast(uint*)w2;
|
|
assert(*u2 == 21);
|
|
uint* u3 = cast(uint*)&m;
|
|
assert(*u3 == 6);
|
|
// cast int* to void* is OK
|
|
void* v1 = cast(void*)w;
|
|
void* v3 = &m;
|
|
void* v4 = &a[0];
|
|
// cast from void* back to int* is OK
|
|
int* t3 = cast(int*)v3;
|
|
assert(*t3 == 6);
|
|
int* t4 = cast(int*)v4;
|
|
assert(*t4 == 17);
|
|
// cast from void* to uint* is OK
|
|
uint* t1 = cast(uint*)v1;
|
|
assert(*t1 == 6);
|
|
// and check that they're real pointers
|
|
m = 18;
|
|
assert(*t1 == 18);
|
|
assert(*u3 == 18);
|
|
|
|
int** p = &w;
|
|
|
|
if (k == 1) // bad reinterpret
|
|
double *d1 = cast(double*)w;
|
|
if (k == 3) // bad reinterpret
|
|
char* d3 = cast(char*)w2;
|
|
if (k == 4) {
|
|
void* q1 = cast(void*)p; // OK-void is int*
|
|
void* *q = cast(void**)p; // OK-void is int
|
|
}
|
|
if (k == 5)
|
|
void*** q = cast(void***)p; // bad: too many *
|
|
if (k == 6) // bad reinterpret through void*
|
|
double* d1 = cast(double*)v1;
|
|
if (k == 7)
|
|
double* d7 = cast(double*)v4;
|
|
if (k == 8)
|
|
++v4; // can't do pointer arithmetic on void*
|
|
return true;
|
|
}
|
|
static assert(badpointer(4));
|
|
static assert(!is(typeof(compiles!(badpointer(1)))));
|
|
static assert( is(typeof(compiles!(badpointer(2)))));
|
|
static assert(!is(typeof(compiles!(badpointer(3)))));
|
|
static assert( is(typeof(compiles!(badpointer(4)))));
|
|
static assert(!is(typeof(compiles!(badpointer(5)))));
|
|
static assert(!is(typeof(compiles!(badpointer(6)))));
|
|
static assert(!is(typeof(compiles!(badpointer(7)))));
|
|
static assert(!is(typeof(compiles!(badpointer(8)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10211
|
|
// Allow casts S**->D**, when S*->D* is OK
|
|
|
|
int bug10211()
|
|
{
|
|
int m = 7;
|
|
int* x = &m;
|
|
int** y = &x;
|
|
assert(**y == 7);
|
|
uint* p = cast(uint*)x;
|
|
uint** q = cast(uint**)y;
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug10211());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10568
|
|
// CTFE rejects function pointer safety casts
|
|
|
|
@safe void safetyDance() {}
|
|
|
|
int isItSafeToDance()
|
|
{
|
|
void function() @trusted yourfriends = &safetyDance;
|
|
void function() @safe nofriendsOfMine = yourfriends;
|
|
return 1;
|
|
}
|
|
|
|
static assert(isItSafeToDance());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12296
|
|
// CTFE rejects const compatible AA pointer cast
|
|
|
|
int test12296()
|
|
{
|
|
immutable x = [5 : 4];
|
|
auto aa = &x;
|
|
const(int[int])* y = aa;
|
|
return 1;
|
|
}
|
|
static assert(test12296());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9170
|
|
// Allow reinterpret casts float<->int
|
|
|
|
int f9170(float x)
|
|
{
|
|
return *(cast(int*)&x);
|
|
}
|
|
|
|
float i9170(int x)
|
|
{
|
|
return *(cast(float*)&x);
|
|
}
|
|
|
|
float u9170(uint x)
|
|
{
|
|
return *(cast(float*)&x);
|
|
}
|
|
|
|
int f9170arr(float[] x)
|
|
{
|
|
return *(cast(int*)&(x[1]));
|
|
}
|
|
|
|
long d9170(double x)
|
|
{
|
|
return *(cast(long*)&x);
|
|
}
|
|
|
|
int fref9170(ref float x)
|
|
{
|
|
return *(cast(int*)&x);
|
|
}
|
|
|
|
long dref9170(ref double x)
|
|
{
|
|
return *(cast(long*)&x);
|
|
}
|
|
|
|
bool bug9170()
|
|
{
|
|
float f = 1.25;
|
|
double d = 1.25;
|
|
assert(f9170(f) == 0x3FA0_0000);
|
|
assert(fref9170(f) == 0x3FA0_0000);
|
|
assert(d9170(d) == 0x3FF4_0000_0000_0000L);
|
|
assert(dref9170(d) == 0x3FF4_0000_0000_0000L);
|
|
float [3] farr = [0, 1.25, 0];
|
|
assert(f9170arr(farr) == 0x3FA0_0000);
|
|
int i = 0x3FA0_0000;
|
|
assert(i9170(i) == 1.25);
|
|
uint u = 0x3FA0_0000;
|
|
assert(u9170(u) == 1.25);
|
|
return true;
|
|
}
|
|
|
|
static assert(bug9170());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6792
|
|
// ICE with pointer cast of indexed array
|
|
|
|
struct S6792
|
|
{
|
|
int i;
|
|
}
|
|
|
|
static assert({
|
|
{
|
|
void* p;
|
|
p = [S6792(1)].ptr;
|
|
S6792 s = *(cast(S6792*)p);
|
|
assert(s.i == 1);
|
|
}
|
|
{
|
|
void*[] ary;
|
|
ary ~= [S6792(2)].ptr;
|
|
S6792 s = *(cast(S6792*)ary[0]);
|
|
assert(s.i == 2);
|
|
}
|
|
{
|
|
void*[7] ary;
|
|
ary[6]= [S6792(2)].ptr;
|
|
S6792 s = *(cast(S6792*)ary[6]);
|
|
assert(s.i == 2);
|
|
}
|
|
{
|
|
void* p;
|
|
p = [S6792(1)].ptr;
|
|
void*[7] ary;
|
|
ary[5]= p;
|
|
S6792 s = *(cast(S6792*)ary[5]);
|
|
assert(s.i == 1);
|
|
}
|
|
{
|
|
S6792*[string] aa;
|
|
aa["key"] = [S6792(3)].ptr;
|
|
const(S6792) s = *(cast(const(S6792)*)aa["key"]);
|
|
assert(s.i == 3);
|
|
}
|
|
{
|
|
S6792[string] blah;
|
|
blah["abc"] = S6792(6);
|
|
S6792*[string] aa;
|
|
aa["kuy"] = &blah["abc"];
|
|
const(S6792) s = *(cast(const(S6792)*)aa["kuy"]);
|
|
assert(s.i == 6);
|
|
|
|
void*[7] ary;
|
|
ary[5]= &blah["abc"];
|
|
S6792 t = *(cast(S6792*)ary[5]);
|
|
assert(t.i == 6);
|
|
|
|
int q = 6;
|
|
ary[3]= &q;
|
|
int gg = *(cast(int*)(ary[3]));
|
|
}
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7780
|
|
// array cast
|
|
|
|
int bug7780(int testnum)
|
|
{
|
|
int[] y = new int[2];
|
|
y[0] = 2000000;
|
|
if (testnum == 1)
|
|
{
|
|
void[] x = y;
|
|
return (cast(byte[])x)[1];
|
|
}
|
|
if (testnum == 2)
|
|
{
|
|
int[] x = y[0 .. 1];
|
|
return (cast(byte[])x)[1];
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static assert( is(typeof(compiles!(bug7780(0)))));
|
|
static assert(!is(typeof(compiles!(bug7780(1)))));
|
|
static assert(!is(typeof(compiles!(bug7780(2)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14028
|
|
// static array pointer that refers existing array elements.
|
|
|
|
int test14028a(size_t ofs)(bool ct)
|
|
{
|
|
int[4] a;
|
|
int[2]* p;
|
|
int num = ofs;
|
|
|
|
if (ct)
|
|
p = cast(int[2]*)&a[ofs]; // SymOffExp
|
|
else
|
|
p = cast(int[2]*)&a[num]; // CastExp + AddrExp
|
|
|
|
// pointers comparison
|
|
assert(cast(void*)a.ptr <= cast(void*)p);
|
|
assert(cast(void*)a.ptr <= cast(void*)&(*p)[0]);
|
|
assert(cast(void*)&a[0] <= cast(void*)p);
|
|
|
|
return 1;
|
|
}
|
|
static assert(test14028a!0(true));
|
|
static assert(test14028a!0(false));
|
|
static assert(test14028a!3(true));
|
|
static assert(test14028a!3(false));
|
|
static assert(!is(typeof(compiles!(test14028a!4(true)))));
|
|
static assert(!is(typeof(compiles!(test14028a!4(false)))));
|
|
|
|
int test14028b(int num)
|
|
{
|
|
int[4] a;
|
|
int[2]* p;
|
|
|
|
if (num == 1)
|
|
{
|
|
p = cast(int[2]*)&a[0]; // &a[0..2];
|
|
(*p)[0] = 1; // a[0] = 1
|
|
(*p)[1] = 2; // a[1] = 2
|
|
assert(a == [1,2,0,0]);
|
|
p = p + 1; // &a[0] -> &a[2]
|
|
(*p)[0] = 3; // a[2] = 3
|
|
(*p)[1] = 4; // a[3] = 4
|
|
assert(a == [1,2,3,4]);
|
|
}
|
|
if (num == 2)
|
|
{
|
|
p = cast(int[2]*)&a[1]; // &a[1..3];
|
|
(*p)[0] = 1; // a[1] = 1
|
|
p = p + 1; // &a[1..3] -> &a[3..5]
|
|
(*p)[0] = 2; // a[3] = 2
|
|
assert(a == [0,1,0,2]);
|
|
}
|
|
if (num == 3)
|
|
{
|
|
p = cast(int[2]*)&a[1]; // &a[1..3];
|
|
(*p)[0] = 1; // a[1] = 1
|
|
p = p + 1; // &a[1..3] -> &a[3..5]
|
|
(*p)[0] = 2; // a[3] = 2
|
|
(*p)[1] = 3; // a[4] = 3 (CTFE error)
|
|
}
|
|
if (num == 4)
|
|
{
|
|
p = cast(int[2]*)&a[0]; // &a[0..2];
|
|
p = p + 1; // &a[0..2] -> &a[2..4]
|
|
p = p + 1; // &a[2..4] -> &a[4..6] (ok)
|
|
}
|
|
if (num == 5)
|
|
{
|
|
p = cast(int[2]*)&a[1]; // &a[1..3];
|
|
p = p + 2; // &a[1..3] -> &a[5..7] (CTFE error)
|
|
}
|
|
return 1;
|
|
}
|
|
static assert(test14028b(1));
|
|
static assert(test14028b(2));
|
|
static assert(!is(typeof(compiles!(test14028b(3)))));
|
|
static assert(test14028b(4));
|
|
static assert(!is(typeof(compiles!(test14028b(5)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10275
|
|
// cast struct literals to immutable
|
|
|
|
struct Bug10275
|
|
{
|
|
uint[] ivals;
|
|
}
|
|
|
|
Bug10275 bug10275()
|
|
{
|
|
return Bug10275([1, 2, 3]);
|
|
}
|
|
|
|
int test10275()
|
|
{
|
|
immutable(Bug10275) xxx = cast(immutable(Bug10275))bug10275();
|
|
return 1;
|
|
}
|
|
|
|
static assert(test10275());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6851
|
|
// passing pointer by argument
|
|
|
|
void set6851(int* pn)
|
|
{
|
|
*pn = 20;
|
|
}
|
|
void bug6851()
|
|
{
|
|
int n = 0;
|
|
auto pn = &n;
|
|
*pn = 10;
|
|
assert(n == 10);
|
|
set6851(&n);
|
|
}
|
|
static assert({ bug6851(); return true; }());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7876
|
|
|
|
int* bug7876(int n) @system
|
|
{
|
|
int x;
|
|
auto ptr = &x;
|
|
if (n == 2)
|
|
ptr = null;
|
|
return ptr;
|
|
}
|
|
|
|
struct S7876
|
|
{
|
|
int* p;
|
|
}
|
|
|
|
S7876 bug7876b(int n) @system
|
|
{
|
|
int x;
|
|
S7876 s;
|
|
s.p = &x;
|
|
if (n == 11)
|
|
s.p = null;
|
|
return s;
|
|
}
|
|
|
|
int test7876(int n)
|
|
{
|
|
if (n >= 10)
|
|
{
|
|
S7876 m = bug7876b(n);
|
|
return 1;
|
|
}
|
|
int* p = bug7876(n);
|
|
return 1;
|
|
}
|
|
|
|
static assert( is(typeof(compiles!(test7876(2)))));
|
|
static assert(!is(typeof(compiles!(test7876(0)))));
|
|
static assert( is(typeof(compiles!(test7876(11)))));
|
|
static assert(!is(typeof(compiles!(test7876(10)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11824
|
|
|
|
int f11824(T)()
|
|
{
|
|
T[] arr = new T[](1);
|
|
T* getAddr(ref T a)
|
|
{
|
|
return &a;
|
|
}
|
|
getAddr(arr[0]);
|
|
return 1;
|
|
}
|
|
static assert(f11824!int()); // OK
|
|
static assert(f11824!(int[])()); // OK <- NG
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6817
|
|
// if converted to &&, only with -inline
|
|
|
|
static assert({
|
|
void toggle()
|
|
{
|
|
bool b;
|
|
if (b)
|
|
b = false;
|
|
}
|
|
toggle();
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************
|
|
cast to void
|
|
**************************************************/
|
|
|
|
static assert({
|
|
cast(void)(71);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6816
|
|
// nested function can't access this
|
|
|
|
struct S6816
|
|
{
|
|
size_t foo()
|
|
{
|
|
return (){ return value +1 ; }();
|
|
}
|
|
size_t value;
|
|
}
|
|
|
|
enum s6816 = S6816().foo();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7277
|
|
// ICE nestedstruct.init.tupleof
|
|
|
|
struct Foo7277
|
|
{
|
|
int a;
|
|
int func()
|
|
{
|
|
int b;
|
|
void nested()
|
|
{
|
|
b = 7;
|
|
a = 10;
|
|
}
|
|
nested();
|
|
return a+b;
|
|
}
|
|
}
|
|
|
|
static assert(Foo7277().func() == 17);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10217
|
|
// ICE. CTFE version of 9315
|
|
|
|
bool bug10217()
|
|
{
|
|
struct S
|
|
{
|
|
int i;
|
|
void bar() {}
|
|
}
|
|
auto yyy = S.init.tupleof[$ - 1];
|
|
assert(!yyy);
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug10217());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8276
|
|
// ICE
|
|
|
|
void bug8676(int n)
|
|
{
|
|
const int X1 = 4 + n;
|
|
const int X2 = 4;
|
|
int X3 = 4;
|
|
int bar1() { return X1; }
|
|
int bar2() { return X2; }
|
|
int bar3() { return X3; }
|
|
static assert(!is(typeof(compiles!(bar1()))));
|
|
static assert( is(typeof(compiles!(bar2()))));
|
|
static assert(!is(typeof(compiles!(bar3()))));
|
|
}
|
|
|
|
/**************************************************
|
|
classes and interfaces
|
|
**************************************************/
|
|
|
|
interface SomeInterface
|
|
{
|
|
int daz();
|
|
float bar(char);
|
|
int baz();
|
|
}
|
|
|
|
interface SomeOtherInterface
|
|
{
|
|
int xxx();
|
|
}
|
|
|
|
class TheBase : SomeInterface, SomeOtherInterface
|
|
{
|
|
int q = 88;
|
|
int rad = 61;
|
|
int a = 14;
|
|
int somebaseclassfunc() { return 28; }
|
|
int daz() { return 0; }
|
|
int baz() { return 0; }
|
|
int xxx() { return 762; }
|
|
int foo() { return q; }
|
|
float bar(char c) { return 3.6; }
|
|
}
|
|
|
|
class SomeClass : TheBase, SomeInterface
|
|
{
|
|
int gab = 9;
|
|
int fab;
|
|
int a = 17;
|
|
int b = 23;
|
|
override int foo() { return gab + a; }
|
|
override float bar(char c) { return 2.6; }
|
|
int something() { return 0; }
|
|
override int daz() { return 0; }
|
|
override int baz() { return 0; }
|
|
}
|
|
|
|
class Unrelated : TheBase
|
|
{
|
|
this(int x) { a = x; }
|
|
}
|
|
|
|
auto classtest1(int n)
|
|
{
|
|
SomeClass c = new SomeClass;
|
|
assert(c.a == 17);
|
|
assert(c.q == 88);
|
|
TheBase d = c;
|
|
assert(d.a == 14);
|
|
assert(d.q == 88);
|
|
if (n == 7)
|
|
{
|
|
// bad cast -- should fail
|
|
Unrelated u = cast(Unrelated)d;
|
|
assert(u is null);
|
|
}
|
|
SomeClass e = cast(SomeClass)d;
|
|
d.q = 35;
|
|
assert(c.q == 35);
|
|
assert(c.foo() == 9 + 17);
|
|
++c.a;
|
|
assert(c.foo() == 9 + 18);
|
|
assert(d.foo() == 9 + 18);
|
|
d = new TheBase;
|
|
SomeInterface fc = c;
|
|
SomeOtherInterface ot = c;
|
|
assert(fc.bar('x') == 2.6);
|
|
assert(ot.xxx() == 762);
|
|
fc = d;
|
|
ot = d;
|
|
assert(fc.bar('x') == 3.6);
|
|
assert(ot.xxx() == 762);
|
|
|
|
Unrelated u2 = new Unrelated(7);
|
|
assert(u2.a == 7);
|
|
return 6;
|
|
}
|
|
static assert(classtest1(1));
|
|
static assert(classtest1(2));
|
|
static assert(classtest1(7)); // https://issues.dlang.org/show_bug.cgi?id=7154
|
|
|
|
// can't initialize enum with not null class
|
|
SomeClass classtest2(int n)
|
|
{
|
|
return n == 5 ? (new SomeClass) : null;
|
|
}
|
|
static assert( is(typeof((){ enum const(SomeClass) xx = classtest2(2);}())));
|
|
static assert(!is(typeof((){ enum const(SomeClass) xx = classtest2(5);}())));
|
|
|
|
class RecursiveClass
|
|
{
|
|
int x;
|
|
this(int n) { x = n; }
|
|
RecursiveClass b;
|
|
void doit() { b = new RecursiveClass(7); b.x = 2;}
|
|
}
|
|
|
|
int classtest3()
|
|
{
|
|
RecursiveClass x = new RecursiveClass(17);
|
|
x.doit();
|
|
RecursiveClass y = x.b;
|
|
assert(y.x == 2);
|
|
assert(x.x == 17);
|
|
return 1;
|
|
}
|
|
|
|
static assert(classtest3());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12016
|
|
// class cast and qualifier reinterpret
|
|
|
|
class B12016 { }
|
|
|
|
class C12016 : B12016 { }
|
|
|
|
bool f12016(immutable B12016 b)
|
|
{
|
|
assert(b);
|
|
return true;
|
|
}
|
|
|
|
static assert(f12016(new immutable C12016));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10610
|
|
// ice immutable implicit conversion
|
|
|
|
class Bug10610(T)
|
|
{
|
|
int baz() immutable
|
|
{
|
|
return 1;
|
|
}
|
|
static immutable(Bug10610!T) min = new Bug10610!T();
|
|
}
|
|
|
|
void ice10610()
|
|
{
|
|
alias T10610 = Bug10610!(int);
|
|
static assert (T10610.min.baz());
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13141
|
|
// regression fix caused by 10610
|
|
|
|
struct MapResult13141(alias pred)
|
|
{
|
|
int[] range;
|
|
@property empty() { return range.length == 0; }
|
|
@property front() { return pred(range[0]); }
|
|
void popFront() { range = range[1 .. $]; }
|
|
}
|
|
|
|
string[] array13141(R)(R r)
|
|
{
|
|
typeof(return) result;
|
|
foreach (e; r)
|
|
result ~= e;
|
|
return result;
|
|
}
|
|
|
|
//immutable string[] splitterNames = [4].map!(e => "4").array();
|
|
immutable string[] splitterNames13141 = MapResult13141!(e => "4")([4]).array13141();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11587
|
|
// AA compare
|
|
|
|
static assert([1:2, 3:4] == [3:4, 1:2]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14325
|
|
// more AA comparisons
|
|
|
|
static assert([1:1] != [1:2, 2:1]); // OK
|
|
static assert([1:1] != [1:2]); // OK
|
|
static assert([1:1] != [2:1]); // OK <- Error
|
|
static assert([1:1, 2:2] != [3:3, 4:4]); // OK <- Error
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7147
|
|
// typeid()
|
|
|
|
static assert({
|
|
TypeInfo xxx = typeid(Object);
|
|
TypeInfo yyy = typeid(new Error("xxx"));
|
|
return true;
|
|
}());
|
|
|
|
int bug7147(int n)
|
|
{
|
|
Error err = n ? new Error("xxx") : null;
|
|
TypeInfo qqq = typeid(err);
|
|
return 1;
|
|
}
|
|
|
|
// Must not segfault if class is null
|
|
static assert(!is(typeof(compiles!(bug7147(0)))));
|
|
static assert( is(typeof(compiles!(bug7147(1)))));
|
|
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14123
|
|
// identity TypeInfo objects
|
|
|
|
static assert({
|
|
bool eq(TypeInfo t1, TypeInfo t2)
|
|
{
|
|
return t1 is t2;
|
|
}
|
|
|
|
class C {}
|
|
struct S {}
|
|
|
|
assert( eq(typeid(C), typeid(C)));
|
|
assert(!eq(typeid(C), typeid(Object)));
|
|
assert( eq(typeid(S), typeid(S)));
|
|
assert(!eq(typeid(S), typeid(int)));
|
|
assert( eq(typeid(int), typeid(int)));
|
|
assert(!eq(typeid(int), typeid(long)));
|
|
|
|
Object o = new Object;
|
|
Object c = new C;
|
|
assert( eq(typeid(o), typeid(o)));
|
|
assert(!eq(typeid(c), typeid(o)));
|
|
assert(!eq(typeid(o), typeid(S)));
|
|
|
|
return 1;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6885
|
|
// wrong code with new array
|
|
|
|
struct S6885
|
|
{
|
|
int p;
|
|
}
|
|
|
|
int bug6885()
|
|
{
|
|
auto array = new double[1][2];
|
|
array[1][0] = 6;
|
|
array[0][0] = 1;
|
|
assert(array[1][0] == 6);
|
|
|
|
auto barray = new S6885[2];
|
|
barray[1].p = 5;
|
|
barray[0].p = 2;
|
|
assert(barray[1].p == 5);
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug6885());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6886
|
|
// ICE with new array of dynamic arrays
|
|
|
|
int bug6886()
|
|
{
|
|
auto carray = new int[][2];
|
|
carray[1] = [6];
|
|
carray[0] = [4];
|
|
assert(carray[1][0] == 6);
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug6886());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10198
|
|
// Multidimensional struct block initializer
|
|
|
|
struct Block10198
|
|
{
|
|
int[4][3] val;
|
|
}
|
|
|
|
int bug10198()
|
|
{
|
|
Block10198 pp = Block10198(67);
|
|
assert(pp.val[2][3] == 67);
|
|
assert(pp.val[1][3] == 67);
|
|
return 1;
|
|
}
|
|
static assert(bug10198());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14440
|
|
// Multidimensional block initialization should create distinct arrays for each elements
|
|
|
|
struct Matrix14440(E, size_t row, size_t col)
|
|
{
|
|
E[col][row] array2D;
|
|
|
|
@safe pure nothrow
|
|
this(E[row * col] numbers...)
|
|
{
|
|
foreach (r; 0 .. row)
|
|
{
|
|
foreach (c; 0 .. col)
|
|
{
|
|
array2D[r][c] = numbers[r * col + c];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void test14440()
|
|
{
|
|
// Replace 'enum' with 'auto' here and it will work fine.
|
|
enum matrix = Matrix14440!(int, 3, 3)(
|
|
1, 2, 3,
|
|
4, 5, 6,
|
|
7, 8, 9
|
|
);
|
|
|
|
static assert(matrix.array2D[0][0] == 1);
|
|
static assert(matrix.array2D[0][1] == 2);
|
|
static assert(matrix.array2D[0][2] == 3);
|
|
static assert(matrix.array2D[1][0] == 4);
|
|
static assert(matrix.array2D[1][1] == 5);
|
|
static assert(matrix.array2D[1][2] == 6);
|
|
static assert(matrix.array2D[2][0] == 7);
|
|
static assert(matrix.array2D[2][1] == 8);
|
|
static assert(matrix.array2D[2][2] == 9);
|
|
}
|
|
|
|
/****************************************************
|
|
* Exception chaining tests from xtest46.d
|
|
****************************************************/
|
|
|
|
class A75
|
|
{
|
|
pure static void raise(string s)
|
|
{
|
|
throw new Exception(s);
|
|
}
|
|
}
|
|
|
|
int test75()
|
|
{
|
|
int x = 0;
|
|
try
|
|
{
|
|
A75.raise("a");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
x = 1;
|
|
}
|
|
assert(x == 1);
|
|
return 1;
|
|
}
|
|
static assert(test75());
|
|
|
|
/****************************************************
|
|
* Exception chaining tests from test4.d
|
|
****************************************************/
|
|
|
|
int test4_test54()
|
|
{
|
|
int status = 0;
|
|
|
|
try
|
|
{
|
|
try
|
|
{
|
|
status++;
|
|
assert(status == 1);
|
|
throw new Exception("first");
|
|
}
|
|
finally
|
|
{
|
|
status++;
|
|
assert(status == 2);
|
|
status++;
|
|
throw new Exception("second");
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(e.msg == "first");
|
|
assert(e.next.msg == "second");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static assert(test4_test54());
|
|
|
|
void foo55()
|
|
{
|
|
try
|
|
{
|
|
Exception x = new Exception("second");
|
|
throw x;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(e.msg == "second");
|
|
}
|
|
}
|
|
|
|
int test4_test55()
|
|
{
|
|
int status = 0;
|
|
try
|
|
{
|
|
try
|
|
{
|
|
status++;
|
|
assert(status == 1);
|
|
Exception x = new Exception("first");
|
|
throw x;
|
|
}
|
|
finally
|
|
{
|
|
status++;
|
|
assert(status == 2);
|
|
status++;
|
|
foo55();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(e.msg == "first");
|
|
assert(status == 3);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static assert(test4_test55());
|
|
|
|
/****************************************************
|
|
* Exception chaining tests from eh.d
|
|
****************************************************/
|
|
|
|
void bug1513outer()
|
|
{
|
|
int result1513;
|
|
|
|
void bug1513a()
|
|
{
|
|
throw new Exception("d");
|
|
}
|
|
|
|
void bug1513b()
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
bug1513a();
|
|
}
|
|
finally
|
|
{
|
|
result1513 |= 4;
|
|
throw new Exception("f");
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(e.msg == "d");
|
|
assert(e.next.msg == "f");
|
|
assert(!e.next.next);
|
|
}
|
|
}
|
|
|
|
void bug1513c()
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
throw new Exception("a");
|
|
}
|
|
finally
|
|
{
|
|
result1513 |= 1;
|
|
throw new Exception("b");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
bug1513b();
|
|
result1513 |= 2;
|
|
throw new Exception("c");
|
|
}
|
|
}
|
|
|
|
void bug1513()
|
|
{
|
|
result1513 = 0;
|
|
try
|
|
{
|
|
bug1513c();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(result1513 == 7);
|
|
assert(e.msg == "a");
|
|
assert(e.next.msg == "b");
|
|
assert(e.next.next.msg == "c");
|
|
}
|
|
}
|
|
|
|
bug1513();
|
|
}
|
|
|
|
void collideone()
|
|
{
|
|
try
|
|
{
|
|
throw new Exception("x");
|
|
}
|
|
finally
|
|
{
|
|
throw new Exception("y");
|
|
}
|
|
}
|
|
|
|
void doublecollide()
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
throw new Exception("p");
|
|
}
|
|
finally
|
|
{
|
|
throw new Exception("q");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
collideone();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(e.msg == "p");
|
|
assert(e.next.msg == "q");
|
|
assert(e.next.next.msg == "x");
|
|
assert(e.next.next.next.msg == "y");
|
|
assert(!e.next.next.next.next);
|
|
}
|
|
}
|
|
|
|
void collidetwo()
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
throw new Exception("p2");
|
|
}
|
|
finally
|
|
{
|
|
throw new Exception("q2");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
collideone();
|
|
}
|
|
}
|
|
|
|
void collideMixed()
|
|
{
|
|
int works = 6;
|
|
try
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
throw new Exception("e");
|
|
}
|
|
finally
|
|
{
|
|
throw new Error("t");
|
|
}
|
|
}
|
|
catch (Exception f)
|
|
{
|
|
// Doesn't catch, because Error is chained to it.
|
|
works += 2;
|
|
}
|
|
}
|
|
catch (Error z)
|
|
{
|
|
works += 4;
|
|
assert(z.msg == "t"); // Error comes first
|
|
assert(z.next is null);
|
|
assert(z.bypassedException.msg == "e");
|
|
}
|
|
assert(works == 10);
|
|
}
|
|
|
|
class AnotherException : Exception
|
|
{
|
|
this(string s)
|
|
{
|
|
super(s);
|
|
}
|
|
}
|
|
|
|
void multicollide()
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
try
|
|
{
|
|
throw new Exception("m2");
|
|
}
|
|
finally
|
|
{
|
|
throw new AnotherException("n2");
|
|
}
|
|
}
|
|
catch (AnotherException s)
|
|
{
|
|
// Not caught -- we needed to catch the root cause "m2", not
|
|
// just the collateral "n2" (which would leave m2 uncaught).
|
|
assert(0);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
collidetwo();
|
|
}
|
|
}
|
|
catch (Exception f)
|
|
{
|
|
assert(f.msg == "m2");
|
|
assert(f.next.msg == "n2");
|
|
Throwable e = f.next.next;
|
|
assert(e.msg == "p2");
|
|
assert(e.next.msg == "q2");
|
|
assert(e.next.next.msg == "x");
|
|
assert(e.next.next.next.msg == "y");
|
|
assert(!e.next.next.next.next);
|
|
}
|
|
}
|
|
|
|
int testsFromEH()
|
|
{
|
|
bug1513outer();
|
|
doublecollide();
|
|
collideMixed();
|
|
multicollide();
|
|
return 1;
|
|
}
|
|
static assert(testsFromEH());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6901
|
|
// With + synchronized statements
|
|
|
|
struct With1
|
|
{
|
|
int a;
|
|
int b;
|
|
}
|
|
|
|
class Foo6
|
|
{
|
|
}
|
|
|
|
class Foo32
|
|
{
|
|
struct Bar
|
|
{
|
|
int x;
|
|
}
|
|
}
|
|
|
|
class Base56
|
|
{
|
|
private string myfoo;
|
|
private string mybar;
|
|
|
|
// Get/set properties that will be overridden.
|
|
void foo(string s) { myfoo = s; }
|
|
string foo() { return myfoo; }
|
|
|
|
// Get/set properties that will not be overridden.
|
|
void bar(string s) { mybar = s; }
|
|
string bar() { return mybar; }
|
|
}
|
|
|
|
class Derived56 : Base56
|
|
{
|
|
alias Base56.foo foo; // Bring in Base56's foo getter.
|
|
override void foo(string s) { super.foo = s; } // Override foo setter.
|
|
}
|
|
|
|
int testwith()
|
|
{
|
|
With1 x = With1(7);
|
|
with (x)
|
|
{
|
|
a = 2;
|
|
}
|
|
assert(x.a == 2);
|
|
|
|
// from test11.d
|
|
Foo6 foo6 = new Foo6();
|
|
|
|
with (foo6)
|
|
{
|
|
int xx;
|
|
xx = 4;
|
|
}
|
|
with (new Foo32)
|
|
{
|
|
Bar z;
|
|
z.x = 5;
|
|
}
|
|
Derived56 d = new Derived56;
|
|
with (d)
|
|
{
|
|
foo = "hi";
|
|
d.foo = "hi";
|
|
bar = "hi";
|
|
assert(foo == "hi");
|
|
assert(d.foo == "hi");
|
|
assert(bar == "hi");
|
|
}
|
|
int w = 7;
|
|
synchronized
|
|
{
|
|
++w;
|
|
}
|
|
assert(w == 8);
|
|
return 1;
|
|
}
|
|
|
|
static assert(testwith());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9236
|
|
// ICE switch with(EnumType)
|
|
|
|
enum Command9236
|
|
{
|
|
Char,
|
|
Any,
|
|
};
|
|
|
|
bool bug9236(Command9236 cmd)
|
|
{
|
|
int n = 0;
|
|
with (Command9236) switch (cmd)
|
|
{
|
|
case Any:
|
|
n = 1;
|
|
break;
|
|
default:
|
|
n = 2;
|
|
}
|
|
assert(n == 1);
|
|
|
|
switch (cmd) with (Command9236)
|
|
{
|
|
case Any:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static assert(bug9236(Command9236.Any));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6416
|
|
// static struct declaration
|
|
|
|
static assert({
|
|
static struct S { int y = 7; }
|
|
S a;
|
|
a.y += 6;
|
|
assert(a.y == 13);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10499
|
|
// static template struct declaration
|
|
|
|
static assert({
|
|
static struct Result() {}
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13757
|
|
// extern(C) alias declaration
|
|
|
|
static assert({
|
|
alias FP1 = extern(C) int function();
|
|
alias extern(C) int function() FP2;
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6522
|
|
// opAssign + foreach ref
|
|
|
|
struct Foo6522
|
|
{
|
|
bool b = false;
|
|
void opAssign(int x)
|
|
{
|
|
this.b = true;
|
|
}
|
|
}
|
|
|
|
bool foo6522()
|
|
{
|
|
Foo6522[1] array;
|
|
foreach (ref item; array)
|
|
item = 1;
|
|
return true;
|
|
}
|
|
|
|
static assert(foo6522());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7245
|
|
// pointers + foreach ref
|
|
|
|
int bug7245(int testnum)
|
|
{
|
|
int[3] arr;
|
|
arr[0] = 4;
|
|
arr[1] = 6;
|
|
arr[2] = 8;
|
|
int* ptr;
|
|
|
|
foreach (i, ref p; arr)
|
|
{
|
|
if (i == 1)
|
|
ptr = &p;
|
|
if (testnum == 1)
|
|
p = 5;
|
|
}
|
|
|
|
return *ptr;
|
|
}
|
|
|
|
static assert(bug7245(0) == 6);
|
|
static assert(bug7245(1) == 5);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8498
|
|
// modifying foreach
|
|
// https://issues.dlang.org/show_bug.cgi?id=7658
|
|
// foreach ref
|
|
// https://issues.dlang.org/show_bug.cgi?id=8539
|
|
// nested funcs, ref param, -inline
|
|
|
|
int bug8498()
|
|
{
|
|
foreach (ref i; 0 .. 5)
|
|
{
|
|
assert(i == 0);
|
|
i = 100;
|
|
}
|
|
return 1;
|
|
}
|
|
static assert(bug8498());
|
|
|
|
string bug7658()
|
|
{
|
|
string[] children = ["0"];
|
|
foreach (ref child; children)
|
|
child = "1";
|
|
return children[0];
|
|
}
|
|
|
|
static assert(bug7658() == "1");
|
|
|
|
int bug8539()
|
|
{
|
|
static void one(ref int x)
|
|
{
|
|
x = 1;
|
|
}
|
|
static void go()
|
|
{
|
|
int y;
|
|
one(y);
|
|
assert(y == 1); // fails with -inline
|
|
}
|
|
go();
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug8539());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7874
|
|
// https://issues.dlang.org/show_bug.cgi?id=13297
|
|
// https://issues.dlang.org/show_bug.cgi?id=13740
|
|
// better lvalue handling
|
|
|
|
int bug7874(int x){ return ++x = 1; }
|
|
static assert(bug7874(0) == 1);
|
|
|
|
// ----
|
|
|
|
struct S13297
|
|
{
|
|
int* p;
|
|
}
|
|
void f13297(ref int* p)
|
|
{
|
|
p = cast(int*) 1;
|
|
assert(p); // passes
|
|
}
|
|
static assert(
|
|
{
|
|
S13297 s;
|
|
f13297(s.p);
|
|
return s.p != null; // false
|
|
}());
|
|
|
|
// ----
|
|
|
|
class R13740
|
|
{
|
|
int e;
|
|
bool empty = false;
|
|
@property ref front() { return e; }
|
|
void popFront() { empty = true; }
|
|
}
|
|
static assert({
|
|
auto r = new R13740();
|
|
foreach (ref e; r)
|
|
e = 42;
|
|
assert(r.e == 42); /* fails in CTFE */
|
|
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6919
|
|
|
|
void bug6919(int* val)
|
|
{
|
|
*val = 1;
|
|
}
|
|
void test6919()
|
|
{
|
|
int n;
|
|
bug6919(&n);
|
|
assert(n == 1);
|
|
}
|
|
static assert({ test6919(); return true; }());
|
|
|
|
void bug6919b(string* val)
|
|
{
|
|
*val = "1";
|
|
}
|
|
|
|
void test6919b()
|
|
{
|
|
string val;
|
|
bug6919b(&val);
|
|
assert(val == "1");
|
|
}
|
|
static assert({ test6919b(); return true; }());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6995
|
|
|
|
struct Foo6995
|
|
{
|
|
static size_t index(size_t v)()
|
|
{
|
|
return v;
|
|
}
|
|
}
|
|
|
|
static assert(Foo6995.index!(27)() == 27);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7043
|
|
// ref with -inline
|
|
|
|
int bug7043(S)(ref int x)
|
|
{
|
|
return x;
|
|
}
|
|
|
|
static assert({
|
|
int i = 416;
|
|
return bug7043!(char)(i);
|
|
}() == 416);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6037
|
|
// recursive ref
|
|
|
|
void bug6037(ref int x, bool b)
|
|
{
|
|
int w = 3;
|
|
if (b)
|
|
{
|
|
bug6037(w, false);
|
|
assert(w == 6);
|
|
}
|
|
else
|
|
{
|
|
x = 6;
|
|
assert(w == 3); // fails
|
|
}
|
|
}
|
|
|
|
int bug6037outer()
|
|
{
|
|
int q;
|
|
bug6037(q, true);
|
|
return 401;
|
|
}
|
|
|
|
static assert(bug6037outer() == 401);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14299
|
|
// [REG2.067a], more than one depth of recursive call with ref
|
|
|
|
string gen14299(int max, int idx, ref string name)
|
|
{
|
|
string ret;
|
|
name = [cast(char)(idx + '0')];
|
|
ret ~= name;
|
|
if (idx < max)
|
|
{
|
|
string subname;
|
|
ret ~= gen14299(max, idx + 1, subname);
|
|
}
|
|
ret ~= name;
|
|
return ret;
|
|
}
|
|
string test14299(int max)
|
|
{
|
|
string n;
|
|
return gen14299(max, 0, n);
|
|
}
|
|
static assert(test14299(1) == "0110"); // OK <- fail
|
|
static assert(test14299(2) == "012210"); // OK <- ICE
|
|
static assert(test14299(3) == "01233210");
|
|
static assert(test14299(4) == "0123443210");
|
|
static assert(test14299(5) == "012345543210");
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7940
|
|
// wrong code for complicated assign
|
|
|
|
struct Bug7940
|
|
{
|
|
int m;
|
|
}
|
|
|
|
struct App7940
|
|
{
|
|
Bug7940[] x;
|
|
}
|
|
|
|
int bug7940()
|
|
{
|
|
Bug7940[2] y;
|
|
App7940 app;
|
|
app.x = y[0 .. 1];
|
|
app.x[0].m = 12;
|
|
assert(y[0].m == 12);
|
|
assert(app.x[0].m == 12);
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug7940());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10298
|
|
// wrong code for struct array literal init
|
|
|
|
struct Bug10298
|
|
{
|
|
int m;
|
|
}
|
|
|
|
int bug10298()
|
|
{
|
|
Bug10298[1] y = [Bug10298(78)];
|
|
y[0].m = 6;
|
|
assert(y[0].m == 6);
|
|
|
|
// Root cause
|
|
Bug10298[1] x;
|
|
x[] = [cast(const Bug10298)(Bug10298(78))];
|
|
assert(x[0].m == 78);
|
|
return 1;
|
|
}
|
|
|
|
static assert(bug10298());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7266
|
|
// dotvar ref parameters
|
|
|
|
struct S7266 { int a; }
|
|
|
|
bool bug7266()
|
|
{
|
|
S7266 s;
|
|
s.a = 4;
|
|
bar7266(s.a);
|
|
assert(s.a == 5);
|
|
out7266(s.a);
|
|
assert(s.a == 7);
|
|
return true;
|
|
}
|
|
|
|
void bar7266(ref int b)
|
|
{
|
|
b = 5;
|
|
assert(b == 5);
|
|
}
|
|
|
|
void out7266(out int b)
|
|
{
|
|
b = 7;
|
|
assert(b == 7);
|
|
}
|
|
|
|
static assert(bug7266());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9982
|
|
// dotvar assign through pointer
|
|
|
|
struct Bug9982
|
|
{
|
|
int a;
|
|
}
|
|
|
|
int test9982()
|
|
{
|
|
Bug9982 x;
|
|
int*q = &x.a;
|
|
*q = 99;
|
|
assert(x.a == 99);
|
|
return 1;
|
|
}
|
|
|
|
static assert(test9982());
|
|
|
|
// https://issues.dlang.org/show_bug.cgi?id=9982
|
|
// rejects-valid case
|
|
|
|
struct SS9982
|
|
{
|
|
Bug9982 s2;
|
|
this(Bug9982 s1)
|
|
{
|
|
s2.a = 6;
|
|
emplace9982(&s2, s1);
|
|
assert(s2.a == 3);
|
|
}
|
|
}
|
|
|
|
void emplace9982(Bug9982* chunk, Bug9982 arg)
|
|
{
|
|
*chunk = arg;
|
|
}
|
|
|
|
enum s9982 = Bug9982(3);
|
|
enum p9982 = SS9982(s9982);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11618
|
|
// dotvar assign through casted pointer
|
|
|
|
struct Tuple11618(T...)
|
|
{
|
|
T field;
|
|
alias field this;
|
|
}
|
|
|
|
static assert({
|
|
Tuple11618!(immutable dchar) result = void;
|
|
auto addr = cast(dchar*)&result[0];
|
|
*addr = dchar.init;
|
|
return (result[0] == dchar.init);
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7143
|
|
// 'is' for classes
|
|
|
|
class C7143
|
|
{
|
|
int x;
|
|
}
|
|
|
|
int bug7143(int test)
|
|
{
|
|
C7143 c = new C7143;
|
|
C7143 d = new C7143;
|
|
if (test == 1)
|
|
{
|
|
if (c)
|
|
return c.x + 8;
|
|
return -1;
|
|
}
|
|
if (test == 2)
|
|
{
|
|
if (c is null)
|
|
return -1;
|
|
return c.x + 45;
|
|
}
|
|
if (test == 3)
|
|
{
|
|
if (c is c)
|
|
return 58;
|
|
}
|
|
if (test == 4)
|
|
{
|
|
if (c !is c)
|
|
return -1;
|
|
else
|
|
return 48;
|
|
}
|
|
if (test == 6)
|
|
d = c;
|
|
if (test == 5 || test == 6)
|
|
{
|
|
if (c is d)
|
|
return 188;
|
|
else
|
|
return 48;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static assert(bug7143(1) == 8);
|
|
static assert(bug7143(2) == 45);
|
|
static assert(bug7143(3) == 58);
|
|
static assert(bug7143(4) == 48);
|
|
static assert(bug7143(5) == 48);
|
|
static assert(bug7143(6) == 188);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7147
|
|
// virtual function calls from base class
|
|
|
|
class A7147
|
|
{
|
|
int foo() { return 0; }
|
|
|
|
int callfoo()
|
|
{
|
|
return foo();
|
|
}
|
|
}
|
|
|
|
class B7147 : A7147
|
|
{
|
|
override int foo() { return 1; }
|
|
}
|
|
|
|
int test7147()
|
|
{
|
|
A7147 a = new B7147;
|
|
return a.callfoo();
|
|
}
|
|
|
|
static assert(test7147() == 1);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7158
|
|
|
|
class C7158
|
|
{
|
|
bool b() { return true; }
|
|
}
|
|
struct S7158
|
|
{
|
|
C7158 c;
|
|
}
|
|
|
|
bool test7158()
|
|
{
|
|
S7158 s = S7158(new C7158);
|
|
return s.c.b;
|
|
}
|
|
static assert(test7158());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8484
|
|
|
|
class C8484
|
|
{
|
|
int n;
|
|
int b() { return n + 3; }
|
|
}
|
|
|
|
struct S
|
|
{
|
|
C8484 c;
|
|
}
|
|
|
|
int t8484(ref C8484 c)
|
|
{
|
|
return c.b();
|
|
}
|
|
|
|
int test8484()
|
|
{
|
|
auto s = S(new C8484);
|
|
s.c.n = 4;
|
|
return t8484(s.c);
|
|
}
|
|
static assert(test8484() == 7);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7419
|
|
|
|
struct X7419
|
|
{
|
|
double x;
|
|
this(double x)
|
|
{
|
|
this.x = x;
|
|
}
|
|
}
|
|
|
|
void bug7419()
|
|
{
|
|
enum x = {
|
|
auto p = X7419(3);
|
|
return p.x;
|
|
}();
|
|
static assert(x == 3);
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9445
|
|
// ice
|
|
|
|
template c9445(T...) { }
|
|
|
|
void ice9445(void delegate() expr, void function() f2)
|
|
{
|
|
static assert(!is(typeof(c9445!(f2()))));
|
|
static assert(!is(typeof(c9445!(expr()))));
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10452
|
|
// delegate ==
|
|
|
|
struct S10452
|
|
{
|
|
bool func() { return true; }
|
|
}
|
|
|
|
struct Outer10452
|
|
{
|
|
S10452 inner;
|
|
}
|
|
|
|
class C10452
|
|
{
|
|
bool func() { return true; }
|
|
}
|
|
|
|
bool delegate() ref10452(return ref S10452 s)
|
|
{
|
|
return &s.func;
|
|
}
|
|
|
|
bool test10452()
|
|
{
|
|
bool delegate() bar = () { return true; };
|
|
|
|
assert(bar !is null);
|
|
assert(bar is bar);
|
|
|
|
S10452 bag;
|
|
S10452[6] bad;
|
|
Outer10452 outer;
|
|
C10452 tag = new C10452;
|
|
|
|
auto rat = &outer.inner.func;
|
|
assert(rat == rat);
|
|
auto tat = &tag.func;
|
|
assert(tat == tat);
|
|
|
|
auto bat = &outer.inner.func;
|
|
auto mat = &bad[2].func;
|
|
assert(mat is mat);
|
|
assert(rat == bat);
|
|
|
|
auto zat = &bag.func;
|
|
auto cat = &bag.func;
|
|
assert(zat == zat);
|
|
assert(zat == cat);
|
|
|
|
auto drat = ref10452(bag);
|
|
assert(cat == drat);
|
|
assert(drat == drat);
|
|
drat = ref10452(bad[2]);
|
|
assert( drat == mat);
|
|
assert(tat != rat);
|
|
assert(zat != rat);
|
|
assert(rat != cat);
|
|
assert(zat != bar);
|
|
assert(tat != cat);
|
|
cat = bar;
|
|
assert(cat == bar);
|
|
return true;
|
|
}
|
|
static assert(test10452());
|
|
|
|
/**************************************************/
|
|
//https://issues.dlang.org/show_bug.cgi?id=7162
|
|
// https://issues.dlang.org/show_bug.cgi?id=4711
|
|
|
|
void f7162() { }
|
|
|
|
bool ice7162()
|
|
{
|
|
false && f7162();
|
|
false || f7162();
|
|
false && f7162(); // https://issues.dlang.org/show_bug.cgi?id=4711
|
|
true && f7162();
|
|
return true;
|
|
}
|
|
|
|
static assert(ice7162());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8857
|
|
// only with -inline (creates an &&)
|
|
|
|
struct Result8857 { char[] next; }
|
|
|
|
void bug8857()()
|
|
{
|
|
Result8857 r;
|
|
r.next = null;
|
|
if (true)
|
|
{
|
|
auto next = r.next;
|
|
}
|
|
}
|
|
static assert({
|
|
bug8857();
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7527
|
|
|
|
struct Bug7527
|
|
{
|
|
char[] data;
|
|
}
|
|
|
|
enum bug7527 = ()
|
|
{
|
|
auto app = Bug7527();
|
|
|
|
app.data.ptr[0 .. 1] = "x";
|
|
return 1;
|
|
};
|
|
|
|
static assert(!is(typeof(compiles!(bug7527()))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7527
|
|
|
|
int bug7380;
|
|
|
|
static assert(!is(typeof( compiles!(
|
|
(){
|
|
return &bug7380;
|
|
}()
|
|
))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7165
|
|
|
|
struct S7165
|
|
{
|
|
int* ptr;
|
|
bool f() const { return !!ptr; }
|
|
}
|
|
|
|
static assert(!S7165().f());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7187
|
|
|
|
int[] f7187() { return [0]; }
|
|
int[] f7187b(int n) { return [0]; }
|
|
|
|
int g7187(int[] r)
|
|
{
|
|
auto t = r[0 .. 0];
|
|
return 1;
|
|
}
|
|
|
|
static assert(g7187(f7187()));
|
|
static assert(g7187(f7187b(7)));
|
|
|
|
struct S7187 { const(int)[] field; }
|
|
|
|
const(int)[] f7187c()
|
|
{
|
|
auto s = S7187([0]);
|
|
return s.field;
|
|
}
|
|
|
|
bool g7187c(const(int)[] r)
|
|
{
|
|
auto t = r[0 .. 0];
|
|
return true;
|
|
}
|
|
|
|
static assert(g7187c(f7187c()));
|
|
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6933
|
|
// struct destructors
|
|
|
|
struct Bug6933
|
|
{
|
|
int x = 3;
|
|
~this() { }
|
|
}
|
|
|
|
int test6933()
|
|
{
|
|
Bug6933 q;
|
|
assert(q.x == 3);
|
|
return 3;
|
|
}
|
|
|
|
static assert(test6933());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7197
|
|
|
|
int foo7197(int[] x...)
|
|
{
|
|
return 1;
|
|
}
|
|
template bar7197(y...)
|
|
{
|
|
enum int bar7197 = foo7197(y);
|
|
}
|
|
enum int bug7197 = 7;
|
|
static assert(bar7197!(bug7197));
|
|
|
|
/**************************************************
|
|
Enum string compare
|
|
**************************************************/
|
|
|
|
enum EScmp : string { a = "aaa" }
|
|
|
|
bool testEScmp()
|
|
{
|
|
EScmp x = EScmp.a;
|
|
assert(x < "abc");
|
|
return true;
|
|
}
|
|
|
|
static assert(testEScmp());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7667
|
|
|
|
bool baz7667(int[] vars...)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
struct S7667
|
|
{
|
|
static void his(int n)
|
|
{
|
|
static assert(baz7667(2));
|
|
}
|
|
}
|
|
|
|
bool bug7667()
|
|
{
|
|
S7667 unused;
|
|
unused.his(7);
|
|
return true;
|
|
}
|
|
enum e7667 = bug7667();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7536
|
|
|
|
bool bug7536(string expr)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void vop()
|
|
{
|
|
const string x7536 = "x";
|
|
static assert(bug7536(x7536));
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6681
|
|
// unions
|
|
|
|
struct S6681
|
|
{
|
|
this(int a, int b) { this.a = b; this.b = a; }
|
|
union
|
|
{
|
|
ulong g;
|
|
struct { int a, b; };
|
|
}
|
|
}
|
|
|
|
static immutable S6681 s6681 = S6681(0, 1);
|
|
|
|
bool bug6681(int test)
|
|
{
|
|
S6681 x = S6681(0, 1);
|
|
x.g = 5;
|
|
auto u = &x.g;
|
|
auto v = &x.a;
|
|
long w = *u;
|
|
int z;
|
|
assert(w == 5);
|
|
if (test == 4)
|
|
z = *v; // error
|
|
x.a = 2; // invalidate g, and hence u.
|
|
if (test == 1)
|
|
w = *u; // error
|
|
z = *v;
|
|
assert(z == 2);
|
|
x.g = 6;
|
|
w = *u;
|
|
assert(w == 6);
|
|
if (test == 3)
|
|
z = *v;
|
|
return true;
|
|
}
|
|
static assert(bug6681(2));
|
|
static assert(!is(typeof(compiles!(bug6681(1)))));
|
|
static assert(!is(typeof(compiles!(bug6681(3)))));
|
|
static assert(!is(typeof(compiles!(bug6681(4)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9113
|
|
// ICE with struct in union
|
|
|
|
union U9113
|
|
{
|
|
struct M
|
|
{
|
|
int y;
|
|
}
|
|
int xx;
|
|
}
|
|
|
|
int bug9113(T)()
|
|
{
|
|
U9113 x;
|
|
x.M.y = 10; // error, need 'this'
|
|
return 1;
|
|
}
|
|
|
|
static assert(!is(typeof(compiles!(bug9113!(int)()))));
|
|
|
|
/**************************************************
|
|
Creation of unions
|
|
**************************************************/
|
|
|
|
union UnionTest1
|
|
{
|
|
int x;
|
|
float y;
|
|
}
|
|
|
|
int uniontest1()
|
|
{
|
|
UnionTest1 u = UnionTest1(1);
|
|
return 1;
|
|
}
|
|
|
|
static assert(uniontest1());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=6438
|
|
// void
|
|
|
|
struct S6438
|
|
{
|
|
int a;
|
|
int b = void;
|
|
}
|
|
|
|
void fill6438(int[] arr, int testnum)
|
|
{
|
|
if (testnum == 2)
|
|
{
|
|
auto u = arr[0];
|
|
}
|
|
foreach (ref x; arr)
|
|
x = 7;
|
|
auto r = arr[0];
|
|
S6438[2] s;
|
|
auto p = &s[0].b;
|
|
if (testnum == 3)
|
|
{
|
|
auto v = *p;
|
|
}
|
|
}
|
|
|
|
bool bug6438(int testnum)
|
|
{
|
|
int[4] stackSpace = void;
|
|
fill6438(stackSpace[], testnum);
|
|
assert(stackSpace == [7, 7, 7, 7]);
|
|
return true;
|
|
}
|
|
|
|
static assert( is(typeof(compiles!(bug6438(1)))));
|
|
static assert(!is(typeof(compiles!(bug6438(2)))));
|
|
static assert(!is(typeof(compiles!(bug6438(3)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10994
|
|
// void static array members
|
|
|
|
struct Bug10994
|
|
{
|
|
ubyte[2] buf = void;
|
|
}
|
|
|
|
static bug10994 = Bug10994.init;
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10937
|
|
// struct inside union
|
|
|
|
struct S10937
|
|
{
|
|
union
|
|
{
|
|
ubyte[1] a;
|
|
struct
|
|
{
|
|
ubyte b;
|
|
}
|
|
}
|
|
|
|
this(ubyte B)
|
|
{
|
|
if (B > 6)
|
|
this.b = B;
|
|
else
|
|
this.a[0] = B;
|
|
}
|
|
}
|
|
|
|
enum test10937 = S10937(7);
|
|
enum west10937 = S10937(2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13831
|
|
|
|
struct Vector13831()
|
|
{
|
|
}
|
|
|
|
struct Coord13831
|
|
{
|
|
union
|
|
{
|
|
struct { short x; }
|
|
Vector13831!() vector;
|
|
}
|
|
}
|
|
|
|
struct Chunk13831
|
|
{
|
|
this(Coord13831 coord)
|
|
{
|
|
this.coord = coord;
|
|
}
|
|
|
|
Coord13831 coord;
|
|
|
|
static const Chunk13831* unknownChunk = new Chunk13831(Coord13831());
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7732
|
|
|
|
struct AssociativeArray
|
|
{
|
|
int* impl;
|
|
int f()
|
|
{
|
|
if (impl !is null)
|
|
auto x = *impl;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int test7732()
|
|
{
|
|
AssociativeArray aa;
|
|
return aa.f;
|
|
}
|
|
|
|
static assert(test7732());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7784
|
|
struct Foo7784
|
|
{
|
|
void bug()
|
|
{
|
|
tab["A"] = Bar7784(&this);
|
|
auto pbar = "A" in tab;
|
|
auto bar = *pbar;
|
|
}
|
|
|
|
Bar7784[string] tab;
|
|
}
|
|
|
|
struct Bar7784
|
|
{
|
|
Foo7784* foo;
|
|
int val;
|
|
}
|
|
|
|
bool ctfe7784()
|
|
{
|
|
auto foo = Foo7784();
|
|
foo.bug();
|
|
return true;
|
|
}
|
|
|
|
static assert(ctfe7784());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7781
|
|
|
|
static assert(({ return true; }()));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7785
|
|
|
|
bool bug7785(int n)
|
|
{
|
|
int val = 7;
|
|
auto p = &val;
|
|
if (n == 2)
|
|
{
|
|
auto ary = p[0 .. 1];
|
|
}
|
|
auto x = p[0];
|
|
val = 6;
|
|
assert(x == 7);
|
|
if (n == 3)
|
|
p[0 .. 1] = 1;
|
|
return true;
|
|
}
|
|
|
|
static assert(bug7785(1));
|
|
static assert(!is(typeof(compiles!(bug7785(2)))));
|
|
static assert(!is(typeof(compiles!(bug7785(3)))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7987
|
|
|
|
class C7987
|
|
{
|
|
int m;
|
|
}
|
|
|
|
struct S7987
|
|
{
|
|
int* p;
|
|
C7987 c;
|
|
}
|
|
|
|
bool bug7987()
|
|
{
|
|
int[7] q;
|
|
int[][2] b = q[0 .. 5];
|
|
assert(b == b);
|
|
assert(b is b);
|
|
C7987 c1 = new C7987;
|
|
C7987 c2 = new C7987;
|
|
S7987 s, t;
|
|
s.p = &q[0];
|
|
t.p = &q[1];
|
|
assert(s != t);
|
|
s.p = &q[1];
|
|
/*assert(s == t);*/ assert(s.p == t.p);
|
|
s.c = c1;
|
|
t.c = c2;
|
|
/*assert(s != t);*/ assert(s.c !is t.c);
|
|
assert(s !is t);
|
|
s.c = c2;
|
|
/*assert(s == t);*/ assert(s.p == t.p && s.c is t.c);
|
|
assert(s is t);
|
|
return true;
|
|
}
|
|
|
|
static assert(bug7987());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10579
|
|
// typeinfo.func() must not segfault
|
|
|
|
static assert(!is(typeof(compiles!(typeid(int).toString.length))));
|
|
|
|
class Bug10579
|
|
{
|
|
int foo() { return 1; }
|
|
}
|
|
Bug10579 uninitialized10579;
|
|
|
|
static assert(!is(typeof(compiles!(uninitialized10579.foo()))));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10804
|
|
// mixin ArrayLiteralExp typed string
|
|
|
|
void test10804()
|
|
{
|
|
String identity(String)(String a) { return a; }
|
|
|
|
string cfun()
|
|
{
|
|
char[] s;
|
|
s.length = 8 + 2 + (2) + 1 + 2;
|
|
s[] = "identity(`Ω`c)"c[];
|
|
return cast(string)s; // Return ArrayLiteralExp as the CTFE result
|
|
}
|
|
{
|
|
enum a1 = "identity(`Ω`c)"c;
|
|
enum a2 = cfun();
|
|
static assert(cast(ubyte[])mixin(a1) == [0xCE, 0xA9]);
|
|
static assert(cast(ubyte[])mixin(a2) == [0xCE, 0xA9]); // should pass
|
|
}
|
|
|
|
wstring wfun()
|
|
{
|
|
wchar[] s;
|
|
s.length = 8 + 2 + (2) + 1 + 2;
|
|
s[] = "identity(`\U0002083A`w)"w[];
|
|
return cast(wstring)s; // Return ArrayLiteralExp as the CTFE result
|
|
}
|
|
{
|
|
enum a1 = "identity(`\U0002083A`w)"w;
|
|
enum a2 = wfun();
|
|
static assert(cast(ushort[])mixin(a1) == [0xD842, 0xDC3A]);
|
|
static assert(cast(ushort[])mixin(a2) == [0xD842, 0xDC3A]);
|
|
}
|
|
|
|
dstring dfun()
|
|
{
|
|
dchar[] s;
|
|
s.length = 8 + 2 + (1) + 1 + 2;
|
|
s[] = "identity(`\U00101000`d)"d[];
|
|
return cast(dstring)s; // Return ArrayLiteralExp as the CTFE result
|
|
}
|
|
{
|
|
enum a1 = "identity(`\U00101000`d)"d;
|
|
enum a2 = dfun();
|
|
static assert(cast(uint[])mixin(a1) == [0x00101000]);
|
|
static assert(cast(uint[])mixin(a2) == [0x00101000]);
|
|
}
|
|
}
|
|
|
|
/******************************************************/
|
|
|
|
struct B73 {}
|
|
struct C73 { B73 b; }
|
|
C73 func73() { C73 b = void; b.b = B73(); return b; }
|
|
C73 test73 = func73();
|
|
|
|
/******************************************************/
|
|
|
|
struct S74
|
|
{
|
|
int[1] n;
|
|
static S74 test(){ S74 ret = void; ret.n[0] = 0; return ret; }
|
|
}
|
|
|
|
enum Test74 = S74.test();
|
|
|
|
/******************************************************/
|
|
|
|
static bool bug8865()
|
|
in
|
|
{
|
|
int x = 0;
|
|
label:
|
|
foreach (i; (++x) .. 3)
|
|
{
|
|
if (i == 1)
|
|
continue label; // doesn't work.
|
|
else
|
|
break label; // doesn't work.
|
|
}
|
|
}
|
|
out
|
|
{
|
|
int x = 0;
|
|
label:
|
|
foreach (i; (++x) .. 3)
|
|
{
|
|
if (i == 1)
|
|
continue label; // doesn't work.
|
|
else
|
|
break label; // doesn't work.
|
|
}
|
|
}
|
|
do
|
|
{
|
|
int x = 0;
|
|
label:
|
|
foreach (i; (++x) .. 3)
|
|
{
|
|
if (i == 1)
|
|
continue label; // works.
|
|
else
|
|
break label; // works.
|
|
}
|
|
|
|
return true;
|
|
}
|
|
static assert(bug8865());
|
|
|
|
/******************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=15450
|
|
// labeled foreach + continue/break
|
|
|
|
static assert({
|
|
L1:
|
|
foreach (l; [0])
|
|
continue L1;
|
|
|
|
L2:
|
|
foreach (l; [0])
|
|
break L2;
|
|
|
|
return true;
|
|
}());
|
|
|
|
struct Test75
|
|
{
|
|
this(int) pure {}
|
|
}
|
|
|
|
/******************************************************/
|
|
|
|
static assert( __traits(compiles, { static shared(Test75*) t75 = new shared(Test75)(0); return t75; }));
|
|
static assert( __traits(compiles, { static shared(Test75)* t75 = new shared(Test75)(0); return t75; }));
|
|
static assert( __traits(compiles, { static __gshared Test75* t75 = new Test75(0); return t75; }));
|
|
static assert( __traits(compiles, { static const(Test75*) t75 = new const(Test75)(0); return t75; }));
|
|
static assert( __traits(compiles, { static immutable Test75* t75 = new immutable(Test75)(0); return t75; }));
|
|
static assert(!__traits(compiles, { static Test75* t75 = new Test75(0); return t75; }));
|
|
/+
|
|
static assert(!__traits(compiles, { enum t75 = new shared(Test75)(0); return t75; }));
|
|
static assert(!__traits(compiles, { enum t75 = new Test75(0); return t75; }));
|
|
static assert(!__traits(compiles, { enum shared(Test75)* t75 = new shared(Test75)(0); return t75; }));
|
|
static assert(!__traits(compiles, { enum Test75* t75 = new Test75(0); return t75; }));
|
|
|
|
static assert( __traits(compiles, { enum t75 = new const(Test75)(0); return t75;}));
|
|
static assert( __traits(compiles, { enum t75 = new immutable(Test75)(0); return t75;}));
|
|
static assert( __traits(compiles, { enum const(Test75)* t75 = new const(Test75)(0); return t75;}));
|
|
static assert( __traits(compiles, { enum immutable(Test75)* t75 = new immutable(Test75)(0); return t75;}));
|
|
+/
|
|
/******************************************************/
|
|
|
|
class Test76
|
|
{
|
|
this(int) pure {}
|
|
}
|
|
/+
|
|
static assert(!__traits(compiles, { enum t76 = new shared(Test76)(0); return t76;}));
|
|
static assert(!__traits(compiles, { enum t76 = new Test76(0); return t76;}));
|
|
static assert(!__traits(compiles, { enum shared(Test76) t76 = new shared(Test76)(0); return t76;}));
|
|
static assert(!__traits(compiles, { enum Test76 t76 = new Test76(0); return t76;}));
|
|
|
|
static assert( __traits(compiles, { enum t76 = new const(Test76)(0); return t76;}));
|
|
static assert( __traits(compiles, { enum t76 = new immutable(Test76)(0); return t76;}));
|
|
static assert( __traits(compiles, { enum const(Test76) t76 = new const(Test76)(0); return t76;}));
|
|
static assert( __traits(compiles, { enum immutable(Test76) t76 = new immutable(Test76)(0); return t76;}));
|
|
+/
|
|
/******************************************************/
|
|
|
|
static assert( __traits(compiles, { static shared Test76 t76 = new shared(Test76)(0); return t76; }));
|
|
static assert( __traits(compiles, { static shared(Test76) t76 = new shared(Test76)(0); return t76; }));
|
|
static assert( __traits(compiles, { static __gshared Test76 t76 = new Test76(0); return t76; }));
|
|
static assert( __traits(compiles, { static const Test76 t76 = new const(Test76)(0); return t76; }));
|
|
static assert( __traits(compiles, { static immutable Test76 t76 = new immutable Test76(0); return t76; }));
|
|
static assert(!__traits(compiles, { static Test76 t76 = new Test76(0); return t76; }));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=5678
|
|
|
|
struct Bug5678
|
|
{
|
|
this(int) {}
|
|
}
|
|
|
|
static assert(!__traits(compiles, { enum const(Bug5678)* b5678 = new const(Bug5678)(0); return b5678; }));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10782
|
|
// run semantic2 for class field
|
|
|
|
enum e10782 = 0;
|
|
class C10782 { int x = e10782; }
|
|
string f10782()
|
|
{
|
|
auto c = new C10782();
|
|
return "";
|
|
}
|
|
mixin(f10782());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10929
|
|
// NRVO support in CTFE
|
|
|
|
struct S10929
|
|
{
|
|
this(this)
|
|
{
|
|
postblitCount++;
|
|
}
|
|
~this()
|
|
{
|
|
dtorCount++;
|
|
}
|
|
int payload;
|
|
int dtorCount;
|
|
int postblitCount;
|
|
}
|
|
|
|
auto makeS10929()
|
|
{
|
|
auto s = S10929(42, 0, 0);
|
|
return s;
|
|
}
|
|
|
|
bool test10929()
|
|
{
|
|
auto s = makeS10929();
|
|
assert(s.postblitCount == 0);
|
|
assert(s.dtorCount == 0);
|
|
return true;
|
|
};
|
|
static assert(test10929());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9245
|
|
// support postblit call on array assignments
|
|
|
|
bool test9245()
|
|
{
|
|
int postblits = 0;
|
|
struct S
|
|
{
|
|
this(this)
|
|
{
|
|
++postblits;
|
|
}
|
|
}
|
|
|
|
S s;
|
|
S[2] a;
|
|
assert(postblits == 0);
|
|
|
|
{
|
|
S[2] arr = s;
|
|
assert(postblits == 2);
|
|
arr[] = s;
|
|
assert(postblits == 4);
|
|
postblits = 0;
|
|
|
|
S[2] arr2 = arr;
|
|
assert(postblits == 2);
|
|
arr2 = arr;
|
|
assert(postblits == 4);
|
|
postblits = 0;
|
|
|
|
const S[2] constArr = s;
|
|
assert(postblits == 2);
|
|
postblits = 0;
|
|
|
|
const S[2] constArr2 = arr;
|
|
assert(postblits == 2);
|
|
postblits = 0;
|
|
}
|
|
{
|
|
S[2][2] arr = s;
|
|
assert(postblits == 4);
|
|
arr[] = a;
|
|
assert(postblits == 8);
|
|
postblits = 0;
|
|
|
|
S[2][2] arr2 = arr;
|
|
assert(postblits == 4);
|
|
arr2 = arr;
|
|
assert(postblits == 8);
|
|
postblits = 0;
|
|
|
|
const S[2][2] constArr = s;
|
|
assert(postblits == 4);
|
|
postblits = 0;
|
|
|
|
const S[2][2] constArr2 = arr;
|
|
assert(postblits == 4);
|
|
postblits = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
static assert(test9245());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12906
|
|
// don't call postblit on blit initializing
|
|
|
|
struct S12906 { this(this) { assert(0); } }
|
|
|
|
static assert({
|
|
S12906[1] arr;
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11510
|
|
// support overlapped field access in CTFE
|
|
|
|
struct S11510
|
|
{
|
|
union
|
|
{
|
|
size_t x;
|
|
int* y; // pointer field
|
|
}
|
|
}
|
|
bool test11510()
|
|
{
|
|
S11510 s;
|
|
|
|
s.y = [1,2,3].ptr; // writing overlapped pointer field is OK
|
|
assert(s.y[0 .. 3] == [1,2,3]); // reading valid field is OK
|
|
|
|
s.x = 10;
|
|
assert(s.x == 10);
|
|
|
|
// There's no reinterpretation between S.x and S.y
|
|
return true;
|
|
}
|
|
static assert(test11510());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11534
|
|
// subtitude inout
|
|
|
|
struct MultiArray11534
|
|
{
|
|
void set(size_t[] sizes...)
|
|
{
|
|
storage = new size_t[5];
|
|
}
|
|
|
|
@property auto raw_ptr() inout
|
|
{
|
|
return storage.ptr + 1;
|
|
}
|
|
size_t[] storage;
|
|
}
|
|
|
|
enum test11534 = () {
|
|
auto m = MultiArray11534();
|
|
m.set(3,2,1);
|
|
auto start = m.raw_ptr; //this trigger the bug
|
|
//auto start = m.storage.ptr + 1; //this obviously works
|
|
return 0;
|
|
}();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11941
|
|
// Regression of 11534 fix
|
|
|
|
void takeConst11941(const string[]) {}
|
|
string[] identity11941(string[] x) { return x; }
|
|
|
|
bool test11941a()
|
|
{
|
|
struct S { string[] a; }
|
|
S s;
|
|
|
|
takeConst11941(identity11941(s.a));
|
|
s.a ~= [];
|
|
|
|
return true;
|
|
}
|
|
static assert(test11941a());
|
|
|
|
bool test11941b()
|
|
{
|
|
struct S { string[] a; }
|
|
S s;
|
|
|
|
takeConst11941(identity11941(s.a));
|
|
s.a ~= "foo"; /* Error refers to this line (15), */
|
|
string[] b = s.a[]; /* but only when this is here. */
|
|
|
|
return true;
|
|
}
|
|
static assert(test11941b());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11535
|
|
// element-wise assignment from string to ubyte array literal
|
|
|
|
struct Hash11535
|
|
{
|
|
ubyte[6] _buffer;
|
|
|
|
void put(scope const(ubyte)[] data...)
|
|
{
|
|
uint i = 0, index = 0;
|
|
auto inputLen = data.length;
|
|
|
|
(&_buffer[index])[0 .. inputLen - i] = (&data[i])[0 .. inputLen - i];
|
|
}
|
|
}
|
|
|
|
auto md5_digest11535(T...)(scope const T data)
|
|
{
|
|
Hash11535 hash;
|
|
hash.put(cast(const(ubyte[]))data[0]);
|
|
return hash._buffer;
|
|
}
|
|
|
|
static assert(md5_digest11535(`TEST`) == [84, 69, 83, 84, 0, 0]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11540
|
|
// goto label + try-catch-finally / with statement
|
|
|
|
static assert(()
|
|
{
|
|
// jump inside TryCatchStatement.body
|
|
{
|
|
bool c = false;
|
|
try
|
|
{
|
|
if (c) // need to bypass front-end optimization
|
|
throw new Exception("");
|
|
else
|
|
goto L2;
|
|
L2:
|
|
;
|
|
}
|
|
catch (Exception e) {}
|
|
}
|
|
|
|
// exit from TryCatchStatement.body
|
|
{
|
|
bool c = false;
|
|
try
|
|
{
|
|
if (c) // need to bypass front-end optimization
|
|
throw new Exception("");
|
|
else
|
|
goto L3;
|
|
}
|
|
catch (Exception e) {}
|
|
|
|
c = true;
|
|
L3:
|
|
assert(!c);
|
|
}
|
|
|
|
return 1;
|
|
}());
|
|
|
|
static assert(()
|
|
{
|
|
// enter to TryCatchStatement.catches which has no exception variable
|
|
{
|
|
bool c = false;
|
|
goto L1;
|
|
try
|
|
{
|
|
c = true;
|
|
}
|
|
catch (Exception/* e*/)
|
|
{
|
|
L1:
|
|
;
|
|
}
|
|
assert(c == false);
|
|
}
|
|
|
|
// jump inside TryCatchStatement.catches
|
|
{
|
|
bool c = false;
|
|
try
|
|
{
|
|
throw new Exception("");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
goto L2;
|
|
c = true;
|
|
L2:
|
|
;
|
|
}
|
|
assert(c == false);
|
|
}
|
|
|
|
// exit from TryCatchStatement.catches
|
|
{
|
|
bool c = false;
|
|
try
|
|
{
|
|
throw new Exception("");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
goto L3;
|
|
c = true;
|
|
}
|
|
L3:
|
|
assert(c == false);
|
|
}
|
|
|
|
return 1;
|
|
}());
|
|
|
|
static assert(()
|
|
{
|
|
// jump inside TryFinallyStatement.body
|
|
{
|
|
try
|
|
{
|
|
goto L2;
|
|
L2: ;
|
|
}
|
|
finally {}
|
|
}
|
|
|
|
// exit from TryFinallyStatement.body
|
|
{
|
|
bool c = false;
|
|
try
|
|
{
|
|
goto L3;
|
|
}
|
|
finally {}
|
|
|
|
c = true;
|
|
L3:
|
|
assert(!c);
|
|
}
|
|
|
|
// enter in / exit out from finally block is rejected in semantic analysis
|
|
|
|
// jump inside TryFinallyStatement.finalbody
|
|
{
|
|
bool c = false;
|
|
try
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
goto L4;
|
|
c = true;
|
|
L4:
|
|
assert(c == false);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}());
|
|
|
|
static assert(()
|
|
{
|
|
{
|
|
bool c = false;
|
|
with (Object.init)
|
|
{
|
|
goto L2;
|
|
c = true;
|
|
L2:
|
|
;
|
|
}
|
|
assert(c == false);
|
|
}
|
|
|
|
{
|
|
bool c = false;
|
|
with (Object.init)
|
|
{
|
|
goto L3;
|
|
c = true;
|
|
}
|
|
L3:
|
|
assert(c == false);
|
|
}
|
|
|
|
return 1;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11627
|
|
//cast dchar to char at compile time on AA assignment
|
|
|
|
bool test11627()
|
|
{
|
|
char[ubyte] toCharTmp;
|
|
dchar letter = 'A';
|
|
|
|
//char c = cast(char)letter; // OK
|
|
toCharTmp[0] = cast(char)letter; // NG
|
|
|
|
return true;
|
|
}
|
|
static assert(test11627());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11664
|
|
// ignore function local static variables
|
|
|
|
bool test11664()
|
|
{
|
|
static int x;
|
|
static int y = 1;
|
|
return true;
|
|
}
|
|
static assert(test11664());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12110
|
|
// operand of dereferencing does not need to be an lvalue
|
|
|
|
struct SliceOverIndexed12110
|
|
{
|
|
Uint24Array12110* arr;
|
|
|
|
@property front(uint val)
|
|
{
|
|
arr.dupThisReference();
|
|
}
|
|
}
|
|
|
|
struct Uint24Array12110
|
|
{
|
|
ubyte[] data;
|
|
|
|
this(ubyte[] range)
|
|
{
|
|
data = range;
|
|
SliceOverIndexed12110(&this).front = 0;
|
|
assert(data.length == range.length * 2);
|
|
}
|
|
|
|
void dupThisReference()
|
|
{
|
|
auto new_data = new ubyte[data.length * 2];
|
|
data = new_data;
|
|
}
|
|
}
|
|
|
|
static m12110 = Uint24Array12110([0x80]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12310
|
|
// heap allocation for built-in sclar types
|
|
|
|
bool test12310()
|
|
{
|
|
auto p1 = new int, p2 = p1;
|
|
assert(*p1 == 0);
|
|
assert(*p2 == 0);
|
|
*p1 = 10;
|
|
assert(*p1 == 10);
|
|
assert(*p2 == 10);
|
|
|
|
auto q1 = new int(3), q2 = q1;
|
|
assert(*q1 == 3);
|
|
assert(*q2 == 3);
|
|
*q1 = 20;
|
|
assert(*q1 == 20);
|
|
assert(*q2 == 20);
|
|
|
|
return true;
|
|
}
|
|
static assert(test12310());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12499
|
|
// initialize TupleDeclaraion in CTFE
|
|
|
|
auto f12499()
|
|
{
|
|
//Initialize 3 ints to 5.
|
|
TypeTuple!(int, int, int) a = 5;
|
|
return a[0]; //Error: variable _a_field_0 cannot be read at compile time
|
|
}
|
|
static assert(f12499() == 5);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12602
|
|
// slice in struct literal members
|
|
|
|
struct Result12602
|
|
{
|
|
uint[] source;
|
|
}
|
|
|
|
auto wrap12602a(uint[] r)
|
|
{
|
|
return Result12602(r);
|
|
}
|
|
|
|
auto wrap12602b(uint[] r)
|
|
{
|
|
Result12602 x;
|
|
x.source = r;
|
|
return x;
|
|
}
|
|
|
|
auto testWrap12602a()
|
|
{
|
|
uint[] dest = [1, 2, 3, 4];
|
|
|
|
auto ra = wrap12602a(dest[0 .. 2]);
|
|
auto rb = wrap12602a(dest[2 .. 4]);
|
|
|
|
foreach (i; 0 .. 2)
|
|
rb.source[i] = ra.source[i];
|
|
|
|
assert(ra.source == [1,2]);
|
|
assert(rb.source == [1,2]);
|
|
assert(&ra.source[0] == &dest[0]);
|
|
assert(&rb.source[0] == &dest[2]);
|
|
assert(dest == [1,2,1,2]);
|
|
return dest;
|
|
}
|
|
|
|
auto testWrap12602b()
|
|
{
|
|
uint[] dest = [1, 2, 3, 4];
|
|
|
|
auto ra = wrap12602b(dest[0 .. 2]);
|
|
auto rb = wrap12602b(dest[2 .. 4]);
|
|
|
|
foreach (i; 0 .. 2)
|
|
rb.source[i] = ra.source[i];
|
|
|
|
assert(ra.source == [1,2]);
|
|
assert(rb.source == [1,2]);
|
|
assert(&ra.source[0] == &dest[0]);
|
|
assert(&rb.source[0] == &dest[2]);
|
|
assert(dest == [1,2,1,2]);
|
|
return dest;
|
|
}
|
|
|
|
auto testWrap12602c()
|
|
{
|
|
uint[] dest = [1, 2, 3, 4];
|
|
|
|
auto ra = Result12602(dest[0 .. 2]);
|
|
auto rb = Result12602(dest[2 .. 4]);
|
|
|
|
foreach (i; 0 .. 2)
|
|
rb.source[i] = ra.source[i];
|
|
|
|
assert(ra.source == [1,2]);
|
|
assert(rb.source == [1,2]);
|
|
assert(&ra.source[0] == &dest[0]);
|
|
assert(&rb.source[0] == &dest[2]);
|
|
assert(dest == [1,2,1,2]);
|
|
return dest;
|
|
}
|
|
|
|
auto testWrap12602d()
|
|
{
|
|
uint[] dest = [1, 2, 3, 4];
|
|
|
|
Result12602 ra; ra.source = dest[0 .. 2];
|
|
Result12602 rb; rb.source = dest[2 .. 4];
|
|
|
|
foreach (i; 0 .. 2)
|
|
rb.source[i] = ra.source[i];
|
|
|
|
assert(ra.source == [1,2]);
|
|
assert(rb.source == [1,2]);
|
|
assert(&ra.source[0] == &dest[0]);
|
|
assert(&rb.source[0] == &dest[2]);
|
|
assert(dest == [1,2,1,2]);
|
|
return dest;
|
|
}
|
|
|
|
static assert(testWrap12602a() == [1,2,1,2]);
|
|
static assert(testWrap12602b() == [1,2,1,2]);
|
|
static assert(testWrap12602c() == [1,2,1,2]);
|
|
static assert(testWrap12602d() == [1,2,1,2]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12677
|
|
// class type initializing from DotVarExp
|
|
|
|
final class C12677
|
|
{
|
|
TypeTuple!(Object, int[]) _test;
|
|
this()
|
|
{
|
|
auto t0 = _test[0]; //
|
|
auto t1 = _test[1]; //
|
|
assert(t0 is null);
|
|
assert(t1 is null);
|
|
}
|
|
}
|
|
|
|
struct S12677
|
|
{
|
|
auto f = new C12677();
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12851
|
|
// interpret function local const static array
|
|
|
|
void test12851()
|
|
{
|
|
const int[5] arr;
|
|
alias staticZip = TypeTuple!(arr[0]);
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13630
|
|
// indexing and setting array element via pointer
|
|
|
|
struct S13630(T)
|
|
{
|
|
T[3] arr;
|
|
|
|
this(A...)(const auto ref A args)
|
|
{
|
|
auto p = arr.ptr;
|
|
|
|
foreach (ref v; args)
|
|
{
|
|
*p = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
enum s13630 = S13630!float(1);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13827
|
|
|
|
struct Matrix13827(T, uint N)
|
|
{
|
|
private static defaultMatrix()
|
|
{
|
|
T[N] arr;
|
|
return arr;
|
|
}
|
|
|
|
union
|
|
{
|
|
T[N] A = defaultMatrix;
|
|
T[N] flat;
|
|
}
|
|
|
|
this(A...)(const auto ref A args)
|
|
{
|
|
uint k;
|
|
|
|
foreach (ref v; args)
|
|
flat[k++] = cast(T)v;
|
|
}
|
|
}
|
|
enum m13827 = Matrix13827!(int, 3)(1, 2, 3);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13847
|
|
// support DotTypeExp
|
|
|
|
class B13847
|
|
{
|
|
int foo() { return 1; }
|
|
}
|
|
|
|
class C13847 : B13847
|
|
{
|
|
override int foo() { return 2; }
|
|
|
|
final void test(int n)
|
|
{
|
|
assert(foo() == n);
|
|
assert(B13847.foo() == 1);
|
|
assert(C13847.foo() == 2);
|
|
assert(this.B13847.foo() == 1);
|
|
assert(this.C13847.foo() == 2);
|
|
}
|
|
}
|
|
|
|
class D13847 : C13847
|
|
{
|
|
override int foo() { return 3; }
|
|
}
|
|
|
|
static assert({
|
|
C13847 c = new C13847();
|
|
c.test(2);
|
|
assert(c.B13847.foo() == 1);
|
|
assert(c.C13847.foo() == 2);
|
|
|
|
D13847 d = new D13847();
|
|
d.test(3);
|
|
assert(d.B13847.foo() == 1);
|
|
assert(d.C13847.foo() == 2);
|
|
assert(d.D13847.foo() == 3);
|
|
|
|
c = d;
|
|
c.test(3);
|
|
assert(c.B13847.foo() == 1);
|
|
assert(c.C13847.foo() == 2);
|
|
return true;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12495
|
|
// cast from string to immutable(ubyte)[]
|
|
|
|
string getStr12495()
|
|
{
|
|
char[1] buf = void; // dummy starting point.
|
|
string s = cast(string)buf[0..0]; // empty slice, .ptr points mutable.
|
|
assert(buf.ptr == s.ptr);
|
|
s ~= 'a'; // this should allocate.
|
|
assert(buf.ptr != s.ptr);
|
|
return s.idup; // this should allocate again, and
|
|
// definitely point immutable memory.
|
|
}
|
|
auto indexOf12495(string s)
|
|
{
|
|
auto p1 = s.ptr;
|
|
auto p2 = (cast(immutable(ubyte)[])s).ptr;
|
|
assert(cast(void*)p1 == cast(void*)p2); // OK <- fails
|
|
return cast(void*)p2 - cast(void*)p1; // OK <- "cannot subtract pointers ..."
|
|
}
|
|
static assert(indexOf12495(getStr12495()) == 0);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13992
|
|
// Repainting pointer arithmetic result
|
|
|
|
enum hash13992 = hashOf13992("abcd".ptr);
|
|
|
|
@trusted hashOf13992(const void* buf)
|
|
{
|
|
auto data = cast(const(ubyte)*) buf;
|
|
size_t hash;
|
|
data += 2; // problematic pointer arithmetic
|
|
hash += *data; // CTFE internal issue was shown by the dereference
|
|
return hash;
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13739
|
|
// Precise copy for ArrayLiteralExp elements
|
|
|
|
static assert(
|
|
{
|
|
int[] a1 = [13];
|
|
int[][] a2 = [a1];
|
|
assert(a2[0] is a1); // OK
|
|
assert(a2[0].ptr is a1.ptr); // OK <- NG
|
|
|
|
a1[0] = 1;
|
|
assert(a2[0][0] == 1); // OK <- NG
|
|
|
|
a2[0][0] = 2;
|
|
assert(a1[0] == 2); // OK <- NG
|
|
|
|
return 1;
|
|
}());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14463
|
|
// ICE on slice assignment without postblit
|
|
|
|
struct Boo14463
|
|
{
|
|
private int[1] c;
|
|
this(int[] x)
|
|
{
|
|
c = x;
|
|
}
|
|
}
|
|
immutable Boo14463 a14463 = Boo14463([1]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=13295
|
|
// Don't copy struct literal in VarExp::interpret()
|
|
|
|
struct S13295
|
|
{
|
|
int n;
|
|
}
|
|
|
|
void f13295(ref const S13295 s)
|
|
{
|
|
*cast(int*) &s.n = 1;
|
|
assert(s.n == 1); // OK <- fail
|
|
}
|
|
|
|
static assert(
|
|
{
|
|
S13295 s;
|
|
f13295(s);
|
|
return s.n == 1; // true <- false
|
|
}());
|
|
|
|
int foo14061(int[] a)
|
|
{
|
|
foreach (immutable x; a)
|
|
{
|
|
auto b = a ~ x;
|
|
return b == [1, 1];
|
|
}
|
|
return 0;
|
|
}
|
|
static assert(foo14061([1]));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14024
|
|
// CTFE version
|
|
|
|
bool test14024()
|
|
{
|
|
string op;
|
|
|
|
struct S
|
|
{
|
|
char x = 'x';
|
|
this(this) { op ~= x-0x20; } // upper case
|
|
~this() { op ~= x; } // lower case
|
|
}
|
|
|
|
S[4] mem;
|
|
ref S[2] slice(int a, int b) { return mem[a .. b][0 .. 2]; }
|
|
|
|
op = null;
|
|
mem[0].x = 'a';
|
|
mem[1].x = 'b';
|
|
mem[2].x = 'x';
|
|
mem[3].x = 'y';
|
|
slice(0, 2) = slice(2, 4); // [ab] = [xy]
|
|
assert(op == "XaYb", op);
|
|
|
|
op = null;
|
|
mem[0].x = 'x';
|
|
mem[1].x = 'y';
|
|
mem[2].x = 'a';
|
|
mem[3].x = 'b';
|
|
slice(2, 4) = slice(0, 2); // [ab] = [xy]
|
|
assert(op == "XaYb", op);
|
|
|
|
op = null;
|
|
mem[0].x = 'a';
|
|
mem[1].x = 'b';
|
|
mem[2].x = 'c';
|
|
slice(0, 2) = slice(1, 3); // [ab] = [bc]
|
|
assert(op == "BaCb", op);
|
|
|
|
op = null;
|
|
mem[0].x = 'x';
|
|
mem[1].x = 'y';
|
|
mem[2].x = 'z';
|
|
slice(1, 3) = slice(0, 2); // [yz] = [xy]
|
|
assert(op == "YzXy", op);
|
|
|
|
return true;
|
|
}
|
|
static assert(test14024());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14304
|
|
// cache of static immutable value
|
|
|
|
immutable struct Bug14304
|
|
{
|
|
string s_name;
|
|
alias s_name this;
|
|
|
|
string fun()()
|
|
{
|
|
return "fun";
|
|
}
|
|
}
|
|
class Buggy14304
|
|
{
|
|
static string fun(string str)()
|
|
{
|
|
return str;
|
|
}
|
|
static immutable val = immutable Bug14304("val");
|
|
}
|
|
void test14304()
|
|
{
|
|
enum kt = Buggy14304.fun!(Buggy14304.val);
|
|
static assert(kt == "val");
|
|
enum bt = Buggy14304.val.fun();
|
|
static assert(bt == "fun");
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14371
|
|
// evaluate BinAssignExp as lvalue
|
|
|
|
int test14371()
|
|
{
|
|
int x;
|
|
++(x += 1);
|
|
return x;
|
|
}
|
|
static assert(test14371() == 2);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7151
|
|
// [CTFE] cannot compare classes with ==
|
|
|
|
bool test7151()
|
|
{
|
|
auto a = new Object;
|
|
return a == a && a != new Object;
|
|
}
|
|
static assert(test7151());
|
|
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12603
|
|
// [CTFE] goto does not correctly call dtors
|
|
|
|
struct S12603
|
|
{
|
|
this(uint* dtorCalled)
|
|
{
|
|
*dtorCalled = 0;
|
|
this.dtorCalled = dtorCalled;
|
|
}
|
|
|
|
@disable this();
|
|
|
|
~this()
|
|
{
|
|
++*dtorCalled;
|
|
}
|
|
|
|
uint* dtorCalled;
|
|
}
|
|
|
|
|
|
auto numDtorCallsByGotoWithinScope()
|
|
{
|
|
uint dtorCalled;
|
|
{
|
|
S12603 s = S12603(&dtorCalled);
|
|
assert(dtorCalled == 0);
|
|
goto L_abc;
|
|
L_abc:
|
|
assert(dtorCalled == 0);
|
|
}
|
|
assert(dtorCalled == 1);
|
|
return dtorCalled;
|
|
}
|
|
static assert(numDtorCallsByGotoWithinScope() == 1);
|
|
|
|
|
|
auto numDtorCallsByGotoOutOfScope()
|
|
{
|
|
uint dtorCalled;
|
|
{
|
|
S12603 s = S12603(&dtorCalled);
|
|
assert(dtorCalled == 0);
|
|
goto L_abc;
|
|
}
|
|
L_abc:
|
|
assert(dtorCalled == 1);
|
|
return dtorCalled;
|
|
}
|
|
static assert(numDtorCallsByGotoOutOfScope() == 1);
|
|
|
|
|
|
uint numDtorCallsByGotoDifferentScopeAfter()
|
|
{
|
|
uint dtorCalled;
|
|
{
|
|
S12603 s = S12603(&dtorCalled);
|
|
assert(dtorCalled == 0);
|
|
}
|
|
assert(dtorCalled == 1);
|
|
goto L_abc;
|
|
L_abc:
|
|
assert(dtorCalled == 1);
|
|
return dtorCalled;
|
|
}
|
|
static assert(numDtorCallsByGotoDifferentScopeAfter() == 1);
|
|
|
|
|
|
auto numDtorCallsByGotoDifferentScopeBefore()
|
|
{
|
|
uint dtorCalled;
|
|
assert(dtorCalled == 0);
|
|
goto L_abc;
|
|
L_abc:
|
|
assert(dtorCalled == 0);
|
|
{
|
|
S12603 s = S12603(&dtorCalled);
|
|
assert(dtorCalled == 0);
|
|
}
|
|
assert(dtorCalled == 1);
|
|
return dtorCalled;
|
|
}
|
|
static assert(numDtorCallsByGotoDifferentScopeBefore() == 1);
|
|
|
|
|
|
struct S12603_2
|
|
{
|
|
~this()
|
|
{
|
|
dtorCalled = true;
|
|
}
|
|
|
|
bool dtorCalled = false;
|
|
}
|
|
|
|
auto structInCaseScope()
|
|
{
|
|
auto charsets = S12603_2();
|
|
switch(1)
|
|
{
|
|
case 0:
|
|
auto set = charsets;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return charsets.dtorCalled;
|
|
}
|
|
|
|
static assert(!structInCaseScope());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=15233
|
|
// ICE in TupleExp, Copy On Write bug
|
|
|
|
alias TT15233(stuff ...) = stuff;
|
|
|
|
struct Tok15233 {}
|
|
enum tup15233 = TT15233!(Tok15233(), "foo");
|
|
static assert(tup15233[0] == Tok15233());
|
|
static assert(tup15233[1] == "foo");
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=15251
|
|
// void cast in ForStatement.increment
|
|
|
|
int test15251()
|
|
{
|
|
for (ubyte lwr = 19;
|
|
lwr != 20;
|
|
cast(void)++lwr) // have to to be evaluated with CTFEGoal.Nothing
|
|
{}
|
|
return 1;
|
|
}
|
|
static assert(test15251());
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=15998
|
|
// Sagfault caused by memory corruption
|
|
|
|
immutable string[2] foo15998 = ["",""];
|
|
immutable string[2][] bar15998a = foo15998 ~ baz15998;
|
|
immutable string[2][] bar15998b = baz15998 ~ foo15998;
|
|
|
|
auto baz15998()
|
|
{
|
|
immutable(string[2])[] r;
|
|
return r;
|
|
}
|
|
|
|
static assert(bar15998a == [["", ""]]);
|
|
static assert(bar15998b == [["", ""]]);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=16094
|
|
// Non-overlapped slice assignment on an aggregate
|
|
|
|
char[] f16094a()
|
|
{
|
|
char[] x = new char[](6);
|
|
x[3..6] = x[0..3];
|
|
return x;
|
|
}
|
|
|
|
int[] f16094b()
|
|
{
|
|
int[] x = new int[](6);
|
|
x[3..6] = x[0..3];
|
|
return x;
|
|
}
|
|
|
|
enum copy16094a = f16094a();
|
|
enum copy16094b = f16094b();
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=17407
|
|
|
|
bool foo17407()
|
|
{
|
|
void delegate ( ) longest_convert;
|
|
return __traits(compiles, longest_convert = &doesNotExists);
|
|
}
|
|
|
|
static assert(!foo17407);
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=18057
|
|
// Recursive field initializer causes segfault.
|
|
|
|
struct RBNode(T)
|
|
{
|
|
RBNode!T *copy = new RBNode!T;
|
|
}
|
|
|
|
static assert(!__traits(compiles, { alias bug18057 = RBNode!int; }));
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=19140
|
|
|
|
void test19140()
|
|
{
|
|
real f19140();
|
|
static if (__traits(compiles, (){ enum real r = f19140(); })) {}
|
|
}
|
|
|
|
/**************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=19074
|
|
|
|
struct S19074a { }
|
|
|
|
struct S19074b
|
|
{
|
|
S19074a field;
|
|
this(S19074a) { }
|
|
|
|
static const S19074b* data = new S19074b(S19074a());
|
|
}
|
|
|
|
void test19074()
|
|
{
|
|
auto var = S19074b.data;
|
|
}
|
|
|
|
/************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=19447
|
|
|
|
bool f19447()
|
|
{
|
|
int[3] c=1;
|
|
assert(c[0]==1);
|
|
g19447(c[0..2]);
|
|
assert(c[0]!=1); //fails
|
|
assert(c[0]==2);
|
|
return true;
|
|
}
|
|
void g19447(ref int[2] a)
|
|
{
|
|
int[2] b=2;
|
|
a=b;
|
|
//a[]=b; // works
|
|
//a[] = b[]; // works
|
|
assert(a[0]==2);
|
|
}
|
|
static assert(f19447());
|
|
|
|
/***/
|
|
|
|
char[] mangle19447(char[] dst)
|
|
{
|
|
dst.length = 10;
|
|
size_t i = "_D".length;
|
|
dst[0 .. i] = "_D";
|
|
return dst;
|
|
}
|
|
|
|
static char[] x19447 = mangle19447(null);
|
|
|
|
/***/
|
|
enum KindEnum
|
|
{
|
|
integer,
|
|
arrayOf
|
|
}
|
|
|
|
struct FullKind
|
|
{
|
|
KindEnum[] contents;
|
|
|
|
this(KindEnum ) { opAssign; }
|
|
|
|
this(KindEnum , FullKind contentKind)
|
|
{
|
|
contents = contentKind.contents;
|
|
}
|
|
|
|
void opAssign()
|
|
{
|
|
contents = [];
|
|
}
|
|
}
|
|
|
|
enum fk = FullKind(KindEnum.integer);
|
|
enum fk2 = FullKind(KindEnum.arrayOf, fk);
|
|
|
|
/************************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9937
|
|
|
|
int test9937()
|
|
{
|
|
import core.math;
|
|
|
|
float x = float.max;
|
|
x *= 2;
|
|
x = toPrec!float(x);
|
|
x /= 2;
|
|
assert(x == float.infinity);
|
|
return 1;
|
|
}
|
|
|
|
static assert(test9937());
|
|
|
|
/************************************************/
|
|
// static array .tupleof
|
|
|
|
struct SArrayTupleEquiv(T)
|
|
{
|
|
T f1;
|
|
T f2;
|
|
}
|
|
|
|
// basic .tupleof invariants
|
|
bool testSArrayTupleA()
|
|
{
|
|
int[2] xs;
|
|
assert(xs.tupleof == TypeTuple!(0, 0));
|
|
assert(xs.tupleof == (cast(int[2])[0, 0]).tupleof);
|
|
|
|
xs.tupleof = TypeTuple!(1, 2);
|
|
assert(xs.tupleof == TypeTuple!(1, 2));
|
|
|
|
auto ys = SArrayTupleEquiv!int(1, 2);
|
|
assert(xs.tupleof == ys.tupleof);
|
|
|
|
return true;
|
|
}
|
|
static assert(testSArrayTupleA());
|
|
|
|
// tuples with side effects
|
|
bool testSArrayTupleB()
|
|
{
|
|
// Counter records lifetime events in copies/dtors, as a cheap way to check that .tupleof for
|
|
// static arrays exhibit all the same side effects as an equivalent struct's .tupleof
|
|
int[int] copies;
|
|
int[int] dtors;
|
|
struct Counter
|
|
{
|
|
int id = -1;
|
|
|
|
this(this)
|
|
{
|
|
copies[id] = copies.get(id, 0) + 1;
|
|
}
|
|
|
|
~this()
|
|
{
|
|
dtors[id] = dtors.get(id, 0) + 1;
|
|
}
|
|
}
|
|
|
|
void consume(Counter, Counter) {}
|
|
Counter[2] produce(int id1, int id2)
|
|
{
|
|
return [Counter(id1), Counter(id2)];
|
|
}
|
|
|
|
// first sample expected behavior from struct .tupleof
|
|
// braces create a subscope, shortening lifetimes
|
|
{
|
|
auto a = SArrayTupleEquiv!Counter(Counter(0), Counter(1));
|
|
|
|
typeof(a) b;
|
|
b.tupleof = a.tupleof;
|
|
|
|
Counter x, y;
|
|
TypeTuple!(x, y) = a.tupleof;
|
|
|
|
a.tupleof[0] = Counter(2);
|
|
a.tupleof[1] = Counter(3);
|
|
consume(a.tupleof);
|
|
|
|
a.tupleof = produce(4, 5).tupleof;
|
|
}
|
|
int[int][2] expected = [copies.dup, dtors.dup];
|
|
copies = null; // .clear is not CTFE friendly
|
|
dtors = null;
|
|
|
|
// the real test -- sample behavior of array .tupleof
|
|
{
|
|
Counter[2] a = [Counter(0), Counter(1)];
|
|
|
|
typeof(a) b;
|
|
b.tupleof = a.tupleof;
|
|
|
|
Counter x, y;
|
|
TypeTuple!(x, y) = a.tupleof;
|
|
|
|
a.tupleof[0] = Counter(2);
|
|
a.tupleof[1] = Counter(3);
|
|
consume(a.tupleof);
|
|
|
|
a.tupleof = produce(4, 5).tupleof;
|
|
}
|
|
assert(expected[0] == copies);
|
|
assert(expected[1] == dtors);
|
|
|
|
return true;
|
|
}
|
|
static assert(testSArrayTupleB());
|