blob: 2c9a84eddfb804ac7185e52a3b8798458bb91871 [file] [log] [blame]
// PERMUTE_ARGS: -inline
/*
TEST_OUTPUT:
---
compilable/interpret3.d(6350): 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(("" ~ "\&copy;"[0]).length == 1);
const char[] null5722 = null;
static assert((null5722 ~ "\&copy;"[0]).length == 1);
static assert(("\&copy;"[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;
}
bool 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(