4 changes: 2 additions & 2 deletions src/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -3736,11 +3736,11 @@ Statement *ReturnStatement::semantic(Scope *sc)
}
if (checkNonAssignmentArrayOp(exp))
exp = new ErrorExp();
if (exp->op == TOKcall)
exp = valueNoDtor(exp);

// Extract side-effect part
exp = Expression::extractLast(exp, &e0);
if (exp->op == TOKcall)
exp = valueNoDtor(exp);

/* Void-return function can have void typed expression
* on return statement.
Expand Down
2 changes: 2 additions & 0 deletions src/win32.mak
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ MAKEFILES=win32.mak posix.mak osmodel.mak

defaulttarget: debdmd

auto-tester-build: dmd

dmd: reldmd

release:
Expand Down
41 changes: 41 additions & 0 deletions test/compilable/interpret3.d
Original file line number Diff line number Diff line change
Expand Up @@ -4695,6 +4695,47 @@ int bug10198()
}
static assert(bug10198());

/**************************************************
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
****************************************************/
Expand Down
13 changes: 13 additions & 0 deletions test/fail_compilation/ice14424.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// REQUIRED_ARGS: -o- -unittest
/*
TEST_OUTPUT:
---
fail_compilation/ice14424.d(12): Error: tuple has no effect in expression (tuple(__unittestL3_1))
---
*/

void main()
{
import imports.a14424;
__traits(getUnitTests, imports.a14424);
}
3 changes: 3 additions & 0 deletions test/fail_compilation/imports/a14424.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module imports.a14424;

unittest { }
20 changes: 10 additions & 10 deletions test/fail_compilation/parseStc3.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
fail_compilation/parseStc3.d(10): Error: redundant attribute 'pure'
fail_compilation/parseStc3.d(11): Error: redundant attribute 'nothrow'
fail_compilation/parseStc3.d(12): Error: redundant attribute '@nogc'
fail_compilation/parseStc3.d(13): Error: redundant attribute '@property'
fail_compilation/parseStc3.d(10): Deprecation: redundant attribute 'pure'
fail_compilation/parseStc3.d(11): Deprecation: redundant attribute 'nothrow'
fail_compilation/parseStc3.d(12): Deprecation: redundant attribute '@nogc'
fail_compilation/parseStc3.d(13): Deprecation: redundant attribute '@property'
---
*/
pure void f1() pure {}
Expand All @@ -16,9 +16,9 @@ nothrow void f2() nothrow {}
/*
TEST_OUTPUT:
---
fail_compilation/parseStc3.d(24): Error: redundant attribute '@safe'
fail_compilation/parseStc3.d(25): Error: redundant attribute '@system'
fail_compilation/parseStc3.d(26): Error: redundant attribute '@trusted'
fail_compilation/parseStc3.d(24): Deprecation: redundant attribute '@safe'
fail_compilation/parseStc3.d(25): Deprecation: redundant attribute '@system'
fail_compilation/parseStc3.d(26): Deprecation: redundant attribute '@trusted'
---
*/
@safe void f6() @safe {}
Expand Down Expand Up @@ -49,11 +49,11 @@ TEST_OUTPUT:
fail_compilation/parseStc3.d(59): Error: conflicting attribute '@system'
fail_compilation/parseStc3.d(59): Error: conflicting attribute '@trusted'
fail_compilation/parseStc3.d(60): Error: conflicting attribute '@system'
fail_compilation/parseStc3.d(60): Error: redundant attribute '@system'
fail_compilation/parseStc3.d(60): Deprecation: redundant attribute '@system'
fail_compilation/parseStc3.d(61): Error: conflicting attribute '@safe'
fail_compilation/parseStc3.d(61): Error: redundant attribute '@system'
fail_compilation/parseStc3.d(61): Deprecation: redundant attribute '@system'
fail_compilation/parseStc3.d(62): Error: conflicting attribute '@safe'
fail_compilation/parseStc3.d(62): Error: redundant attribute '@trusted'
fail_compilation/parseStc3.d(62): Deprecation: redundant attribute '@trusted'
---
*/
@safe @system void f15() @trusted {}
Expand Down
20 changes: 10 additions & 10 deletions test/fail_compilation/parseStc4.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
/*
TEST_OUTPUT:
---
fail_compilation/parseStc4.d(14): Error: redundant attribute 'pure'
fail_compilation/parseStc4.d(14): Error: redundant attribute 'nothrow'
fail_compilation/parseStc4.d(14): Deprecation: redundant attribute 'pure'
fail_compilation/parseStc4.d(14): Deprecation: redundant attribute 'nothrow'
fail_compilation/parseStc4.d(14): Error: conflicting attribute '@system'
fail_compilation/parseStc4.d(14): Error: redundant attribute '@nogc'
fail_compilation/parseStc4.d(14): Error: redundant attribute '@property'
fail_compilation/parseStc4.d(14): Deprecation: redundant attribute '@nogc'
fail_compilation/parseStc4.d(14): Deprecation: redundant attribute '@property'
---
*/
pure nothrow @safe @nogc @property
Expand All @@ -19,12 +19,12 @@ pure nothrow @system @nogc @property
/*
TEST_OUTPUT:
---
fail_compilation/parseStc4.d(34): Error: redundant attribute 'const'
fail_compilation/parseStc4.d(35): Error: redundant attribute 'const'
fail_compilation/parseStc4.d(36): Error: redundant attribute 'const'
fail_compilation/parseStc4.d(38): Error: redundant attribute 'pure'
fail_compilation/parseStc4.d(39): Error: redundant attribute '@safe'
fail_compilation/parseStc4.d(40): Error: redundant attribute 'nothrow'
fail_compilation/parseStc4.d(34): Deprecation: redundant attribute 'const'
fail_compilation/parseStc4.d(35): Deprecation: redundant attribute 'const'
fail_compilation/parseStc4.d(36): Deprecation: redundant attribute 'const'
fail_compilation/parseStc4.d(38): Deprecation: redundant attribute 'pure'
fail_compilation/parseStc4.d(39): Deprecation: redundant attribute '@safe'
fail_compilation/parseStc4.d(40): Deprecation: redundant attribute 'nothrow'
fail_compilation/parseStc4.d(41): Error: conflicting attribute '@trusted'
---
*/
Expand Down
37 changes: 37 additions & 0 deletions test/runnable/mars1.d
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,42 @@ int test13969(const S13969* f) {
return 0 % ((f.y > 0) ? f.x / f.y : f.x / -f.y);
}

////////////////////////////////////////////////////////////////////////

void test14220()
{
auto a = toString(14);

printf("a.ptr = %p, a.length = %d\n", a.ptr, cast(int)a.length);
return;
}

auto toString(int value)
{
uint mValue = value;

char[int.sizeof * 3] buffer = void;
size_t index = buffer.length;

do
{
uint div = cast(int)(mValue / 10);
char mod = mValue % 10 + '0';
buffer[--index] = mod; // Line 22
mValue = div;
} while (mValue);

//printf("buffer.ptr = %p, index = %d\n", buffer.ptr, cast(int)index);
return dup(buffer[index .. $]);
}

char[] dup(char[] a)
{
//printf("a.ptr = %p, a.length = %d\n", a.ptr, cast(int)a.length);
a[0] = 1; // segfault
return a;
}

////////////////////////////////////////////////////////////////////////

int main()
Expand Down Expand Up @@ -1320,6 +1356,7 @@ int main()
test9449();
test12057();
test13784();
test14220();
printf("Success\n");
return 0;
}
31 changes: 31 additions & 0 deletions test/runnable/opover.d
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,37 @@ void test12778()
}
}

/**************************************/
// 14344

struct S14344
{
S14344 opBinary(string op)(S14344 v)
{
static assert(0);
}
S14344 opAssign()(S14344 v)
{
static assert(0);
}
}

struct S14344Mix
{
S14344 s;
alias s this;
}

class C14344
{
S14344Mix height() { return S14344Mix(); }

void update()
{
S14344 height = this.height;
}
}

/**************************************/

int main()
Expand Down
41 changes: 41 additions & 0 deletions test/runnable/sctor.d
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,47 @@ void test13515()
assert(s.aa[5]["foo"] is null);
}

/***************************************************/
// 14409

class B14409 { this(int) {} }
class C14409 : B14409
{
this(int n)
{
if (true)
super(n);
else
assert(0);
}
}

/***************************************************/
// 14376

auto map14376()
{
return MapResult14376!(e => 0)();
}

struct MapResult14376(alias pred)
{
@property int front() { return pred(0); }
}

struct S14376
{
typeof(map14376()) x;

this(int dummy)
{
if (true)
this.x = map14376();
else
assert(0);
}
}

/***************************************************/

int main()
Expand Down
145 changes: 145 additions & 0 deletions test/runnable/sdtor.d
Original file line number Diff line number Diff line change
Expand Up @@ -3449,6 +3449,150 @@ void test13586()
}
}

/**********************************/
// 14443

T enforce14443(E : Throwable = Exception, T)(T value)
{
if (!value)
throw new E("Enforcement failed");
return value;
}

struct RefCounted14443(T)
if (!is(T == class) && !(is(T == interface)))
{
struct RefCountedStore
{
private struct Impl
{
T _payload;
size_t _count;
}

private Impl* _store;

private void initialize(A...)(auto ref A args)
{
import core.stdc.stdlib : malloc;

// enforce is necessary
_store = cast(Impl*) enforce14443(malloc(Impl.sizeof));

// emulate 'emplace'
static if (args.length > 0)
_store._payload.tupleof = args;
else
_store._payload = T.init;

_store._count = 1;
}

@property bool isInitialized() const nothrow @safe
{
return _store !is null;
}

void ensureInitialized()
{
if (!isInitialized) initialize();
}

}
RefCountedStore _refCounted;

this(A...)(auto ref A args) if (A.length > 0)
{
_refCounted.initialize(args);
}

this(this)
{
if (!_refCounted.isInitialized)
return;
++_refCounted._store._count;
//printf("RefCounted count = %d (inc)\n", _refCounted._store._count);
}

~this()
{
if (!_refCounted.isInitialized)
return;
assert(_refCounted._store._count > 0);
if (--_refCounted._store._count)
{
//printf("RefCounted count = %u\n", _refCounted._store._count);
return;
}

import core.stdc.stdlib : free;
free(_refCounted._store);
_refCounted._store = null;
}

void opAssign(typeof(this) rhs) { assert(0); }
void opAssign(T rhs) { assert(0); }

@property ref T refCountedPayload()
{
_refCounted.ensureInitialized();
return _refCounted._store._payload;
}

alias refCountedPayload this;
}

struct Path14443
{
struct Payload
{
int p;
}
RefCounted14443!Payload data;
}

struct PathRange14443
{
Path14443 path;
size_t i;

@property PathElement14443 front()
{
return PathElement14443(this, path.data.p);
}
}

struct PathElement14443
{
PathRange14443 range;

this(PathRange14443 range, int)
{
this.range = range;
}
}

void test14443()
{
auto path = Path14443(RefCounted14443!(Path14443.Payload)(12));
assert(path.data.p == 12);

@property refCount() { return path.data._refCounted._store._count; }
assert(refCount == 1);

{
auto _r = PathRange14443(path);
assert(refCount == 2);
// foreach
{
auto element = _r.front;
assert(refCount == 3); // fail with 2.067
}
assert(refCount == 2);
}
assert(refCount == 1);
}

/**********************************/
// 13661, 14022, 14023 - postblit/dtor call on static array assignment

Expand Down Expand Up @@ -3809,6 +3953,7 @@ int main()
test13303();
test13673();
test13586();
test14443();
test13661();
test13661a();
test14022();
Expand Down
19 changes: 19 additions & 0 deletions test/runnable/variadic.d
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,24 @@ void test13508() @safe @nogc
S13508 s = make13508!S13508(5);
}

/***************************************/
// 14395

int v2u14395(uint[1] ar...)
{
return ar[0];
}

void print14395(int size = v2u14395(7))
{
assert(size == 7);
}

void test14395()
{
print14395();
}

/***************************************/
// 10414

Expand Down Expand Up @@ -1787,6 +1805,7 @@ int main()
test7233();
test7263();
test9017();
test14395();
test10414();
test9495();
testCopy();
Expand Down