Showing with 281 additions and 41 deletions.
  1. +3 −1 src/backend/cgelem.c
  2. +2 −2 src/backend/cod1.c
  3. +5 −1 src/eh.c
  4. +63 −26 src/expression.c
  5. +10 −3 src/interpret.c
  6. +1 −1 src/mtype.c
  7. +2 −1 src/posix.mak
  8. +5 −1 src/struct.c
  9. +8 −3 src/todt.c
  10. +18 −0 test/fail_compilation/ctfe14731.d
  11. +120 −0 test/runnable/test42.d
  12. +14 −0 test/runnable/testdt.d
  13. +30 −2 test/runnable/xtest46.d
4 changes: 3 additions & 1 deletion src/backend/cgelem.c
Original file line number Diff line number Diff line change
Expand Up @@ -5364,7 +5364,9 @@ STATIC elem * optelem(elem *e, goal_t goal)
return optelem(e,GOALnone);
}

e1 = e->E1 = optelem(e->E1,(op == OPbool || op == OPnot) ? GOALflags : GOALvalue);
e1 = e->E1 = optelem(e->E1, (op == OPddtor) ? GOALnone : (op == OPbool || op == OPnot) ? GOALflags : GOALvalue);
if (!e1)
goto retnull;
if (e1->Eoper == OPconst)
{
#if TARGET_SEGMENTED
Expand Down
4 changes: 2 additions & 2 deletions src/backend/cod1.c
Original file line number Diff line number Diff line change
Expand Up @@ -4263,8 +4263,8 @@ code *loaddata(elem *e,regm_t *pretregs)
}
else if (I64 && sz == 16)
{
ce = movregconst(CNIL,findreglsw(forregs),e->EV.Vcent.lsw,0);
ce = movregconst(ce,findregmsw(forregs),e->EV.Vcent.msw,0);
ce = movregconst(CNIL,findreglsw(forregs),e->EV.Vcent.lsw,64);
ce = movregconst(ce,findregmsw(forregs),e->EV.Vcent.msw,64);
}
else
assert(0);
Expand Down
6 changes: 5 additions & 1 deletion src/eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,10 @@ void except_fillInEHTable(symbol *s)
unsigned foffset;
for (; 1; c2 = code_next(c2))
{
assert(c2);
// Bugzilla 13720: optimizer might elide the corresponding ddtor
if (!c2)
goto Lnodtor;

if (c2->Iop == (ESCAPE | ESCddtor))
{
if (n)
Expand Down Expand Up @@ -337,6 +340,7 @@ void except_fillInEHTable(symbol *s)
stacki--;
assert(stacki != 0);
}
Lnodtor:
boffset += calccodsize(c);
}
}
Expand Down
89 changes: 63 additions & 26 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -12408,52 +12408,89 @@ Expression *CatExp::semantic(Scope *sc)
Type *tb1next = tb1->nextOf();
Type *tb2next = tb2->nextOf();

// Check for: array ~ array
if (tb1next && tb2next &&
(tb1next->implicitConvTo(tb2next) >= MATCHconst ||
tb2next->implicitConvTo(tb1next) >= MATCHconst)
tb2next->implicitConvTo(tb1next) >= MATCHconst ||
e1->op == TOKarrayliteral && e1->implicitConvTo(tb2) ||
e2->op == TOKarrayliteral && e2->implicitConvTo(tb1)
)
)
{
/* Here to avoid the case of:
/* Bugzilla 9248: Here to avoid the case of:
* void*[] a = [cast(void*)1];
* void*[] b = [cast(void*)2];
* a ~ b;
* becoming:
* a ~ [cast(void*)b];
*/

/* Bugzilla 14682: Also to avoid the case of:
* int[][] a;
* a ~ [];
* becoming:
* a ~ cast(int[])[];
*/
goto Lpeer;
}
else if ((tb1->ty == Tsarray || tb1->ty == Tarray) &&
e2->implicitConvTo(tb1next) >= MATCHconvert &&
tb2->ty != Tvoid)

// Check for: array ~ element
if ((tb1->ty == Tsarray || tb1->ty == Tarray) && tb2->ty != Tvoid)
{
if (e2->checkPostblit(sc, tb2))
return new ErrorExp();
e2 = e2->implicitCastTo(sc, tb1next);
type = tb1next->arrayOf();
if (tb2->ty == Tarray || tb2->ty == Tsarray)
if (e1->op == TOKarrayliteral && e1->implicitConvTo(tb2->arrayOf()))
{
// Make e2 into [e2]
e2 = new ArrayLiteralExp(e2->loc, e2);
e2->type = type;
if (e2->checkPostblit(sc, tb2))
return new ErrorExp();
e1 = e1->implicitCastTo(sc, tb2->arrayOf());
type = tb2->arrayOf();
goto L2elem;
}
if (e2->implicitConvTo(tb1next) >= MATCHconvert)
{
if (e2->checkPostblit(sc, tb2))
return new ErrorExp();
e2 = e2->implicitCastTo(sc, tb1next);
type = tb1next->arrayOf();
L2elem:
if (tb2->ty == Tarray || tb2->ty == Tsarray)
{
// Make e2 into [e2]
e2 = new ArrayLiteralExp(e2->loc, e2);
e2->type = type;
}
return this;
}
return this;
}
else if ((tb2->ty == Tsarray || tb2->ty == Tarray) &&
e1->implicitConvTo(tb2next) >= MATCHconvert &&
tb1->ty != Tvoid)
// Check for: element ~ array
if ((tb2->ty == Tsarray || tb2->ty == Tarray) && tb1->ty != Tvoid)
{
if (e1->checkPostblit(sc, tb1))
return new ErrorExp();
e1 = e1->implicitCastTo(sc, tb2next);
type = tb2next->arrayOf();
if (tb1->ty == Tarray || tb1->ty == Tsarray)
if (e2->op == TOKarrayliteral &&
e2->implicitConvTo(tb1->arrayOf()))
{
// Make e1 into [e1]
e1 = new ArrayLiteralExp(e1->loc, e1);
e1->type = type;
if (e1->checkPostblit(sc, tb1))
return new ErrorExp();
e2 = e2->implicitCastTo(sc, tb1->arrayOf());
type = tb1->arrayOf();
goto L1elem;
}
if (e1->implicitConvTo(tb2next) >= MATCHconvert)
{
if (e1->checkPostblit(sc, tb1))
return new ErrorExp();
e1 = e1->implicitCastTo(sc, tb2next);
type = tb2next->arrayOf();
L1elem:
if (tb1->ty == Tarray || tb1->ty == Tsarray)
{
// Make e1 into [e1]
e1 = new ArrayLiteralExp(e1->loc, e1);
e1->type = type;
}
return this;
}
return this;
}

Lpeer:
if ((tb1->ty == Tsarray || tb1->ty == Tarray) &&
(tb2->ty == Tsarray || tb2->ty == Tarray) &&
(tb1next->mod || tb2next->mod) &&
Expand Down
13 changes: 10 additions & 3 deletions src/interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -2982,6 +2982,9 @@ class Interpreter : public Visitor
if (exceptionOrCant(se))
return;
result = interpret(e->member, istate, e->arguments, se);

// Repaint as same as CallExp::interpret() does.
result->loc = e->loc;
}
else
{
Expand Down Expand Up @@ -3074,6 +3077,12 @@ class Interpreter : public Visitor
Expression *ctorfail = interpret(e->member, istate, e->arguments, eref);
if (exceptionOrCant(ctorfail))
return;

/* Bugzilla 14465: Repaint the loc, because a super() call
* in the constructor modifies the loc of ClassReferenceExp
* in CallExp::interpret().
*/
eref->loc = e->loc;
}
result = eref;
return;
Expand Down Expand Up @@ -4897,10 +4906,8 @@ class Interpreter : public Visitor
}
if (!exceptionOrCantInterpret(result))
{
Expression* old = result;
result = paintTypeOntoLiteral(e->type, result);
if (result != old) // only change location if a conversion was necessary
result->loc = e->loc;
result->loc = e->loc;
}
else if (CTFEExp::isCantExp(result) && !global.gag)
showCtfeBackTrace(e, fd); // Print a stack trace.
Expand Down
2 changes: 1 addition & 1 deletion src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -7870,7 +7870,7 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc)
error(loc, "circular reference to '%s'", vd->toPrettyChars());
return new ErrorExp();
}
if (vd->offset < offset)
if (vd->offset < offset || vd->type->size() == 0)
e = NULL;
else if (vd->init)
{
Expand Down
3 changes: 2 additions & 1 deletion src/posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ LDFLAGS=-lm -lstdc++ -lpthread
#else
HOST_CC=g++
#endif
CC=$(HOST_CC) $(MODEL_FLAG)
CC=$(HOST_CC)
GIT=git

# Host D compiler for bootstrapping
Expand Down Expand Up @@ -119,6 +119,7 @@ MMD=-MMD -MF $(basename $@).deps
CFLAGS := $(WARNINGS) \
-fno-exceptions -fno-rtti \
-D__pascal= -DMARS=1 -DTARGET_$(OS_UPCASE)=1 -DDM_TARGET_CPU_$(TARGET_CPU)=1 \
$(MODEL_FLAG)
# Default D compiler flags for all source files
DFLAGS=

Expand Down
6 changes: 5 additions & 1 deletion src/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,11 @@ bool StructDeclaration::fill(Loc loc, Expressions *elements, bool ctorinit)
if (elements && vx)
{
Expression *e;
if (vx->init)
if (vx->type->size() == 0)
{
e = NULL;
}
else if (vx->init)
{
assert(!vx->init->isVoidInitializer());
e = vx->getConstInitializer(false);
Expand Down
11 changes: 8 additions & 3 deletions src/todt.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,10 +773,15 @@ dt_t **Type_toDt(Type *t, dt_t **pdt)

dt_t **toDtElem(TypeSArray *tsa, dt_t **pdt, Expression *e)
{
//printf("TypeSArray::toDtElem()\n");
size_t len = tsa->dim->toInteger();
if (len)
//printf("TypeSArray::toDtElem() tsa = %s\n", tsa->toChars());
if (tsa->size(Loc()) == 0)
{
pdt = dtnzeros(pdt, 0);
}
else
{
size_t len = tsa->dim->toInteger();
assert(len);
pdt = dtend(pdt);
Type *tnext = tsa->next;
Type *tbn = tnext->toBasetype();
Expand Down
18 changes: 18 additions & 0 deletions test/fail_compilation/ctfe14731.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
TEST_OUTPUT:
---
fail_compilation/ctfe14731.d(16): Error: cannot implicitly convert expression (["a b"]) of type string[] to string
fail_compilation/ctfe14731.d(17): Error: cannot implicitly convert expression (split("a b")) of type string[] to string
---
*/

string[] split(string a)
{
return [a];
}

void main()
{
enum string list1 = "a b".split();
string list2 = "a b".split();
}
Loading