aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2019-01-21 21:16:06 +0000
committerIain Buclaw <ibuclaw@gcc.gnu.org>2019-01-21 21:16:06 +0000
commit255b2d916ec794078cfd0c351d3e921f8701142a (patch)
tree3dee0722fb17b5496011bd698f924c31f5e56833 /gcc/d
parentd50114960965a85deb3ba6a19ac4f7640ed97e7e (diff)
downloadgcc-255b2d916ec794078cfd0c351d3e921f8701142a.zip
gcc-255b2d916ec794078cfd0c351d3e921f8701142a.tar.gz
gcc-255b2d916ec794078cfd0c351d3e921f8701142a.tar.bz2
Merge dmd upstream 180465274
Reduces the memory footprint of the CTFE interpreter by replacing new with emplacement new in many places. gcc/d/ChangeLog: 2019-01-21 Iain Buclaw <ibuclaw@gdcproject.org> * d-frontend.cc (Compiler::paintAsType): Update for new signature. From-SVN: r268124
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/ChangeLog4
-rw-r--r--gcc/d/d-frontend.cc2
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/compiler.h3
-rw-r--r--gcc/d/dmd/constfold.c27
-rw-r--r--gcc/d/dmd/ctfe.h9
-rw-r--r--gcc/d/dmd/ctfeexpr.c78
-rw-r--r--gcc/d/dmd/dinterpret.c598
-rw-r--r--gcc/d/dmd/dsymbol.c18
-rw-r--r--gcc/d/dmd/expression.c19
-rw-r--r--gcc/d/dmd/expression.h6
-rw-r--r--gcc/d/dmd/expressionsem.c6
-rw-r--r--gcc/d/dmd/idgen.c3
-rw-r--r--gcc/d/dmd/initsem.c11
-rw-r--r--gcc/d/dmd/mtype.c14
-rw-r--r--gcc/d/dmd/parse.c2
-rw-r--r--gcc/d/dmd/traits.c3
17 files changed, 481 insertions, 324 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 32160db..7014b21 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,7 @@
+2019-01-21 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-frontend.cc (Compiler::paintAsType): Update for new signature.
+
2019-01-20 Iain Buclaw <ibuclaw@gdcproject.org>
* d-builtins.cc (d_init_versions): Check value of
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index a1c0d53..d1d3c78 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -446,7 +446,7 @@ Compiler::genCmain (Scope *sc)
so we just lower the value to GCC and return the converted CST. */
Expression *
-Compiler::paintAsType (Expression *expr, Type *type)
+Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
{
/* We support up to 512-bit values. */
unsigned char buffer[64];
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index a3b2db7..e8ab8df 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-cd2034cd7b157dd8f3e94c684061bb1aa630b2b6
+180465274b72a2ff218449f6793af0fbaabbcaa3
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/compiler.h b/gcc/d/dmd/compiler.h
index e8ab992..a852078 100644
--- a/gcc/d/dmd/compiler.h
+++ b/gcc/d/dmd/compiler.h
@@ -19,6 +19,7 @@ class Expression;
class Module;
class Type;
struct Scope;
+struct UnionExp;
// DMD-generated module `__entrypoint` where the C main resides
extern Module *entrypoint;
@@ -28,7 +29,7 @@ extern Module *rootHasMain;
struct Compiler
{
// CTFE support for cross-compilation.
- static Expression *paintAsType(Expression *, Type *);
+ static Expression *paintAsType(UnionExp *, Expression *, Type *);
// Backend
static void loadModule(Module *);
static void genCmain(Scope *);
diff --git a/gcc/d/dmd/constfold.c b/gcc/d/dmd/constfold.c
index 83f0f3e..ddd356b 100644
--- a/gcc/d/dmd/constfold.c
+++ b/gcc/d/dmd/constfold.c
@@ -1457,8 +1457,7 @@ UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
memcpy(elements->tdata(),
es1->elements->tdata() + ilwr,
(size_t)(iupr - ilwr) * sizeof((*es1->elements)[0]));
- new(&ue) ArrayLiteralExp(e1->loc, elements);
- ue.exp()->type = type;
+ new(&ue) ArrayLiteralExp(e1->loc, type, elements);
}
}
else
@@ -1606,6 +1605,7 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
new(&ue) StringExp(loc, s, len);
StringExp *es = (StringExp *)ue.exp();
+ es->type = type;
es->sz = sz;
es->committed = 1;
}
@@ -1614,9 +1614,8 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
// Create an ArrayLiteralExp
Expressions *elements = new Expressions();
elements->push(e);
- new(&ue) ArrayLiteralExp(e->loc, elements);
+ new(&ue) ArrayLiteralExp(e->loc, type, elements);
}
- ue.exp()->type = type;
assert(ue.exp()->type);
return ue;
}
@@ -1627,8 +1626,7 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
// Handle null ~= null
if (t1->ty == Tarray && t2 == t1->nextOf())
{
- new(&ue) ArrayLiteralExp(e1->loc, e2);
- ue.exp()->type = type;
+ new(&ue) ArrayLiteralExp(e1->loc, type, e2);
assert(ue.exp()->type);
return ue;
}
@@ -1695,9 +1693,8 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
{
(*elems)[i] = ea->getElement(i);
}
- new(&ue) ArrayLiteralExp(e1->loc, elems);
+ new(&ue) ArrayLiteralExp(e1->loc, type, elems);
ArrayLiteralExp *dest = (ArrayLiteralExp *)ue.exp();
- dest->type = type;
sliceAssignArrayLiteralFromString(dest, es, ea->elements->dim);
assert(ue.exp()->type);
return ue;
@@ -1715,9 +1712,8 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
{
(*elems)[es->len + i] = ea->getElement(i);
}
- new(&ue) ArrayLiteralExp(e1->loc, elems);
+ new(&ue) ArrayLiteralExp(e1->loc, type, elems);
ArrayLiteralExp *dest = (ArrayLiteralExp *)ue.exp();
- dest->type = type;
sliceAssignArrayLiteralFromString(dest, es, 0);
assert(ue.exp()->type);
return ue;
@@ -1783,7 +1779,7 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
// Concatenate the arrays
Expressions *elems = ArrayLiteralExp::copyElements(e1, e2);
- new(&ue) ArrayLiteralExp(e1->loc, elems);
+ new(&ue) ArrayLiteralExp(e1->loc, NULL, elems);
e = ue.exp();
if (type->toBasetype()->ty == Tsarray)
@@ -1809,7 +1805,7 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
// Concatenate the array with null
Expressions *elems = ArrayLiteralExp::copyElements(e);
- new(&ue) ArrayLiteralExp(e->loc, elems);
+ new(&ue) ArrayLiteralExp(e->loc, NULL, elems);
e = ue.exp();
if (type->toBasetype()->ty == Tsarray)
@@ -1829,7 +1825,7 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
? ArrayLiteralExp::copyElements(e1) : new Expressions();
elems->push(e2);
- new(&ue) ArrayLiteralExp(e1->loc, elems);
+ new(&ue) ArrayLiteralExp(e1->loc, NULL, elems);
e = ue.exp();
if (type->toBasetype()->ty == Tsarray)
@@ -1846,7 +1842,7 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
{
Expressions *elems = ArrayLiteralExp::copyElements(e1, e2);
- new(&ue) ArrayLiteralExp(e2->loc, elems);
+ new(&ue) ArrayLiteralExp(e2->loc, NULL, elems);
e = ue.exp();
if (type->toBasetype()->ty == Tsarray)
@@ -1874,9 +1870,8 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
{
Expressions *expressions = new Expressions();
expressions->push(e);
- new(&ue) ArrayLiteralExp(loc, expressions);
+ new(&ue) ArrayLiteralExp(loc, t, expressions);
e = ue.exp();
- e->type = t;
}
else
{
diff --git a/gcc/d/dmd/ctfe.h b/gcc/d/dmd/ctfe.h
index 2c6a474..0e49432 100644
--- a/gcc/d/dmd/ctfe.h
+++ b/gcc/d/dmd/ctfe.h
@@ -134,6 +134,7 @@ UnionExp copyLiteral(Expression *e);
/// Set this literal to the given type, copying it if necessary
Expression *paintTypeOntoLiteral(Type *type, Expression *lit);
+Expression *paintTypeOntoLiteral(UnionExp *pue, Type *type, Expression *lit);
UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit);
/// Convert from a CTFE-internal slice, into a normal Expression
@@ -143,11 +144,11 @@ Expression *resolveSlice(Expression *e, UnionExp *pue = NULL);
uinteger_t resolveArrayLength(Expression *e);
/// Create an array literal consisting of 'elem' duplicated 'dim' times.
-ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
+ArrayLiteralExp *createBlockDuplicatedArrayLiteral(UnionExp *pue, Loc loc, Type *type,
Expression *elem, size_t dim);
/// Create a string literal consisting of 'value' duplicated 'dim' times.
-StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
+StringExp *createBlockDuplicatedStringLiteral(UnionExp *pue, Loc loc, Type *type,
unsigned value, size_t dim, unsigned char sz);
@@ -209,7 +210,7 @@ UnionExp pointerArithmetic(Loc loc, TOK op, Type *type,
bool isFloatIntPaint(Type *to, Type *from);
// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.
-Expression *paintFloatInt(Expression *fromVal, Type *to);
+Expression *paintFloatInt(UnionExp *pue, Expression *fromVal, Type *to);
/// Return true if t is an AA
bool isAssocArray(Type *t);
@@ -264,4 +265,4 @@ UnionExp ctfeCat(Loc loc, Type *type, Expression *e1, Expression *e2);
Expression *ctfeIndex(Loc loc, Type *type, Expression *e1, uinteger_t indx);
/// Cast 'e' of type 'type' to type 'to'.
-Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e);
+Expression *ctfeCast(UnionExp *pue, Loc loc, Type *type, Type *to, Expression *e);
diff --git a/gcc/d/dmd/ctfeexpr.c b/gcc/d/dmd/ctfeexpr.c
index 713e0f9..1050e93 100644
--- a/gcc/d/dmd/ctfeexpr.c
+++ b/gcc/d/dmd/ctfeexpr.c
@@ -264,10 +264,9 @@ UnionExp copyLiteral(Expression *e)
ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
Expressions *elements = copyLiteralArray(ale->elements, ale->basis);
- new(&ue) ArrayLiteralExp(e->loc, elements);
+ new(&ue) ArrayLiteralExp(e->loc, e->type, elements);
ArrayLiteralExp *r = (ArrayLiteralExp *)ue.exp();
- r->type = e->type;
r->ownedByCtfe = OWNEDctfe;
return ue;
}
@@ -314,7 +313,10 @@ UnionExp copyLiteral(Expression *e)
{
TypeSArray *tsa = (TypeSArray *)v->type;
size_t len = (size_t)tsa->dim->toInteger();
- m = createBlockDuplicatedArrayLiteral(e->loc, v->type, m, len);
+ UnionExp uex;
+ m = createBlockDuplicatedArrayLiteral(&uex, e->loc, v->type, m, len);
+ if (m == uex.exp())
+ m = uex.copy();
}
}
(*newelems)[i] = m;
@@ -414,6 +416,14 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
return paintTypeOntoLiteralCopy(type, lit).copy();
}
+Expression *paintTypeOntoLiteral(UnionExp *pue, Type *type, Expression *lit)
+{
+ if (lit->type->equals(type))
+ return lit;
+ *pue = paintTypeOntoLiteralCopy(type, lit);
+ return pue->exp();
+}
+
UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit)
{
UnionExp ue;
@@ -539,6 +549,7 @@ uinteger_t resolveArrayLength(Expression *e)
* Helper for NewExp
* Create an array literal consisting of 'elem' duplicated 'dim' times.
* Params:
+ * pue = where to store result
* loc = source location where the interpretation occurs
* type = target type of the result
* elem = the source of array element, it will be owned by the result
@@ -546,7 +557,7 @@ uinteger_t resolveArrayLength(Expression *e)
* Returns:
* Constructed ArrayLiteralExp
*/
-ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
+ArrayLiteralExp *createBlockDuplicatedArrayLiteral(UnionExp *pue, Loc loc, Type *type,
Expression *elem, size_t dim)
{
if (type->ty == Tsarray && type->nextOf()->ty == Tsarray && elem->type->ty != Tsarray)
@@ -554,7 +565,10 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
// If it is a multidimensional array literal, do it recursively
TypeSArray *tsa = (TypeSArray *)type->nextOf();
size_t len = (size_t)tsa->dim->toInteger();
- elem = createBlockDuplicatedArrayLiteral(loc, type->nextOf(), elem, len);
+ UnionExp ue;
+ elem = createBlockDuplicatedArrayLiteral(&ue, loc, type->nextOf(), elem, len);
+ if (elem == ue.exp())
+ elem = ue.copy();
}
// Buzilla 15681
@@ -567,8 +581,8 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
{
(*elements)[i] = mustCopy ? copyLiteral(elem).copy() : elem;
}
- ArrayLiteralExp *ale = new ArrayLiteralExp(loc, elements);
- ale->type = type;
+ new(pue) ArrayLiteralExp(loc, type, elements);
+ ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
ale->ownedByCtfe = OWNEDctfe;
return ale;
}
@@ -577,7 +591,7 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
* Helper for NewExp
* Create a string literal consisting of 'value' duplicated 'dim' times.
*/
-StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
+StringExp *createBlockDuplicatedStringLiteral(UnionExp *pue, Loc loc, Type *type,
unsigned value, size_t dim, unsigned char sz)
{
utf8_t *s = (utf8_t *)mem.xcalloc(dim + 1, sz);
@@ -591,7 +605,8 @@ StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
default: assert(0);
}
}
- StringExp *se = new StringExp(loc, s, dim);
+ new(pue) StringExp(loc, s, dim);
+ StringExp *se = (StringExp *)pue->exp();
se->type = type;
se->sz = sz;
se->committed = true;
@@ -984,13 +999,13 @@ bool isFloatIntPaint(Type *to, Type *from)
}
// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.
-Expression *paintFloatInt(Expression *fromVal, Type *to)
+Expression *paintFloatInt(UnionExp *pue, Expression *fromVal, Type *to)
{
if (exceptionOrCantInterpret(fromVal))
return fromVal;
assert(to->size() == 4 || to->size() == 8);
- return Compiler::paintAsType(fromVal, to);
+ return Compiler::paintAsType(pue, fromVal, to);
}
/******** Constant folding, with support for CTFE ***************************/
@@ -1512,10 +1527,9 @@ UnionExp ctfeCat(Loc loc, Type *type, Expression *e1, Expression *e2)
ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
- new(&ue) ArrayLiteralExp(es1->loc, copyLiteralArray(es1->elements));
+ new(&ue) ArrayLiteralExp(es1->loc, type, copyLiteralArray(es1->elements));
es1 = (ArrayLiteralExp *)ue.exp();
es1->elements->insert(es1->elements->dim, copyLiteralArray(es2->elements));
- es1->type = type;
return ue;
}
if (e1->op == TOKarrayliteral && e2->op == TOKnull &&
@@ -1587,29 +1601,33 @@ Expression *ctfeIndex(Loc loc, Type *type, Expression *e1, uinteger_t indx)
}
}
-Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e)
+Expression *ctfeCast(UnionExp *pue, Loc loc, Type *type, Type *to, Expression *e)
{
if (e->op == TOKnull)
- return paintTypeOntoLiteral(to, e);
+ return paintTypeOntoLiteral(pue, to, e);
+
if (e->op == TOKclassreference)
{
// Disallow reinterpreting class casts. Do this by ensuring that
// the original class can implicitly convert to the target class
ClassDeclaration *originalClass = ((ClassReferenceExp *)e)->originalClass();
if (originalClass->type->implicitConvTo(to->mutableOf()))
- return paintTypeOntoLiteral(to, e);
+ return paintTypeOntoLiteral(pue, to, e);
else
- return new NullExp(loc, to);
+ {
+ new(pue) NullExp(loc, to);
+ return pue->exp();
+ }
}
+
// Allow TypeInfo type painting
if (isTypeInfo_Class(e->type) && e->type->implicitConvTo(to))
- return paintTypeOntoLiteral(to, e);
+ return paintTypeOntoLiteral(pue, to, e);
+
// Allow casting away const for struct literals
if (e->op == TOKstructliteral &&
e->type->toBasetype()->castMod(0) == to->toBasetype()->castMod(0))
- {
- return paintTypeOntoLiteral(to, e);
- }
+ return paintTypeOntoLiteral(pue, to, e);
Expression *r;
if (e->type->equals(type) && type->equals(to))
@@ -1617,22 +1635,28 @@ Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e)
// necessary not to change e's address for pointer comparisons
r = e;
}
- else if (to->toBasetype()->ty == Tarray && type->toBasetype()->ty == Tarray &&
+ else if (to->toBasetype()->ty == Tarray &&
+ type->toBasetype()->ty == Tarray &&
to->toBasetype()->nextOf()->size() == type->toBasetype()->nextOf()->size())
{
// Bugzilla 12495: Array reinterpret casts: eg. string to immutable(ubyte)[]
- return paintTypeOntoLiteral(to, e);
+ return paintTypeOntoLiteral(pue, to, e);
}
else
{
- r = Cast(loc, type, to, e).copy();
+ *pue = Cast(loc, type, to, e);
+ r = pue->exp();
}
+
if (CTFEExp::isCantExp(r))
error(loc, "cannot cast %s to %s at compile time", e->toChars(), to->toChars());
+
if (e->op == TOKarrayliteral)
((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDctfe;
+
if (e->op == TOKstring)
((StringExp *)e)->ownedByCtfe = OWNEDctfe;
+
return r;
}
@@ -1816,9 +1840,8 @@ UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
for (size_t i = copylen; i < newlen; i++)
(*elements)[i] = defaultElem;
}
- new(&ue) ArrayLiteralExp(loc, elements);
+ new(&ue) ArrayLiteralExp(loc, arrayType, elements);
ArrayLiteralExp *aae = (ArrayLiteralExp *)ue.exp();
- aae->type = arrayType;
aae->ownedByCtfe = OWNEDctfe;
}
return ue;
@@ -2078,9 +2101,8 @@ UnionExp voidInitLiteral(Type *t, VarDeclaration *var)
elem = copyLiteral(elem).copy();
(*elements)[i] = elem;
}
- new(&ue) ArrayLiteralExp(var->loc, elements);
+ new(&ue) ArrayLiteralExp(var->loc, tsa, elements);
ArrayLiteralExp *ae = (ArrayLiteralExp *)ue.exp();
- ae->type = tsa;
ae->ownedByCtfe = OWNEDctfe;
}
else if (t->ty == Tstruct)
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 7c497d8..140abfd 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -264,14 +264,18 @@ void printCtfePerformanceStats()
#endif
}
-VarDeclaration *findParentVar(Expression *e);
-Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
+static Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
FuncDeclaration *fd, Expressions *arguments, Expression *pthis);
-Expression *evaluatePostblit(InterState *istate, Expression *e);
-Expression *evaluateDtor(InterState *istate, Expression *e);
-Expression *scrubReturnValue(Loc loc, Expression *e);
+static Expression *evaluatePostblit(InterState *istate, Expression *e);
+static Expression *evaluateDtor(InterState *istate, Expression *e);
-Expression *scrubCacheValue(Loc loc, Expression *e);
+static bool isEntirelyVoid(Expressions* elems);
+static Expression *scrubArray(Loc loc, Expressions *elems, bool structlit = false);
+static Expression *scrubStructLiteral(Loc loc, StructLiteralExp *sle);
+static Expression *scrubReturnValue(Loc loc, Expression *e);
+static Expression *scrubArrayCache(Expressions *elems);
+static Expression *scrubStructLiteralCache(StructLiteralExp *sle);
+static Expression *scrubCacheValue(Expression *e);
/*************************************
@@ -635,8 +639,24 @@ void ctfeCompile(FuncDeclaration *fd)
*/
Expression *ctfeInterpret(Expression *e)
{
- if (e->op == TOKerror)
+ switch (e->op)
+ {
+ case TOKint64:
+ case TOKfloat64:
+ case TOKcomplex80:
+ case TOKnull:
+ case TOKstring:
+ if (e->type->ty == Terror)
+ return new ErrorExp();
+ /* fall through */
+
+ case TOKerror:
return e;
+
+ default:
+ break;
+ }
+
assert(e->type); // Bugzilla 14642
//assert(e->type->ty != Terror); // FIXME
if (e->type->ty == Terror)
@@ -710,6 +730,8 @@ Expression *ctfeInterpretForPragmaMsg(Expression *e)
/*************************************
* Attempt to interpret a function given the arguments.
* Input:
+ * pue storage for result
+ * fd function being called
* istate state for calling function (NULL if none)
* arguments function arguments
* thisarg 'this', if a needThis() function, NULL if not.
@@ -718,8 +740,9 @@ Expression *ctfeInterpretForPragmaMsg(Expression *e)
* or CTFEExp if function returned void.
*/
-static Expression *interpretFunction(FuncDeclaration *fd, InterState *istate, Expressions *arguments, Expression *thisarg)
+static Expression *interpretFunction(UnionExp *pue, FuncDeclaration *fd, InterState *istate, Expressions *arguments, Expression *thisarg)
{
+ assert(pue);
if (fd->semanticRun == PASSsemantic3)
{
fd->error("circular dependency. Functions cannot be interpreted while being compiled");
@@ -898,7 +921,7 @@ static Expression *interpretFunction(FuncDeclaration *fd, InterState *istate, Ex
e = CTFEExp::cantexp;
break;
}
- e = interpret(fd->fbody, &istatex);
+ e = interpret(pue, fd->fbody, &istatex);
if (istatex.start)
{
@@ -938,6 +961,8 @@ static Expression *interpretFunction(FuncDeclaration *fd, InterState *istate, Ex
// If it generated an uncaught exception, report error.
if (!istate && e->op == TOKthrownexception)
{
+ if (e == pue->exp())
+ e = pue->copy();
((ThrownExceptionExp *)e)->generateUncaughtError();
e = CTFEExp::cantexp;
}
@@ -2004,7 +2029,8 @@ public:
{
// Normally this is already done by optimize()
// Do it here in case optimize(WANTvalue) wasn't run before CTFE
- result = new SymOffExp(e->loc, ((VarExp *)e->e1)->var, 0);
+ new(pue) SymOffExp(e->loc, ((VarExp *)e->e1)->var, 0);
+ result = pue->exp();
result->type = e->type;
return;
}
@@ -2032,7 +2058,7 @@ public:
return;
}
- Expression *er = interpret(e->e1, istate);
+ Expression *er = interpret(pue, e->e1, istate);
if (exceptionOrCant(er))
return;
if (er == e->e1)
@@ -2042,6 +2068,7 @@ public:
}
else
{
+ er = (er == pue->exp()) ? pue->copy() : er;
new(pue) DelegateExp(e->loc, er, e->func, false);
result = pue->exp();
result->type = e->type;
@@ -2100,7 +2127,7 @@ public:
/* Bugzilla 14304: e is a value that is not yet owned by CTFE.
* Mark as "cached", and use it directly during interpretation.
*/
- e = scrubCacheValue(v->loc, e);
+ e = scrubCacheValue(e);
ctfeStack.saveGlobalConstant(v, e);
}
else
@@ -2236,7 +2263,7 @@ public:
* foo(s); // VarExp('s') will have const(S)
*/
// A VarExp may include an implicit cast. It must be done explicitly.
- result = paintTypeOntoLiteral(e->type, result);
+ result = paintTypeOntoLiteral(pue, e->type, result);
}
}
@@ -2363,7 +2390,7 @@ public:
}
if (Expression *ex = isExpression(e->obj))
{
- result = interpret(ex, istate);
+ result = interpret(pue, ex, istate);
if (exceptionOrCant(ex))
return;
@@ -2493,9 +2520,8 @@ public:
result = CTFEExp::cantexp;
return;
}
- new(pue) ArrayLiteralExp(e->loc, basis, expsx);
+ new(pue) ArrayLiteralExp(e->loc, e->type, basis, expsx);
ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
- ale->type = e->type;
ale->ownedByCtfe = OWNEDctfe;
result = ale;
}
@@ -2505,7 +2531,10 @@ public:
result = e;
}
else
- result = copyLiteral(e).copy();
+ {
+ *pue = copyLiteral(e);
+ result = pue->exp();
+ }
}
void visit(AssocArrayLiteralExp *e)
@@ -2585,7 +2614,10 @@ public:
result = ae;
}
else
- result = copyLiteral(e).copy();
+ {
+ *pue = copyLiteral(e);
+ result = pue->exp();
+ }
}
void visit(StructLiteralExp *e)
@@ -2635,7 +2667,10 @@ public:
// Block assignment from inside struct literals
TypeSArray *tsa = (TypeSArray *)v->type;
size_t len = (size_t)tsa->dim->toInteger();
- ex = createBlockDuplicatedArrayLiteral(ex->loc, v->type, ex, len);
+ UnionExp ue;
+ ex = createBlockDuplicatedArrayLiteral(&ue, ex->loc, v->type, ex, len);
+ if (ex == ue.exp())
+ ex = ue.copy();
}
}
@@ -2665,22 +2700,25 @@ public:
result = sle;
}
else
- result = copyLiteral(e).copy();
+ {
+ *pue = copyLiteral(e);
+ result = pue->exp();
+ }
}
// Create an array literal of type 'newtype' with dimensions given by
// 'arguments'[argnum..$]
- static Expression *recursivelyCreateArrayLiteral(Loc loc, Type *newtype, InterState *istate,
+ static Expression *recursivelyCreateArrayLiteral(UnionExp *pue, Loc loc, Type *newtype, InterState *istate,
Expressions *arguments, int argnum)
{
- Expression *lenExpr = interpret((*arguments)[argnum], istate);
+ Expression *lenExpr = interpret(pue, (*arguments)[argnum], istate);
if (exceptionOrCantInterpret(lenExpr))
return lenExpr;
size_t len = (size_t)(lenExpr->toInteger());
Type *elemType = ((TypeArray *)newtype)->next;
if (elemType->ty == Tarray && argnum < (int)arguments->dim - 1)
{
- Expression *elem = recursivelyCreateArrayLiteral(loc, elemType, istate,
+ Expression *elem = recursivelyCreateArrayLiteral(pue, loc, elemType, istate,
arguments, argnum + 1);
if (exceptionOrCantInterpret(elem))
return elem;
@@ -2689,8 +2727,8 @@ public:
elements->setDim(len);
for (size_t i = 0; i < len; i++)
(*elements)[i] = copyLiteral(elem).copy();
- ArrayLiteralExp *ae = new ArrayLiteralExp(loc, elements);
- ae->type = newtype;
+ new(pue) ArrayLiteralExp(loc, newtype, elements);
+ ArrayLiteralExp *ae = (ArrayLiteralExp *)pue->exp();
ae->ownedByCtfe = OWNEDctfe;
return ae;
}
@@ -2699,12 +2737,12 @@ public:
{
const unsigned ch = (unsigned)elemType->defaultInitLiteral(loc)->toInteger();
const unsigned char sz = (unsigned char)elemType->size();
- return createBlockDuplicatedStringLiteral(loc, newtype, ch, len, sz);
+ return createBlockDuplicatedStringLiteral(pue, loc, newtype, ch, len, sz);
}
else
{
Expression *el = interpret(elemType->defaultInitLiteral(loc), istate);
- return createBlockDuplicatedArrayLiteral(loc, newtype, el, len);
+ return createBlockDuplicatedArrayLiteral(pue, loc, newtype, el, len);
}
}
@@ -2717,13 +2755,13 @@ public:
return;
}
- result = interpret(e->argprefix, istate, ctfeNeedNothing);
- if (exceptionOrCant(result))
+ Expression *epre = interpret(pue, e->argprefix, istate, ctfeNeedNothing);
+ if (exceptionOrCant(epre))
return;
if (e->newtype->ty == Tarray && e->arguments)
{
- result = recursivelyCreateArrayLiteral(e->loc, e->newtype, istate, e->arguments, 0);
+ result = recursivelyCreateArrayLiteral(pue, e->loc, e->newtype, istate, e->arguments, 0);
return;
}
if (e->newtype->toBasetype()->ty == Tstruct)
@@ -2734,7 +2772,7 @@ public:
se = interpret(se, istate);
if (exceptionOrCant(se))
return;
- result = interpretFunction(e->member, istate, e->arguments, se);
+ result = interpretFunction(pue, e->member, istate, e->arguments, se);
// Repaint as same as CallExp::interpret() does.
result->loc = e->loc;
@@ -2761,11 +2799,12 @@ public:
StructLiteralExp *se = new StructLiteralExp(e->loc, sd, exps, e->newtype);
se->type = e->newtype;
se->ownedByCtfe = OWNEDctfe;
- result = interpret(se, istate);
+ result = interpret(pue, se, istate);
}
if (exceptionOrCant(result))
return;
- new(pue) AddrExp(e->loc, result, e->type);
+ Expression *ev = (result == pue->exp()) ? pue->copy() : result;
+ new(pue) AddrExp(e->loc, ev, e->type);
result = pue->exp();
return;
}
@@ -2809,13 +2848,14 @@ public:
// We probably won't get away with this.
StructLiteralExp *se = new StructLiteralExp(e->loc, (StructDeclaration *)cd, elems, e->newtype);
se->ownedByCtfe = OWNEDctfe;
- Expression *eref = new ClassReferenceExp(e->loc, se, e->type);
+ new(pue) ClassReferenceExp(e->loc, se, e->type);
+ Expression *eref = pue->exp();
if (e->member)
{
// Call constructor
if (!e->member->fbody)
{
- Expression *ctorfail = evaluateIfBuiltin(istate, e->loc, e->member, e->arguments, eref);
+ Expression *ctorfail = evaluateIfBuiltin(pue, istate, e->loc, e->member, e->arguments, eref);
if (ctorfail)
{
if (exceptionOrCant(ctorfail))
@@ -2827,7 +2867,8 @@ public:
result = CTFEExp::cantexp;
return;
}
- Expression *ctorfail = interpretFunction(e->member, istate, e->arguments, eref);
+ UnionExp ue;
+ Expression *ctorfail = interpretFunction(&ue, e->member, istate, e->arguments, eref);
if (exceptionOrCant(ctorfail))
return;
@@ -2855,8 +2896,7 @@ public:
Expressions *elements = new Expressions();
elements->setDim(1);
(*elements)[0] = newval;
- ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, elements);
- ae->type = e->newtype->arrayOf();
+ ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, e->newtype->arrayOf(), elements);
ae->ownedByCtfe = OWNEDctfe;
IndexExp *ei = new IndexExp(e->loc, ae, new IntegerExp(Loc(), 0, Type::tsize_t));
@@ -3462,7 +3502,7 @@ public:
assignAssocArrayElement(e->loc, existingAA, lastIndex, newval);
// Determine the return value
- result = ctfeCast(e->loc, e->type, e->type, fp && post ? oldval : newval);
+ result = ctfeCast(pue, e->loc, e->type, e->type, fp && post ? oldval : newval);
return;
}
if (e1->op == TOKarraylength)
@@ -3474,10 +3514,13 @@ public:
*/
// Determine the return value
- result = ctfeCast(e->loc, e->type, e->type, fp && post ? oldval : newval);
+ result = ctfeCast(pue, e->loc, e->type, e->type, fp && post ? oldval : newval);
if (exceptionOrCant(result))
return;
+ if (result == pue->exp())
+ result = pue->copy();
+
size_t oldlen = (size_t)oldval->toInteger();
size_t newlen = (size_t)newval->toInteger();
if (oldlen == newlen) // no change required -- we're done!
@@ -3511,15 +3554,21 @@ public:
if (!isBlockAssignment)
{
- newval = ctfeCast(e->loc, e->type, e->type, newval);
+ newval = ctfeCast(pue, e->loc, e->type, e->type, newval);
if (exceptionOrCant(newval))
return;
+ if (newval == pue->exp())
+ newval = pue->copy();
// Determine the return value
if (goal == ctfeNeedLvalue) // Bugzilla 14371
result = e1;
else
- result = ctfeCast(e->loc, e->type, e->type, fp && post ? oldval : newval);
+ {
+ result = ctfeCast(pue, e->loc, e->type, e->type, fp && post ? oldval : newval);
+ if (result == pue->exp())
+ result = pue->copy();
+ }
if (exceptionOrCant(result))
return;
}
@@ -3536,7 +3585,7 @@ public:
{
// Note that slice assignments don't support things like ++, so
// we don't need to remember 'returnValue'.
- result = interpretAssignToSlice(e, e1, newval, isBlockAssignment);
+ result = interpretAssignToSlice(pue, e, e1, newval, isBlockAssignment);
if (exceptionOrCant(result))
return;
if (e->e1->op == TOKslice)
@@ -3781,7 +3830,7 @@ public:
* it returns aggregate[low..upp], except that as an optimisation,
* if goal == ctfeNeedNothing, it will return NULL
*/
- Expression *interpretAssignToSlice(BinExp *e,
+ Expression *interpretAssignToSlice(UnionExp *pue, BinExp *e,
Expression *e1, Expression *newval, bool isBlockAssignment)
{
dinteger_t lowerbound;
@@ -3962,7 +4011,7 @@ public:
new IntegerExp(e->loc, firstIndex, Type::tsize_t),
new IntegerExp(e->loc, firstIndex + upperbound - lowerbound, Type::tsize_t));
retslice->type = e->type;
- return interpret(retslice, istate);
+ return interpret(pue, retslice, istate);
}
if (aggregate->op == TOKarrayliteral)
{
@@ -4178,7 +4227,7 @@ public:
new IntegerExp(e->loc, firstIndex, Type::tsize_t),
new IntegerExp(e->loc, firstIndex + upperbound - lowerbound, Type::tsize_t));
retslice->type = e->type;
- return interpret(retslice, istate);
+ return interpret(pue, retslice, istate);
}
e->error("slice operation %s = %s cannot be evaluated at compile time",
@@ -4285,7 +4334,7 @@ public:
* relational sub-expressions can be negated, eg
* (!(q1 < p1) && p2 <= q2) is valid.
*/
- void interpretFourPointerRelation(BinExp *e)
+ void interpretFourPointerRelation(UnionExp *pue, BinExp *e)
{
assert(e->op == TOKandand || e->op == TOKoror);
@@ -4311,12 +4360,16 @@ public:
}
//printf("FourPointerRelation %s\n", toChars());
+ UnionExp ue1;
+ UnionExp ue2;
+ UnionExp ue3;
+ UnionExp ue4;
// Evaluate the first two pointers
- p1 = interpret(p1, istate);
+ p1 = interpret(&ue1, p1, istate);
if (exceptionOrCant(p1))
return;
- p2 = interpret(p2, istate);
+ p2 = interpret(&ue2, p2, istate);
if (exceptionOrCant(p2))
return;
dinteger_t ofs1, ofs2;
@@ -4329,7 +4382,7 @@ public:
{
// Here it is either CANT_INTERPRET,
// or an IsInside comparison returning false.
- p3 = interpret(p3, istate);
+ p3 = interpret(&ue3, p3, istate);
if (CTFEExp::isCantExp(p3))
return;
// Note that it is NOT legal for it to throw an exception!
@@ -4338,7 +4391,7 @@ public:
except = p3;
else
{
- p4 = interpret(p4, istate);
+ p4 = interpret(&ue4, p4, istate);
if (CTFEExp::isCantExp(p4))
{
result = p4;
@@ -4367,7 +4420,8 @@ public:
(dir1 != dir2 && pointToSameMemoryBlock(agg1, agg3) && pointToSameMemoryBlock(agg2, agg4)))
{
// it's a legal two-sided comparison
- result = new IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
+ new(pue) IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
+ result = pue->exp();
return;
}
// It's an invalid four-pointer comparison. Either the second
@@ -4393,25 +4447,24 @@ public:
nott = !nott;
ex = ((NotExp *)ex)->e1;
}
- TOK cmpop = ex->op;
- if (nott)
- cmpop = reverseRelation(cmpop);
- int cmp = comparePointers(cmpop, agg1, ofs1, agg2, ofs2);
+ const TOK cmpop = nott ? reverseRelation(ex->op) : ex->op;
+ const int cmp = comparePointers(cmpop, agg1, ofs1, agg2, ofs2);
// We already know this is a valid comparison.
assert(cmp >= 0);
if ((e->op == TOKandand && cmp == 1) ||
(e->op == TOKoror && cmp == 0))
{
- result = interpret(e->e2, istate);
+ result = interpret(pue, e->e2, istate);
return;
}
- result = new IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
+ new(pue) IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
+ result = pue->exp();
}
void visit(AndAndExp *e)
{
// Check for an insidePointer expression, evaluate it if so
- interpretFourPointerRelation(e);
+ interpretFourPointerRelation(pue, e);
if (result)
return;
@@ -4461,7 +4514,7 @@ public:
void visit(OrOrExp *e)
{
// Check for an insidePointer expression, evaluate it if so
- interpretFourPointerRelation(e);
+ interpretFourPointerRelation(pue, e);
if (result)
return;
@@ -4695,7 +4748,7 @@ public:
}
// Check for built-in functions
- result = evaluateIfBuiltin(istate, e->loc, fd, e->arguments, pthis);
+ result = evaluateIfBuiltin(pue, istate, e->loc, fd, e->arguments, pthis);
if (result)
return;
@@ -4707,13 +4760,17 @@ public:
return;
}
- result = interpretFunction(fd, istate, e->arguments, pthis);
+ result = interpretFunction(pue, fd, istate, e->arguments, pthis);
if (result->op == TOKvoidexp)
return;
if (!exceptionOrCantInterpret(result))
{
- if (goal != ctfeNeedLvalue) // Peel off CTFE reference if it's unnesessary
- result = interpret(result, istate);
+ if (goal != ctfeNeedLvalue) // Peel off CTFE reference if it's unnecessary
+ {
+ if (result == pue->exp())
+ result = pue->copy();
+ result = interpret(pue, result, istate);
+ }
}
if (!exceptionOrCantInterpret(result))
{
@@ -5306,17 +5363,37 @@ public:
void visit(CatExp *e)
{
- Expression *e1 = interpret(e->e1, istate);
+ UnionExp ue1;
+ Expression *e1 = interpret(&ue1, e->e1, istate);
if (exceptionOrCant(e1))
return;
- Expression *e2 = interpret(e->e2, istate);
+
+ UnionExp ue2;
+ Expression *e2 = interpret(&ue2, e->e2, istate);
if (exceptionOrCant(e2))
return;
+
UnionExp e1tmp;
e1 = resolveSlice(e1, &e1tmp);
+
UnionExp e2tmp;
e2 = resolveSlice(e2, &e2tmp);
- result = ctfeCat(e->loc, e->type, e1, e2).copy();
+
+ /* e1 and e2 can't go on the stack because of x~[y] and [x]~y will
+ * result in [x,y] and then x or y is on the stack.
+ * But if they are both strings, we can, because it isn't the x~[y] case.
+ */
+ if (!(e1->op == TOKstring && e2->op == TOKstring))
+ {
+ if (e1 == ue1.exp())
+ e1 = ue1.copy();
+ if (e2 == ue2.exp())
+ e2 = ue2.copy();
+ }
+
+ *pue = ctfeCat(e->loc, e->type, e1, e2);
+ result = pue->exp();
+
if (CTFEExp::isCantExp(result))
{
e->error("%s cannot be interpreted at compile time", e->toChars());
@@ -5375,7 +5452,7 @@ public:
if (cd->dtor)
{
- result = interpretFunction(cd->dtor, istate, NULL, cre);
+ result = interpretFunction(pue, cd->dtor, istate, NULL, cre);
if (exceptionOrCant(result))
return;
}
@@ -5406,7 +5483,7 @@ public:
if (sd->dtor)
{
- result = interpretFunction(sd->dtor, istate, NULL, sle);
+ result = interpretFunction(pue, sd->dtor, istate, NULL, sle);
if (exceptionOrCant(result))
return;
}
@@ -5440,7 +5517,7 @@ public:
for (size_t i = 0; i < ale->elements->dim; i++)
{
Expression *el = (*ale->elements)[i];
- result = interpretFunction(sd->dtor, istate, NULL, el);
+ result = interpretFunction(pue, sd->dtor, istate, NULL, el);
if (exceptionOrCant(result))
return;
}
@@ -5473,7 +5550,7 @@ public:
if (e1->op == TOKint64)
{
// Happens with Windows HANDLEs, for example.
- result = paintTypeOntoLiteral(e->to, e1);
+ result = paintTypeOntoLiteral(pue, e->to, e1);
return;
}
bool castToSarrayPointer = false;
@@ -5516,13 +5593,14 @@ public:
if (e1->op == TOKslice)
{
- if (((SliceExp *)e1)->e1->op == TOKnull)
+ SliceExp *se = (SliceExp *)e1;
+ if (se->e1->op == TOKnull)
{
- result = paintTypeOntoLiteral(e->type, ((SliceExp *)e1)->e1);
+ result = paintTypeOntoLiteral(pue, e->type, se->e1);
return;
}
// Create a CTFE pointer &aggregate[1..2]
- IndexExp *ei = new IndexExp(e->loc, ((SliceExp *)e1)->e1, ((SliceExp *)e1)->lwr);
+ IndexExp *ei = new IndexExp(e->loc, se->e1, se->lwr);
ei->type = e->type->nextOf();
new(pue) AddrExp(e->loc, ei, e->type);
result = pue->exp();
@@ -5541,7 +5619,6 @@ public:
{
// type painting operation
IndexExp *ie = (IndexExp *)e1;
- result = new IndexExp(e1->loc, ie->e1, ie->e2);
if (castBackFromVoid)
{
// get the original type. For strings, it's just the type...
@@ -5550,7 +5627,7 @@ public:
if (ie->e1->op == TOKarrayliteral && ie->e2->op == TOKint64)
{
ArrayLiteralExp *ale = (ArrayLiteralExp *)ie->e1;
- size_t indx = (size_t)ie->e2->toInteger();
+ const size_t indx = (size_t)ie->e2->toInteger();
if (indx < ale->elements->dim)
{
Expression *xx = (*ale->elements)[indx];
@@ -5572,23 +5649,26 @@ public:
return;
}
}
+ new(pue) IndexExp(e1->loc, ie->e1, ie->e2);
+ result = pue->exp();
result->type = e->type;
return;
}
if (e1->op == TOKaddress)
{
- Type *origType = ((AddrExp *)e1)->e1->type;
+ AddrExp *ae = (AddrExp *)e1;
+ Type *origType = ae->e1->type;
if (isSafePointerCast(origType, pointee))
{
- new(pue) AddrExp(e->loc, ((AddrExp *)e1)->e1, e->type);
+ new(pue) AddrExp(e->loc, ae->e1, e->type);
result = pue->exp();
return;
}
- if (castToSarrayPointer && pointee->toBasetype()->ty == Tsarray && ((AddrExp *)e1)->e1->op == TOKindex)
+ if (castToSarrayPointer && pointee->toBasetype()->ty == Tsarray && ae->e1->op == TOKindex)
{
// &val[idx]
dinteger_t dim = ((TypeSArray *)pointee->toBasetype())->dim->toInteger();
- IndexExp *ie = (IndexExp *)((AddrExp *)e1)->e1;
+ IndexExp *ie = (IndexExp *)ae->e1;
Expression *lwr = ie->e2;
Expression *upr = new IntegerExp(ie->e2->loc, ie->e2->toInteger() + dim, Type::tsize_t);
@@ -5669,7 +5749,7 @@ public:
result = pue->exp();
return;
}
- result = ctfeCast(e->loc, e->type, e->to, e1);
+ result = ctfeCast(pue, e->loc, e->type, e->to, e1);
}
void visit(AssertExp *e)
@@ -5708,20 +5788,30 @@ public:
void visit(PtrExp *e)
{
// Check for int<->float and long<->double casts.
- if (e->e1->op == TOKsymoff && ((SymOffExp *)e->e1)->offset == 0 && ((SymOffExp *)e->e1)->var->isVarDeclaration() && isFloatIntPaint(e->type, ((SymOffExp *)e->e1)->var->type))
+ if (e->e1->op == TOKsymoff)
{
- // *(cast(int*)&v), where v is a float variable
- result = paintFloatInt(getVarExp(e->loc, istate, ((SymOffExp *)e->e1)->var, ctfeNeedRvalue), e->type);
- return;
+ SymOffExp *soe = (SymOffExp *)e->e1;
+ if (soe->offset == 0 && soe->var->isVarDeclaration() && isFloatIntPaint(e->type, soe->var->type))
+ {
+ // *(cast(int*)&v), where v is a float variable
+ result = paintFloatInt(pue, getVarExp(e->loc, istate, soe->var, ctfeNeedRvalue), e->type);
+ return;
+ }
}
- if (e->e1->op == TOKcast && ((CastExp *)e->e1)->e1->op == TOKaddress)
+
+ if (e->e1->op == TOKcast)
{
- // *(cast(int*)&x), where x is a float expression
- Expression *x = ((AddrExp *)(((CastExp *)e->e1)->e1))->e1;
- if (isFloatIntPaint(e->type, x->type))
+ CastExp *ce1 = (CastExp *)e->e1;
+ if (ce1->e1->op == TOKaddress)
{
- result = paintFloatInt(interpret(x, istate), e->type);
- return;
+ AddrExp *ae11 = (AddrExp *)ce1->e1;
+ // *(cast(int*)&x), where x is a float expression
+ Expression *x = ae11->e1;
+ if (isFloatIntPaint(e->type, x->type))
+ {
+ result = paintFloatInt(pue, interpret(x, istate), e->type);
+ return;
+ }
}
}
@@ -5785,7 +5875,7 @@ public:
*/
return;
}
- result = interpret(result, istate, goal);
+ result = interpret(pue, result, istate, goal);
if (exceptionOrCant(result))
return;
}
@@ -5898,7 +5988,10 @@ public:
// Block assignment from inside struct literals
TypeSArray *tsa = (TypeSArray *)v->type;
size_t len = (size_t)tsa->dim->toInteger();
- result = createBlockDuplicatedArrayLiteral(ex->loc, v->type, ex, len);
+ UnionExp ue;
+ result = createBlockDuplicatedArrayLiteral(&ue, ex->loc, v->type, ex, len);
+ if (result == ue.exp())
+ result = ue.copy();
(*se->elements)[i] = result;
}
}
@@ -6022,57 +6115,47 @@ Expression *interpret(Statement *s, InterState *istate)
return result;
}
-Expression *scrubArray(Loc loc, Expressions *elems, bool structlit = false);
-
-/* All results destined for use outside of CTFE need to have their CTFE-specific
+/**
+ * All results destined for use outside of CTFE need to have their CTFE-specific
* features removed.
- * In particular, all slices must be resolved.
+ * In particular,
+ * 1. all slices must be resolved.
+ * 2. all .ownedByCtfe set to OWNEDcode
*/
Expression *scrubReturnValue(Loc loc, Expression *e)
{
if (e->op == TOKclassreference)
{
- StructLiteralExp *se = ((ClassReferenceExp*)e)->value;
- se->ownedByCtfe = OWNEDcode;
- if (!(se->stageflags & stageScrub))
- {
- int old = se->stageflags;
- se->stageflags |= stageScrub;
- if (Expression *ex = scrubArray(loc, se->elements, true))
- return ex;
- se->stageflags = old;
- }
+ StructLiteralExp *sle = ((ClassReferenceExp*)e)->value;
+ if (Expression *ex = scrubStructLiteral(loc, sle))
+ return ex;
}
- if (e->op == TOKvoid)
+ else if (e->op == TOKvoid)
{
error(loc, "uninitialized variable '%s' cannot be returned from CTFE", ((VoidInitExp *)e)->var->toChars());
return new ErrorExp();
}
+
e = resolveSlice(e);
+
if (e->op == TOKstructliteral)
{
- StructLiteralExp *se = (StructLiteralExp *)e;
- se->ownedByCtfe = OWNEDcode;
- if (!(se->stageflags & stageScrub))
- {
- int old = se->stageflags;
- se->stageflags |= stageScrub;
- if (Expression *ex = scrubArray(loc, se->elements, true))
- return ex;
- se->stageflags = old;
- }
+ StructLiteralExp *sle = (StructLiteralExp *)e;
+ if (Expression *ex = scrubStructLiteral(loc, sle))
+ return ex;
}
- if (e->op == TOKstring)
+ else if (e->op == TOKstring)
{
((StringExp *)e)->ownedByCtfe = OWNEDcode;
}
- if (e->op == TOKarrayliteral)
+ else if (e->op == TOKarrayliteral)
{
- ((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDcode;
- if (Expression *ex = scrubArray(loc, ((ArrayLiteralExp *)e)->elements))
+ ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
+ ale->ownedByCtfe = OWNEDcode;
+ if (Expression *ex = scrubArray(loc, ale->elements))
return ex;
}
- if (e->op == TOKassocarrayliteral)
+ else if (e->op == TOKassocarrayliteral)
{
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
aae->ownedByCtfe = OWNEDcode;
@@ -6085,24 +6168,34 @@ Expression *scrubReturnValue(Loc loc, Expression *e)
return e;
}
+/* Returns: true if e is void,
+ * or is an array literal or struct literal of void elements.
+ */
+static bool isVoid(Expression *e)
+{
+ if (e->op == TOKvoid)
+ return true;
+
+ if (e->op == TOKarrayliteral)
+ return isEntirelyVoid(((ArrayLiteralExp *)e)->elements);
+
+ if (e->op == TOKstructliteral)
+ return isEntirelyVoid(((StructLiteralExp *)e)->elements);
+
+ return false;
+}
+
// Return true if every element is either void,
// or is an array literal or struct literal of void elements.
bool isEntirelyVoid(Expressions *elems)
{
for (size_t i = 0; i < elems->dim; i++)
{
- Expression *m = (*elems)[i];
+ Expression *e = (*elems)[i];
// It can be NULL for performance reasons,
// see StructLiteralExp::interpret().
- if (!m)
- continue;
-
- if (!(m->op == TOKvoid) &&
- !(m->op == TOKarrayliteral && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) &&
- !(m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements)))
- {
+ if (e && !isVoid(e))
return false;
- }
}
return true;
}
@@ -6112,102 +6205,116 @@ Expression *scrubArray(Loc loc, Expressions *elems, bool structlit)
{
for (size_t i = 0; i < elems->dim; i++)
{
- Expression *m = (*elems)[i];
+ Expression *e = (*elems)[i];
// It can be NULL for performance reasons,
// see StructLiteralExp::interpret().
- if (!m)
+ if (!e)
continue;
// A struct .init may contain void members.
// Static array members are a weird special case (bug 10994).
- if (structlit &&
- ((m->op == TOKvoid) ||
- (m->op == TOKarrayliteral && m->type->ty == Tsarray && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) ||
- (m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements))))
+ if (structlit && isVoid(e))
{
- m = NULL;
+ e = NULL;
}
else
{
- m = scrubReturnValue(loc, m);
- if (CTFEExp::isCantExp(m) || m->op == TOKerror)
- return m;
+ e = scrubReturnValue(loc, e);
+ if (CTFEExp::isCantExp(e) || e->op == TOKerror)
+ return e;
}
- (*elems)[i] = m;
+ (*elems)[i] = e;
}
return NULL;
}
-Expression *scrubArrayCache(Loc loc, Expressions *elems);
+Expression *scrubStructLiteral(Loc loc, StructLiteralExp *sle)
+{
+ sle->ownedByCtfe = OWNEDcode;
+ if (!(sle->stageflags & stageScrub))
+ {
+ const int old = sle->stageflags;
+ sle->stageflags |= stageScrub; // prevent infinite recursion
+ if (Expression *ex = scrubArray(loc, sle->elements, true))
+ return ex;
+ sle->stageflags = old;
+ }
+ return NULL;
+}
-Expression *scrubCacheValue(Loc loc, Expression *e)
+/**************************************
+ * Transitively set all .ownedByCtfe to OWNEDcache
+ */
+Expression *scrubCacheValue(Expression *e)
{
+ if (!e)
+ return e;
+
if (e->op == TOKclassreference)
{
StructLiteralExp *sle = ((ClassReferenceExp*)e)->value;
- sle->ownedByCtfe = OWNEDcache;
- if (!(sle->stageflags & stageScrub))
- {
- int old = sle->stageflags;
- sle->stageflags |= stageScrub;
- if (Expression *ex = scrubArrayCache(loc, sle->elements))
- return ex;
- sle->stageflags = old;
- }
+ if (Expression *ex = scrubStructLiteralCache(sle))
+ return ex;
}
- if (e->op == TOKstructliteral)
+ else if (e->op == TOKstructliteral)
{
StructLiteralExp *sle = (StructLiteralExp *)e;
- sle->ownedByCtfe = OWNEDcache;
- if (!(sle->stageflags & stageScrub))
- {
- int old = sle->stageflags;
- sle->stageflags |= stageScrub;
- if (Expression *ex = scrubArrayCache(loc, sle->elements))
- return ex;
- sle->stageflags = old;
- }
+ if (Expression *ex = scrubStructLiteralCache(sle))
+ return ex;
}
- if (e->op == TOKstring)
+ else if (e->op == TOKstring)
{
((StringExp *)e)->ownedByCtfe = OWNEDcache;
}
- if (e->op == TOKarrayliteral)
+ else if (e->op == TOKarrayliteral)
{
- ((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDcache;
- if (Expression *ex = scrubArrayCache(loc, ((ArrayLiteralExp *)e)->elements))
+ ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
+ ale->ownedByCtfe = OWNEDcache;
+ if (Expression *ex = scrubArrayCache(ale->elements))
return ex;
}
- if (e->op == TOKassocarrayliteral)
+ else if (e->op == TOKassocarrayliteral)
{
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
aae->ownedByCtfe = OWNEDcache;
- if (Expression *ex = scrubArrayCache(loc, aae->keys))
+ if (Expression *ex = scrubArrayCache(aae->keys))
return ex;
- if (Expression *ex = scrubArrayCache(loc, aae->values))
+ if (Expression *ex = scrubArrayCache(aae->values))
return ex;
}
return e;
}
-Expression *scrubArrayCache(Loc loc, Expressions *elems)
+Expression *scrubArrayCache(Expressions *elems)
{
for (size_t i = 0; i < elems->dim; i++)
{
- Expression *m = (*elems)[i];
- if (!m)
- continue;
- (*elems)[i] = scrubCacheValue(loc, m);
+ Expression *e = (*elems)[i];
+ (*elems)[i] = scrubCacheValue(e);
+ }
+ return NULL;
+}
+
+Expression *scrubStructLiteralCache(StructLiteralExp *sle)
+{
+ sle->ownedByCtfe = OWNEDcache;
+ if (!(sle->stageflags & stageScrub))
+ {
+ const int old = sle->stageflags;
+ sle->stageflags |= stageScrub; // prevent infinite recursion
+ if (Expression *ex = scrubArrayCache(sle->elements))
+ return ex;
+ sle->stageflags = old;
}
return NULL;
}
/******************************* Special Functions ***************************/
-Expression *interpret_length(InterState *istate, Expression *earg)
+static Expression *interpret_length(UnionExp *pue, InterState *istate, Expression *earg)
{
//printf("interpret_length()\n");
- earg = interpret(earg, istate);
+ earg = interpret(pue, earg, istate);
if (exceptionOrCantInterpret(earg))
return earg;
dinteger_t len = 0;
@@ -6215,52 +6322,61 @@ Expression *interpret_length(InterState *istate, Expression *earg)
len = ((AssocArrayLiteralExp *)earg)->keys->dim;
else
assert(earg->op == TOKnull);
- Expression *e = new IntegerExp(earg->loc, len, Type::tsize_t);
- return e;
+ new(pue) IntegerExp(earg->loc, len, Type::tsize_t);
+ return pue->exp();
}
-Expression *interpret_keys(InterState *istate, Expression *earg, Type *returnType)
+static Expression *interpret_keys(UnionExp *pue, InterState *istate, Expression *earg, Type *returnType)
{
- earg = interpret(earg, istate);
+ earg = interpret(pue, earg, istate);
if (exceptionOrCantInterpret(earg))
return earg;
if (earg->op == TOKnull)
- return new NullExp(earg->loc, returnType);
+ {
+ new(pue) NullExp(earg->loc, earg->type);
+ return pue->exp();
+ }
if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
return NULL;
assert(earg->op == TOKassocarrayliteral);
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
- ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, aae->keys);
+ ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, returnType, aae->keys);
ae->ownedByCtfe = aae->ownedByCtfe;
- ae->type = returnType;
- return copyLiteral(ae).copy();
+ *pue = copyLiteral(ae);
+ return pue->exp();
}
-Expression *interpret_values(InterState *istate, Expression *earg, Type *returnType)
+static Expression *interpret_values(UnionExp *pue, InterState *istate, Expression *earg, Type *returnType)
{
- earg = interpret(earg, istate);
+ earg = interpret(pue, earg, istate);
if (exceptionOrCantInterpret(earg))
return earg;
if (earg->op == TOKnull)
- return new NullExp(earg->loc, returnType);
+ {
+ new(pue) NullExp(earg->loc, earg->type);
+ return pue->exp();
+ }
if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
return NULL;
assert(earg->op == TOKassocarrayliteral);
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
- ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, aae->values);
+ ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, returnType, aae->values);
ae->ownedByCtfe = aae->ownedByCtfe;
- ae->type = returnType;
//printf("result is %s\n", e->toChars());
- return copyLiteral(ae).copy();
+ *pue = copyLiteral(ae);
+ return pue->exp();
}
-Expression *interpret_dup(InterState *istate, Expression *earg)
+Expression *interpret_dup(UnionExp *pue, InterState *istate, Expression *earg)
{
- earg = interpret(earg, istate);
+ earg = interpret(pue, earg, istate);
if (exceptionOrCantInterpret(earg))
return earg;
if (earg->op == TOKnull)
- return new NullExp(earg->loc, earg->type);
+ {
+ new(pue) NullExp(earg->loc, earg->type);
+ return pue->exp();
+ }
if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
return NULL;
assert(earg->op == TOKassocarrayliteral);
@@ -6278,13 +6394,16 @@ Expression *interpret_dup(InterState *istate, Expression *earg)
}
// signature is int delegate(ref Value) OR int delegate(ref Key, ref Value)
-Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *deleg)
+Expression *interpret_aaApply(UnionExp *pue, InterState *istate, Expression *aa, Expression *deleg)
{
aa = interpret(aa, istate);
if (exceptionOrCantInterpret(aa))
return aa;
if (aa->op != TOKassocarrayliteral)
- return new IntegerExp(deleg->loc, 0, Type::tsize_t);
+ {
+ new(pue) IntegerExp(deleg->loc, 0, Type::tsize_t);
+ return pue->exp();
+ }
FuncDeclaration *fd = NULL;
Expression *pthis = NULL;
@@ -6323,9 +6442,13 @@ Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *de
evalue->type = t;
}
args[numParams - 1] = evalue;
- if (numParams == 2) args[0] = ekey;
+ if (numParams == 2)
+ args[0] = ekey;
- eresult = interpretFunction(fd, istate, &args, pthis);
+ UnionExp ue;
+ eresult = interpretFunction(&ue, fd, istate, &args, pthis);
+ if (eresult == ue.exp())
+ eresult = ue.copy();
if (exceptionOrCantInterpret(eresult))
return eresult;
@@ -6336,19 +6459,10 @@ Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *de
return eresult;
}
-// Helper function: given a function of type A[] f(...),
-// return A[].
-Type *returnedArrayType(FuncDeclaration *fd)
-{
- assert(fd->type->ty == Tfunction);
- assert(fd->type->nextOf()->ty == Tarray);
- return ((TypeFunction *)fd->type)->nextOf();
-}
-
/* Decoding UTF strings for foreach loops. Duplicates the functionality of
* the twelve _aApplyXXn functions in aApply.d in the runtime.
*/
-Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *deleg, bool rvs)
+static Expression *foreachApplyUtf(UnionExp *pue, InterState *istate, Expression *str, Expression *deleg, bool rvs)
{
FuncDeclaration *fd = NULL;
Expression *pthis = NULL;
@@ -6369,7 +6483,10 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
: Type::tsize_t;
size_t len = (size_t)resolveArrayLength(str);
if (len == 0)
- return new IntegerExp(deleg->loc, 0, indexType);
+ {
+ new(pue) IntegerExp(deleg->loc, 0, indexType);
+ return pue->exp();
+ }
str = resolveSlice(str);
@@ -6584,7 +6701,10 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
args[numParams - 1] = val;
- eresult = interpretFunction(fd, istate, &args, pthis);
+ UnionExp ue;
+ eresult = interpretFunction(&ue, fd, istate, &args, pthis);
+ if (eresult == ue.exp())
+ eresult = ue.copy();
if (exceptionOrCantInterpret(eresult))
return eresult;
assert(eresult->op == TOKint64);
@@ -6598,7 +6718,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
/* If this is a built-in function, return the interpreted result,
* Otherwise, return NULL.
*/
-Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
+Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
FuncDeclaration *fd, Expressions *arguments, Expression *pthis)
{
Expression *e = NULL;
@@ -6631,21 +6751,31 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
if (firstarg && firstarg->type->toBasetype()->ty == Taarray)
{
TypeAArray *firstAAtype = (TypeAArray *)firstarg->type;
- const char *id = fd->ident->toChars();
- if (nargs == 1 && fd->ident == Id::aaLen)
- return interpret_length(istate, firstarg);
- if (nargs == 3 && !strcmp(id, "_aaApply"))
- return interpret_aaApply(istate, firstarg, (Expression *)(arguments->data[2]));
- if (nargs == 3 && !strcmp(id, "_aaApply2"))
- return interpret_aaApply(istate, firstarg, (Expression *)(arguments->data[2]));
- if (nargs == 1 && !strcmp(id, "keys") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
- return interpret_keys(istate, firstarg, firstAAtype->index->arrayOf());
- if (nargs == 1 && !strcmp(id, "values") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
- return interpret_values(istate, firstarg, firstAAtype->nextOf()->arrayOf());
- if (nargs == 1 && !strcmp(id, "rehash") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
- return interpret(firstarg, istate);
- if (nargs == 1 && !strcmp(id, "dup") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
- return interpret_dup(istate, firstarg);
+ const Identifier *id = fd->ident;
+ if (nargs == 1)
+ {
+ if (fd->ident == Id::aaLen)
+ return interpret_length(pue, istate, firstarg);
+
+ if (fd->toParent2()->ident == Id::object)
+ {
+ if (id == Id::keys)
+ return interpret_keys(pue, istate, firstarg, firstAAtype->index->arrayOf());
+ if (id == Id::values)
+ return interpret_values(pue, istate, firstarg, firstAAtype->nextOf()->arrayOf());
+ if (id == Id::rehash)
+ return interpret(pue, firstarg, istate);
+ if (id == Id::dup)
+ return interpret_dup(pue, istate, firstarg);
+ }
+ }
+ else // (nargs == 3)
+ {
+ if (id == Id::_aaApply)
+ return interpret_aaApply(pue, istate, firstarg, (Expression *)(arguments->data[2]));
+ if (id == Id::_aaApply2)
+ return interpret_aaApply(pue, istate, firstarg, (Expression *)(arguments->data[2]));
+ }
}
}
if (pthis && !fd->fbody && fd->isCtorDeclaration() && fd->parent && fd->parent->parent && fd->parent->parent->ident == Id::object)
@@ -6693,7 +6823,7 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
str = interpret(str, istate);
if (exceptionOrCantInterpret(str))
return str;
- return foreachApplyUtf(istate, str, (*arguments)[1], rvs);
+ return foreachApplyUtf(pue, istate, str, (*arguments)[1], rvs);
}
}
}
@@ -6723,7 +6853,10 @@ Expression *evaluatePostblit(InterState *istate, Expression *e)
if (e->op == TOKstructliteral)
{
// e.__postblit()
- e = interpretFunction(sd->postblit, istate, NULL, e);
+ UnionExp ue;
+ e = interpretFunction(&ue, sd->postblit, istate, NULL, e);
+ if (e == ue.exp())
+ e = ue.copy();
if (exceptionOrCantInterpret(e))
return e;
return NULL;
@@ -6741,6 +6874,7 @@ Expression *evaluateDtor(InterState *istate, Expression *e)
if (!sd->dtor)
return NULL;
+ UnionExp ue;
if (e->op == TOKarrayliteral)
{
ArrayLiteralExp *alex = (ArrayLiteralExp *)e;
@@ -6750,12 +6884,16 @@ Expression *evaluateDtor(InterState *istate, Expression *e)
else if (e->op == TOKstructliteral)
{
// e.__dtor()
- e = interpretFunction(sd->dtor, istate, NULL, e);
+ e = interpretFunction(&ue, sd->dtor, istate, NULL, e);
}
else
assert(0);
if (exceptionOrCantInterpret(e))
+ {
+ if (e == ue.exp())
+ e = ue.copy();
return e;
+ }
return NULL;
}
diff --git a/gcc/d/dmd/dsymbol.c b/gcc/d/dmd/dsymbol.c
index b7fcf43..4d82d72 100644
--- a/gcc/d/dmd/dsymbol.c
+++ b/gcc/d/dmd/dsymbol.c
@@ -1189,23 +1189,26 @@ void ScopeDsymbol::importScope(Dsymbol *s, Prot protection)
}
}
+#define BITS_PER_INDEX (sizeof(size_t) * CHAR_BIT)
+
static void bitArraySet(BitArray *array, size_t idx)
{
- array->ptr[idx / (sizeof(size_t) * CHAR_BIT)] |= 1ULL << (idx & (sizeof(size_t) * CHAR_BIT - 1));
+ array->ptr[idx / BITS_PER_INDEX] |= 1ULL << (idx % BITS_PER_INDEX);
}
static bool bitArrayGet(BitArray *array, size_t idx)
{
- return (array->ptr[idx / (sizeof(size_t) * CHAR_BIT)] & (1ULL << (idx & (sizeof(size_t) * CHAR_BIT - 1)))) != 0;
+ const size_t boffset = idx % BITS_PER_INDEX;
+ return (array->ptr[idx / BITS_PER_INDEX] & (1ULL << boffset)) >> boffset;
}
static void bitArrayLength(BitArray *array, size_t len)
{
- size_t obytes = (array->len + CHAR_BIT - 1) / CHAR_BIT;
- size_t nbytes = (len + CHAR_BIT - 1) / CHAR_BIT;
-
- if (obytes < nbytes)
+ if (array->len < len)
{
+ const size_t obytes = (array->len + BITS_PER_INDEX - 1) / BITS_PER_INDEX;
+ const size_t nbytes = (len + BITS_PER_INDEX - 1) / BITS_PER_INDEX;
+
if (!array->ptr)
array->ptr = (size_t *)mem.xmalloc(nbytes * sizeof(size_t));
else
@@ -1213,8 +1216,9 @@ static void bitArrayLength(BitArray *array, size_t len)
for (size_t i = obytes; i < nbytes; i++)
array->ptr[i] = 0;
+
+ array->len = nbytes * BITS_PER_INDEX;
}
- array->len = len;
}
void ScopeDsymbol::addAccessiblePackage(Package *p, Prot protection)
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index a1186c9..cbc3819 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -1493,7 +1493,6 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
* is now optimized. See Bugzilla 2356.
*/
Type *tbn = ((TypeArray *)tb)->next;
- Type *tsa = tbn->sarrayOf(nargs - i);
Expressions *elements = new Expressions();
elements->setDim(nargs - i);
@@ -1511,8 +1510,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
(*elements)[u] = a;
}
// Bugzilla 14395: Convert to a static array literal, or its slice.
- arg = new ArrayLiteralExp(loc, elements);
- arg->type = tsa;
+ arg = new ArrayLiteralExp(loc, tbn->sarrayOf(nargs - i), elements);
if (tb->ty == Tarray)
{
arg = new SliceExp(loc, arg, NULL, NULL);
@@ -3741,34 +3739,37 @@ unsigned StringExp::charAt(uinteger_t i) const
// [ e1, e2, e3, ... ]
-ArrayLiteralExp::ArrayLiteralExp(Loc loc, Expressions *elements)
+ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expressions *elements)
: Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
{
this->basis = NULL;
+ this->type = type;
this->elements = elements;
this->ownedByCtfe = OWNEDcode;
}
-ArrayLiteralExp::ArrayLiteralExp(Loc loc, Expression *e)
+ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *e)
: Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
{
this->basis = NULL;
+ this->type = type;
elements = new Expressions;
elements->push(e);
this->ownedByCtfe = OWNEDcode;
}
-ArrayLiteralExp::ArrayLiteralExp(Loc loc, Expression *basis, Expressions *elements)
+ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements)
: Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
{
this->basis = basis;
+ this->type = type;
this->elements = elements;
this->ownedByCtfe = OWNEDcode;
}
ArrayLiteralExp *ArrayLiteralExp::create(Loc loc, Expressions *elements)
{
- return new ArrayLiteralExp(loc, elements);
+ return new ArrayLiteralExp(loc, NULL, elements);
}
bool ArrayLiteralExp::equals(RootObject *o)
@@ -3806,6 +3807,7 @@ bool ArrayLiteralExp::equals(RootObject *o)
Expression *ArrayLiteralExp::syntaxCopy()
{
return new ArrayLiteralExp(loc,
+ NULL,
basis ? basis->syntaxCopy() : NULL,
arraySyntaxCopy(elements));
}
@@ -4082,8 +4084,7 @@ Expression *StructLiteralExp::getField(Type *type, unsigned offset)
z->setDim(length);
for (size_t q = 0; q < length; ++q)
(*z)[q] = e->copy();
- e = new ArrayLiteralExp(loc, z);
- e->type = type;
+ e = new ArrayLiteralExp(loc, type, z);
}
else
{
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 5149082..2dd0b24 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -410,9 +410,9 @@ public:
Expressions *elements;
OwnedBy ownedByCtfe;
- ArrayLiteralExp(Loc loc, Expressions *elements);
- ArrayLiteralExp(Loc loc, Expression *e);
- ArrayLiteralExp(Loc loc, Expression *basis, Expressions *elements);
+ ArrayLiteralExp(Loc loc, Type *type, Expressions *elements);
+ ArrayLiteralExp(Loc loc, Type *type, Expression *e);
+ ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements);
static ArrayLiteralExp *create(Loc loc, Expressions *elements);
Expression *syntaxCopy();
bool equals(RootObject *o);
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index b3274e4..d5319e5 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -6632,8 +6632,7 @@ public:
if (tb2->ty == Tarray || tb2->ty == Tsarray)
{
// Make e2 into [e2]
- exp->e2 = new ArrayLiteralExp(exp->e2->loc, exp->e2);
- exp->e2->type = exp->type;
+ exp->e2 = new ArrayLiteralExp(exp->e2->loc, exp->type, exp->e2);
}
result = exp->optimize(WANTvalue);
return;
@@ -6669,8 +6668,7 @@ public:
if (tb1->ty == Tarray || tb1->ty == Tsarray)
{
// Make e1 into [e1]
- exp->e1 = new ArrayLiteralExp(exp->e1->loc, exp->e1);
- exp->e1->type = exp->type;
+ exp->e1 = new ArrayLiteralExp(exp->e1->loc, exp->type, exp->e1);
}
result = exp->optimize(WANTvalue);
return;
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index d413ded..ec26b2c 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -267,6 +267,9 @@ Msgtable msgtable[] =
{ "_ArrayEq", NULL },
{ "_ArrayPostblit", NULL },
{ "_ArrayDtor", NULL },
+ { "dup", NULL },
+ { "_aaApply", NULL },
+ { "_aaApply2", NULL },
// For pragma's
{ "Pinline", "inline" },
diff --git a/gcc/d/dmd/initsem.c b/gcc/d/dmd/initsem.c
index 7492938..52e26bc 100644
--- a/gcc/d/dmd/initsem.c
+++ b/gcc/d/dmd/initsem.c
@@ -612,7 +612,7 @@ public:
assert((*elements)[i]->op != TOKerror);
}
- Expression *e = new ArrayLiteralExp(init->loc, elements);
+ Expression *e = new ArrayLiteralExp(init->loc, NULL, elements);
ExpInitializer *ei = new ExpInitializer(init->loc, e);
result = inferType(ei, sc);
return;
@@ -857,8 +857,7 @@ public:
elements2->setDim(dim);
for (size_t j = 0; j < dim; j++)
(*elements2)[j] = e;
- e = new ArrayLiteralExp(e->loc, elements2);
- e->type = tn;
+ e = new ArrayLiteralExp(e->loc, tn, elements2);
(*elements)[i] = e;
}
}
@@ -877,8 +876,7 @@ public:
}
}
- Expression *e = new ArrayLiteralExp(init->loc, elements);
- e->type = init->type;
+ Expression *e = new ArrayLiteralExp(init->loc, init->type, elements);
result = e;
return;
}
@@ -902,8 +900,7 @@ public:
elements->setDim(d);
for (size_t i = 0; i < d; i++)
(*elements)[i] = e;
- ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, elements);
- ae->type = itype;
+ ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, itype, elements);
result = ae;
return;
}
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 50a33e5..09161a3 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -2324,16 +2324,11 @@ Identifier *Type::getTypeInfoIdent()
size_t namelen = 19 + sizeof(len) * 3 + len + 1;
char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)mem.xmalloc(namelen);
- sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data);
+ int length = sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data);
//printf("%p, deco = %s, name = %s\n", this, deco, name);
- assert(strlen(name) < namelen); // don't overflow the buffer
+ assert(0 < length && length < namelen); // don't overflow the buffer
- size_t off = 0;
-#ifndef IN_GCC
- if (global.params.isOSX || (global.params.isWindows && !global.params.is64bit))
- ++off; // C mangling will add '_' back in
-#endif
- Identifier *id = Identifier::idPool(name + off);
+ Identifier *id = Identifier::idPool(name, length);
if (name != namebuf)
free(name);
@@ -4340,8 +4335,7 @@ Expression *TypeSArray::defaultInitLiteral(Loc loc)
elements->setDim(d);
for (size_t i = 0; i < d; i++)
(*elements)[i] = NULL;
- ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), elementinit, elements);
- ae->type = this;
+ ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), this, elementinit, elements);
return ae;
}
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index c081e80..171ed14 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -7020,7 +7020,7 @@ Expression *Parser::parsePrimaryExp()
if (keys)
e = new AssocArrayLiteralExp(loc, keys, values);
else
- e = new ArrayLiteralExp(loc, values);
+ e = new ArrayLiteralExp(loc, NULL, values);
break;
}
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index a2d5c9b..1d5f3fc 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -479,8 +479,7 @@ Expression *pointerBitmap(TraitsExp *e)
for (d_uns64 i = 0; i < cntdata; i++)
exps->push(new IntegerExp(e->loc, data[(size_t)i], Type::tsize_t));
- ArrayLiteralExp* ale = new ArrayLiteralExp(e->loc, exps);
- ale->type = Type::tsize_t->sarrayOf(cntdata + 1);
+ ArrayLiteralExp* ale = new ArrayLiteralExp(e->loc, Type::tsize_t->sarrayOf(cntdata + 1), exps);
return ale;
}