1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  * https://github.com/D-Programming-Language/dmd/blob/master/src/interpret.c
9  */
10 
11 #include "root/dsystem.h"               // mem{cpy|set}()
12 #include "root/rmem.h"
13 
14 #include "mars.h"
15 #include "statement.h"
16 #include "expression.h"
17 #include "cond.h"
18 #include "init.h"
19 #include "staticassert.h"
20 #include "mtype.h"
21 #include "scope.h"
22 #include "declaration.h"
23 #include "aggregate.h"
24 #include "id.h"
25 #include "utf.h"
26 #include "attrib.h" // for AttribDeclaration
27 
28 #include "template.h"
29 #include "ctfe.h"
30 
31 /* Interpreter: what form of return value expression is required?
32  */
33 enum CtfeGoal
34 {
35     ctfeNeedRvalue,   // Must return an Rvalue (== CTFE value)
36     ctfeNeedLvalue,   // Must return an Lvalue (== CTFE reference)
37     ctfeNeedNothing   // The return value is not required
38 };
39 
40 bool walkPostorder(Expression *e, StoppableVisitor *v);
41 Expression *interpret(Statement *s, InterState *istate);
42 Expression *interpret(Expression *e, InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
43 Expression *semantic(Expression *e, Scope *sc);
44 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
45 
46 static Expression *interpret(UnionExp *pue, Expression *e, InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
47 static Expression *interpret(UnionExp *pue, Statement *s, InterState *istate);
48 
49 #define SHOWPERFORMANCE 0
50 
51 // Maximum allowable recursive function calls in CTFE
52 #define CTFE_RECURSION_LIMIT 1000
53 
54 /**
55   The values of all CTFE variables
56 */
57 struct CtfeStack
58 {
59 private:
60     /* The stack. Every declaration we encounter is pushed here,
61        together with the VarDeclaration, and the previous
62        stack address of that variable, so that we can restore it
63        when we leave the stack frame.
64        Note that when a function is forward referenced, the interpreter must
65        run semantic3, and that may start CTFE again with a NULL istate. Thus
66        the stack might not be empty when CTFE begins.
67 
68        Ctfe Stack addresses are just 0-based integers, but we save
69        them as 'void *' because Array can only do pointers.
70     */
71     Expressions values;   // values on the stack
72     VarDeclarations vars; // corresponding variables
73     Array<void *> savedId; // id of the previous state of that var
74 
75     Array<void *> frames;  // all previous frame pointers
76     Expressions savedThis;   // all previous values of localThis
77 
78     /* Global constants get saved here after evaluation, so we never
79      * have to redo them. This saves a lot of time and memory.
80      */
81     Expressions globalValues; // values of global constants
82 
83     size_t framepointer;      // current frame pointer
84     size_t maxStackPointer;   // most stack we've ever used
85     Expression *localThis;    // value of 'this', or NULL if none
86 public:
87     CtfeStack();
88 
89     size_t stackPointer();
90 
91     // The current value of 'this', or NULL if none
92     Expression *getThis();
93 
94     // Largest number of stack positions we've used
95     size_t maxStackUsage();
96     // Start a new stack frame, using the provided 'this'.
97     void startFrame(Expression *thisexp);
98     void endFrame();
99     bool isInCurrentFrame(VarDeclaration *v);
100     Expression *getValue(VarDeclaration *v);
101     void setValue(VarDeclaration *v, Expression *e);
102     void push(VarDeclaration *v);
103     void pop(VarDeclaration *v);
104     void popAll(size_t stackpointer);
105     void saveGlobalConstant(VarDeclaration *v, Expression *e);
106 };
107 
108 struct InterState
109 {
110     InterState *caller;         // calling function's InterState
111     FuncDeclaration *fd;        // function being interpreted
112     Statement *start;           // if !=NULL, start execution at this statement
113     /* target of CTFEExp result; also
114      * target of labelled CTFEExp or
115      * CTFEExp. (NULL if no label).
116      */
117     Statement *gotoTarget;
118 
119     InterState();
120 };
121 
122 /************** CtfeStack ********************************************/
123 
124 CtfeStack ctfeStack;
125 
CtfeStack()126 CtfeStack::CtfeStack() : framepointer(0), maxStackPointer(0)
127 {
128 }
129 
stackPointer()130 size_t CtfeStack::stackPointer()
131 {
132     return values.dim;
133 }
134 
getThis()135 Expression *CtfeStack::getThis()
136 {
137     return localThis;
138 }
139 
140 // Largest number of stack positions we've used
maxStackUsage()141 size_t CtfeStack::maxStackUsage()
142 {
143     return maxStackPointer;
144 }
145 
startFrame(Expression * thisexp)146 void CtfeStack::startFrame(Expression *thisexp)
147 {
148     frames.push((void *)(size_t)(framepointer));
149     savedThis.push(localThis);
150     framepointer = stackPointer();
151     localThis = thisexp;
152 }
153 
endFrame()154 void CtfeStack::endFrame()
155 {
156     size_t oldframe = (size_t)(frames[frames.dim-1]);
157     localThis = savedThis[savedThis.dim-1];
158     popAll(framepointer);
159     framepointer = oldframe;
160     frames.setDim(frames.dim - 1);
161     savedThis.setDim(savedThis.dim -1);
162 }
163 
isInCurrentFrame(VarDeclaration * v)164 bool CtfeStack::isInCurrentFrame(VarDeclaration *v)
165 {
166     if (v->isDataseg() && !v->isCTFE())
167         return false;   // It's a global
168     return v->ctfeAdrOnStack >= (int)framepointer;
169 }
170 
getValue(VarDeclaration * v)171 Expression *CtfeStack::getValue(VarDeclaration *v)
172 {
173     if ((v->isDataseg() || v->storage_class & STCmanifest) && !v->isCTFE())
174     {
175         assert(v->ctfeAdrOnStack >= 0 &&
176         v->ctfeAdrOnStack < (int)globalValues.dim);
177         return globalValues[v->ctfeAdrOnStack];
178     }
179     assert(v->ctfeAdrOnStack >= 0 && v->ctfeAdrOnStack < (int)stackPointer());
180     return values[v->ctfeAdrOnStack];
181 }
182 
setValue(VarDeclaration * v,Expression * e)183 void CtfeStack::setValue(VarDeclaration *v, Expression *e)
184 {
185     assert(!v->isDataseg() || v->isCTFE());
186     assert(v->ctfeAdrOnStack >= 0 && v->ctfeAdrOnStack < (int)stackPointer());
187     values[v->ctfeAdrOnStack] = e;
188 }
189 
push(VarDeclaration * v)190 void CtfeStack::push(VarDeclaration *v)
191 {
192     assert(!v->isDataseg() || v->isCTFE());
193     if (v->ctfeAdrOnStack != -1 &&
194         v->ctfeAdrOnStack >= (int)framepointer)
195     {
196         // Already exists in this frame, reuse it.
197         values[v->ctfeAdrOnStack] = NULL;
198         return;
199     }
200     savedId.push((void *)(size_t)(v->ctfeAdrOnStack));
201     v->ctfeAdrOnStack = (int)values.dim;
202     vars.push(v);
203     values.push(NULL);
204 }
205 
pop(VarDeclaration * v)206 void CtfeStack::pop(VarDeclaration *v)
207 {
208     assert(!v->isDataseg() || v->isCTFE());
209     assert(!(v->storage_class & (STCref | STCout)));
210     int oldid = v->ctfeAdrOnStack;
211     v->ctfeAdrOnStack = (int)(size_t)(savedId[oldid]);
212     if (v->ctfeAdrOnStack == (int)values.dim - 1)
213     {
214         values.pop();
215         vars.pop();
216         savedId.pop();
217     }
218 }
219 
popAll(size_t stackpointer)220 void CtfeStack::popAll(size_t stackpointer)
221 {
222     if (stackPointer() > maxStackPointer)
223         maxStackPointer = stackPointer();
224     assert(values.dim >= stackpointer);
225     for (size_t i = stackpointer; i < values.dim; ++i)
226     {
227         VarDeclaration *v = vars[i];
228         v->ctfeAdrOnStack = (int)(size_t)(savedId[i]);
229     }
230     values.setDim(stackpointer);
231     vars.setDim(stackpointer);
232     savedId.setDim(stackpointer);
233 }
234 
saveGlobalConstant(VarDeclaration * v,Expression * e)235 void CtfeStack::saveGlobalConstant(VarDeclaration *v, Expression *e)
236 {
237      assert(v->_init && (v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && !v->isCTFE());
238      v->ctfeAdrOnStack = (int)globalValues.dim;
239      globalValues.push(e);
240 }
241 
242 /************** InterState  ********************************************/
243 
InterState()244 InterState::InterState()
245 {
246     memset(this, 0, sizeof(InterState));
247 }
248 
249 /************** CtfeStatus ********************************************/
250 
251 int CtfeStatus::callDepth = 0;
252 int CtfeStatus::stackTraceCallsToSuppress = 0;
253 int CtfeStatus::maxCallDepth = 0;
254 int CtfeStatus::numArrayAllocs = 0;
255 int CtfeStatus::numAssignments = 0;
256 
257 // CTFE diagnostic information
printCtfePerformanceStats()258 void printCtfePerformanceStats()
259 {
260 #if SHOWPERFORMANCE
261     printf("        ---- CTFE Performance ----\n");
262     printf("max call depth = %d\tmax stack = %d\n", CtfeStatus::maxCallDepth, ctfeStack.maxStackUsage());
263     printf("array allocs = %d\tassignments = %d\n\n", CtfeStatus::numArrayAllocs, CtfeStatus::numAssignments);
264 #endif
265 }
266 
267 static Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
268     FuncDeclaration *fd, Expressions *arguments, Expression *pthis);
269 static Expression *evaluatePostblit(InterState *istate, Expression *e);
270 static Expression *evaluateDtor(InterState *istate, Expression *e);
271 
272 static bool isEntirelyVoid(Expressions* elems);
273 static Expression *scrubArray(Loc loc, Expressions *elems, bool structlit = false);
274 static Expression *scrubStructLiteral(Loc loc, StructLiteralExp *sle);
275 static Expression *scrubReturnValue(Loc loc, Expression *e);
276 static Expression *scrubArrayCache(Expressions *elems);
277 static Expression *scrubStructLiteralCache(StructLiteralExp *sle);
278 static Expression *scrubCacheValue(Expression *e);
279 
280 
281 /*************************************
282  * CTFE-object code for a single function
283  *
284  * Currently only counts the number of local variables in the function
285  */
286 struct CompiledCtfeFunction
287 {
288     FuncDeclaration *func; // Function being compiled, NULL if global scope
289     int numVars;           // Number of variables declared in this function
290     Loc callingloc;
291 
CompiledCtfeFunctionCompiledCtfeFunction292     CompiledCtfeFunction(FuncDeclaration *f)
293     {
294         func = f;
295         numVars = 0;
296     }
297 
onDeclarationCompiledCtfeFunction298     void onDeclaration(VarDeclaration *)
299     {
300         //printf("%s CTFE declare %s\n", v->loc.toChars(), v->toChars());
301         ++numVars;
302     }
303 
onExpressionCompiledCtfeFunction304     void onExpression(Expression *e)
305     {
306         class VarWalker : public StoppableVisitor
307         {
308         public:
309             CompiledCtfeFunction *ccf;
310 
311             VarWalker(CompiledCtfeFunction *ccf)
312                 : ccf(ccf)
313             {
314             }
315 
316             void visit(Expression *)
317             {
318             }
319 
320             void visit(ErrorExp *e)
321             {
322                 // Currently there's a front-end bug: silent errors
323                 // can occur inside delegate literals inside is(typeof()).
324                 // Suppress the check in this case.
325                 if (global.gag && ccf->func)
326                 {
327                     stop = 1;
328                     return;
329                 }
330 
331                 ::error(e->loc, "CTFE internal error: ErrorExp in %s\n", ccf->func ? ccf->func->loc.toChars() : ccf->callingloc.toChars());
332                 assert(0);
333             }
334 
335             void visit(DeclarationExp *e)
336             {
337                 VarDeclaration *v = e->declaration->isVarDeclaration();
338                 if (!v)
339                     return;
340                 TupleDeclaration *td = v->toAlias()->isTupleDeclaration();
341                 if (td)
342                 {
343                     if (!td->objects)
344                         return;
345                     for (size_t i= 0; i < td->objects->dim; ++i)
346                     {
347                         RootObject *o = td->objects->tdata()[i];
348                         Expression *ex = isExpression(o);
349                         DsymbolExp *s = (ex && ex->op == TOKdsymbol) ? (DsymbolExp *)ex : NULL;
350                         assert(s);
351                         VarDeclaration *v2 = s->s->isVarDeclaration();
352                         assert(v2);
353                         if (!v2->isDataseg() || v2->isCTFE())
354                             ccf->onDeclaration(v2);
355                     }
356                 }
357                 else if (!(v->isDataseg() || v->storage_class & STCmanifest) || v->isCTFE())
358                     ccf->onDeclaration(v);
359                 Dsymbol *s = v->toAlias();
360                 if (s == v && !v->isStatic() && v->_init)
361                 {
362                     ExpInitializer *ie = v->_init->isExpInitializer();
363                     if (ie)
364                         ccf->onExpression(ie->exp);
365                 }
366             }
367 
368             void visit(IndexExp *e)
369             {
370                 if (e->lengthVar)
371                     ccf->onDeclaration(e->lengthVar);
372             }
373 
374             void visit(SliceExp *e)
375             {
376                 if (e->lengthVar)
377                     ccf->onDeclaration(e->lengthVar);
378             }
379         };
380 
381         VarWalker v(this);
382         walkPostorder(e, &v);
383     }
384 };
385 
386 class CtfeCompiler : public Visitor
387 {
388 public:
389     CompiledCtfeFunction *ccf;
390 
CtfeCompiler(CompiledCtfeFunction * ccf)391     CtfeCompiler(CompiledCtfeFunction *ccf)
392         : ccf(ccf)
393     {
394     }
395 
visit(Statement *)396     void visit(Statement *)
397     {
398         assert(0);
399     }
400 
visit(ExpStatement * s)401     void visit(ExpStatement *s)
402     {
403         if (s->exp)
404             ccf->onExpression(s->exp);
405     }
406 
visit(CompoundStatement * s)407     void visit(CompoundStatement *s)
408     {
409         for (size_t i = 0; i < s->statements->dim; i++)
410         {
411             Statement *sx = (*s->statements)[i];
412             if (sx)
413                 ctfeCompile(sx);
414         }
415     }
416 
visit(UnrolledLoopStatement * s)417     void visit(UnrolledLoopStatement *s)
418     {
419         for (size_t i = 0; i < s->statements->dim; i++)
420         {
421             Statement *sx = (*s->statements)[i];
422             if (sx)
423                 ctfeCompile(sx);
424         }
425     }
426 
visit(IfStatement * s)427     void visit(IfStatement *s)
428     {
429         ccf->onExpression(s->condition);
430         if (s->ifbody)
431             ctfeCompile(s->ifbody);
432         if (s->elsebody)
433             ctfeCompile(s->elsebody);
434     }
435 
visit(ScopeStatement * s)436     void visit(ScopeStatement *s)
437     {
438         if (s->statement)
439             ctfeCompile(s->statement);
440     }
441 
visit(OnScopeStatement *)442     void visit(OnScopeStatement *)
443     {
444         // rewritten to try/catch/finally
445         assert(0);
446     }
447 
visit(DoStatement * s)448     void visit(DoStatement *s)
449     {
450         ccf->onExpression(s->condition);
451         if (s->_body)
452             ctfeCompile(s->_body);
453     }
454 
visit(WhileStatement *)455     void visit(WhileStatement *)
456     {
457         // rewritten to ForStatement
458         assert(0);
459     }
460 
visit(ForStatement * s)461     void visit(ForStatement *s)
462     {
463         if (s->_init)
464             ctfeCompile(s->_init);
465         if (s->condition)
466             ccf->onExpression(s->condition);
467         if (s->increment)
468             ccf->onExpression(s->increment);
469         if (s->_body)
470             ctfeCompile(s->_body);
471     }
472 
visit(ForeachStatement *)473     void visit(ForeachStatement *)
474     {
475         // rewritten for ForStatement
476         assert(0);
477     }
478 
visit(SwitchStatement * s)479     void visit(SwitchStatement *s)
480     {
481         ccf->onExpression(s->condition);
482         // Note that the body contains the the Case and Default
483         // statements, so we only need to compile the expressions
484         for (size_t i = 0; i < s->cases->dim; i++)
485         {
486             ccf->onExpression((*s->cases)[i]->exp);
487         }
488         if (s->_body)
489             ctfeCompile(s->_body);
490     }
491 
visit(CaseStatement * s)492     void visit(CaseStatement *s)
493     {
494         if (s->statement)
495             ctfeCompile(s->statement);
496     }
497 
visit(DefaultStatement * s)498     void visit(DefaultStatement *s)
499     {
500         if (s->statement)
501             ctfeCompile(s->statement);
502     }
503 
visit(GotoDefaultStatement *)504     void visit(GotoDefaultStatement *)
505     {
506     }
507 
visit(GotoCaseStatement *)508     void visit(GotoCaseStatement *)
509     {
510     }
511 
visit(SwitchErrorStatement *)512     void visit(SwitchErrorStatement *)
513     {
514     }
515 
visit(ReturnStatement * s)516     void visit(ReturnStatement *s)
517     {
518         if (s->exp)
519             ccf->onExpression(s->exp);
520     }
521 
visit(BreakStatement *)522     void visit(BreakStatement *)
523     {
524     }
525 
visit(ContinueStatement *)526     void visit(ContinueStatement *)
527     {
528     }
529 
visit(WithStatement * s)530     void visit(WithStatement *s)
531     {
532         // If it is with(Enum) {...}, just execute the body.
533         if (s->exp->op == TOKscope || s->exp->op == TOKtype)
534         {
535         }
536         else
537         {
538             ccf->onDeclaration(s->wthis);
539             ccf->onExpression(s->exp);
540         }
541         if (s->_body)
542             ctfeCompile(s->_body);
543     }
544 
visit(TryCatchStatement * s)545     void visit(TryCatchStatement *s)
546     {
547         if (s->_body)
548             ctfeCompile(s->_body);
549         for (size_t i = 0; i < s->catches->dim; i++)
550         {
551             Catch *ca = (*s->catches)[i];
552             if (ca->var)
553                 ccf->onDeclaration(ca->var);
554             if (ca->handler)
555                 ctfeCompile(ca->handler);
556         }
557     }
558 
visit(TryFinallyStatement * s)559     void visit(TryFinallyStatement *s)
560     {
561         if (s->_body)
562             ctfeCompile(s->_body);
563         if (s->finalbody)
564             ctfeCompile(s->finalbody);
565     }
566 
visit(ThrowStatement * s)567     void visit(ThrowStatement *s)
568     {
569         ccf->onExpression(s->exp);
570     }
571 
visit(GotoStatement *)572     void visit(GotoStatement *)
573     {
574     }
575 
visit(LabelStatement * s)576     void visit(LabelStatement *s)
577     {
578         if (s->statement)
579             ctfeCompile(s->statement);
580     }
581 
visit(ImportStatement *)582     void visit(ImportStatement *)
583     {
584         // Contains no variables or executable code
585     }
586 
visit(ForeachRangeStatement *)587     void visit(ForeachRangeStatement *)
588     {
589         // rewritten for ForStatement
590         assert(0);
591     }
592 
visit(AsmStatement *)593     void visit(AsmStatement *)
594     {
595         // we can't compile asm statements
596     }
597 
ctfeCompile(Statement * s)598     void ctfeCompile(Statement *s)
599     {
600         s->accept(this);
601     }
602 };
603 
604 /*************************************
605  * Compile this function for CTFE.
606  * At present, this merely allocates variables.
607  */
ctfeCompile(FuncDeclaration * fd)608 void ctfeCompile(FuncDeclaration *fd)
609 {
610     assert(!fd->ctfeCode);
611     assert(!fd->semantic3Errors);
612     assert(fd->semanticRun == PASSsemantic3done);
613 
614     fd->ctfeCode = new CompiledCtfeFunction(fd);
615     if (fd->parameters)
616     {
617         Type *tb = fd->type->toBasetype();
618         assert(tb->ty == Tfunction);
619         for (size_t i = 0; i < fd->parameters->dim; i++)
620         {
621             VarDeclaration *v = (*fd->parameters)[i];
622             fd->ctfeCode->onDeclaration(v);
623         }
624     }
625     if (fd->vresult)
626         fd->ctfeCode->onDeclaration(fd->vresult);
627     CtfeCompiler v(fd->ctfeCode);
628     v.ctfeCompile(fd->fbody);
629 }
630 
631 /*************************************
632  * Entry point for CTFE.
633  * A compile-time result is required. Give an error if not possible.
634  *
635  * `e` must be semantically valid expression. In other words, it should not
636  * contain any `ErrorExp`s in it. But, CTFE interpretation will cross over
637  * functions and may invoke a function that contains `ErrorStatement` in its body.
638  * If that, the "CTFE failed because of previous errors" error is raised.
639  */
ctfeInterpret(Expression * e)640 Expression *ctfeInterpret(Expression *e)
641 {
642     switch (e->op)
643     {
644     case TOKint64:
645     case TOKfloat64:
646     case TOKcomplex80:
647     case TOKnull:
648     case TOKvoid:
649     case TOKstring:
650     case TOKthis:
651     case TOKsuper:
652     case TOKtype:
653     case TOKtypeid:
654     case TOKtemplate:   // non-eponymous template/instance
655     case TOKscope:      // ditto
656     case TOKdottd:      // ditto, e.e1 doesn't matter here
657     case TOKdot:        // ditto
658         if (e->type->ty == Terror)
659             return new ErrorExp();
660         /* fall through */
661 
662     case TOKerror:
663         return e;
664 
665     default:
666         break;
667     }
668 
669     assert(e->type);                    // Bugzilla 14642
670     //assert(e->type->ty != Terror);    // FIXME
671     if (e->type->ty == Terror)
672         return new ErrorExp();
673 
674     // This code is outside a function, but still needs to be compiled
675     // (there are compiler-generated temporary variables such as __dollar).
676     // However, this will only be run once and can then be discarded.
677     CompiledCtfeFunction ctfeCodeGlobal(NULL);
678     ctfeCodeGlobal.callingloc = e->loc;
679     ctfeCodeGlobal.onExpression(e);
680 
681     Expression *result = interpret(e, NULL);
682     if (!CTFEExp::isCantExp(result))
683         result = scrubReturnValue(e->loc, result);
684     if (CTFEExp::isCantExp(result))
685         result = new ErrorExp();
686     return result;
687 }
688 
689 /* Run CTFE on the expression, but allow the expression to be a TypeExp
690  *  or a tuple containing a TypeExp. (This is required by pragma(msg)).
691  */
ctfeInterpretForPragmaMsg(Expression * e)692 Expression *ctfeInterpretForPragmaMsg(Expression *e)
693 {
694     if (e->op == TOKerror || e->op == TOKtype)
695         return e;
696 
697     // It's also OK for it to be a function declaration (happens only with
698     // __traits(getOverloads))
699     if (e->op == TOKvar && ((VarExp *)e)->var->isFuncDeclaration())
700     {
701         return e;
702     }
703 
704     if (e->op != TOKtuple)
705         return e->ctfeInterpret();
706 
707     // Tuples need to be treated seperately, since they are
708     // allowed to contain a TypeExp in this case.
709 
710     TupleExp *tup = (TupleExp *)e;
711     Expressions *expsx = NULL;
712     for (size_t i = 0; i < tup->exps->dim; ++i)
713     {
714         Expression *g = (*tup->exps)[i];
715         Expression *h = g;
716         h = ctfeInterpretForPragmaMsg(g);
717         if (h != g)
718         {
719             if (!expsx)
720             {
721                 expsx = new Expressions();
722                 expsx->setDim(tup->exps->dim);
723                 for (size_t j = 0; j < tup->exps->dim; j++)
724                     (*expsx)[j] = (*tup->exps)[j];
725             }
726             (*expsx)[i] = h;
727         }
728     }
729     if (expsx)
730     {
731         TupleExp *te = new TupleExp(e->loc, expsx);
732         expandTuples(te->exps);
733         te->type = new TypeTuple(te->exps);
734         return te;
735     }
736     return e;
737 }
738 
739 /*************************************
740  * Attempt to interpret a function given the arguments.
741  * Input:
742  *      pue        storage for result
743  *      fd         function being called
744  *      istate     state for calling function (NULL if none)
745  *      arguments  function arguments
746  *      thisarg    'this', if a needThis() function, NULL if not.
747  *
748  * Return result expression if successful, TOKcantexp if not,
749  * or CTFEExp if function returned void.
750  */
751 
interpretFunction(UnionExp * pue,FuncDeclaration * fd,InterState * istate,Expressions * arguments,Expression * thisarg)752 static Expression *interpretFunction(UnionExp *pue, FuncDeclaration *fd, InterState *istate, Expressions *arguments, Expression *thisarg)
753 {
754     assert(pue);
755     if (fd->semanticRun == PASSsemantic3)
756     {
757         fd->error("circular dependency. Functions cannot be interpreted while being compiled");
758         return CTFEExp::cantexp;
759     }
760     if (!fd->functionSemantic3())
761         return CTFEExp::cantexp;
762     if (fd->semanticRun < PASSsemantic3done)
763         return CTFEExp::cantexp;
764 
765     // CTFE-compile the function
766     if (!fd->ctfeCode)
767         ctfeCompile(fd);
768 
769     Type *tb = fd->type->toBasetype();
770     assert(tb->ty == Tfunction);
771     TypeFunction *tf = (TypeFunction *)tb;
772     if (tf->varargs && arguments &&
773         ((fd->parameters && arguments->dim != fd->parameters->dim) || (!fd->parameters && arguments->dim)))
774     {
775         fd->error("C-style variadic functions are not yet implemented in CTFE");
776         return CTFEExp::cantexp;
777     }
778 
779     // Nested functions always inherit the 'this' pointer from the parent,
780     // except for delegates. (Note that the 'this' pointer may be null).
781     // Func literals report isNested() even if they are in global scope,
782     // so we need to check that the parent is a function.
783     if (fd->isNested() && fd->toParent2()->isFuncDeclaration() && !thisarg && istate)
784         thisarg = ctfeStack.getThis();
785 
786     if (fd->needThis() && !thisarg)
787     {
788         // error, no this. Prevent segfault.
789         // Here should be unreachable by the strict 'this' check in front-end.
790         fd->error("need 'this' to access member %s", fd->toChars());
791         return CTFEExp::cantexp;
792     }
793 
794     // Place to hold all the arguments to the function while
795     // we are evaluating them.
796     Expressions eargs;
797     size_t dim = arguments ? arguments->dim : 0;
798     assert((fd->parameters ? fd->parameters->dim : 0) == dim);
799 
800     /* Evaluate all the arguments to the function,
801      * store the results in eargs[]
802      */
803     eargs.setDim(dim);
804     for (size_t i = 0; i < dim; i++)
805     {
806         Expression *earg = (*arguments)[i];
807         Parameter *fparam = Parameter::getNth(tf->parameters, i);
808 
809         if (fparam->storageClass & (STCout | STCref))
810         {
811             if (!istate && (fparam->storageClass & STCout))
812             {
813                 // initializing an out parameter involves writing to it.
814                 earg->error("global %s cannot be passed as an 'out' parameter at compile time", earg->toChars());
815                 return CTFEExp::cantexp;
816             }
817             // Convert all reference arguments into lvalue references
818             earg = interpret(earg, istate, ctfeNeedLvalue);
819             if (CTFEExp::isCantExp(earg))
820                 return earg;
821         }
822         else if (fparam->storageClass & STClazy)
823         {
824         }
825         else
826         {
827             /* Value parameters
828              */
829             Type *ta = fparam->type->toBasetype();
830             if (ta->ty == Tsarray && earg->op == TOKaddress)
831             {
832                 /* Static arrays are passed by a simple pointer.
833                  * Skip past this to get at the actual arg.
834                  */
835                 earg = ((AddrExp *)earg)->e1;
836             }
837             earg = interpret(earg, istate);
838             if (CTFEExp::isCantExp(earg))
839                 return earg;
840             /* Struct literals are passed by value, but we don't need to
841              * copy them if they are passed as const
842              */
843             if (earg->op == TOKstructliteral && !(fparam->storageClass & (STCconst | STCimmutable)))
844                 earg = copyLiteral(earg).copy();
845         }
846         if (earg->op == TOKthrownexception)
847         {
848             if (istate)
849                 return earg;
850             ((ThrownExceptionExp *)earg)->generateUncaughtError();
851             return CTFEExp::cantexp;
852         }
853         eargs[i] = earg;
854     }
855 
856     // Now that we've evaluated all the arguments, we can start the frame
857     // (this is the moment when the 'call' actually takes place).
858     InterState istatex;
859     istatex.caller = istate;
860     istatex.fd = fd;
861     ctfeStack.startFrame(thisarg);
862     if (fd->vthis && thisarg)
863     {
864         ctfeStack.push(fd->vthis);
865         setValue(fd->vthis, thisarg);
866     }
867 
868     for (size_t i = 0; i < dim; i++)
869     {
870         Expression *earg = eargs[i];
871         Parameter *fparam = Parameter::getNth(tf->parameters, i);
872         VarDeclaration *v = (*fd->parameters)[i];
873         ctfeStack.push(v);
874 
875         if ((fparam->storageClass & (STCout | STCref)) &&
876             earg->op == TOKvar && ((VarExp *)earg)->var->toParent2() == fd)
877         {
878             VarDeclaration *vx = ((VarExp *)earg)->var->isVarDeclaration();
879             if (!vx)
880             {
881                 fd->error("cannot interpret %s as a ref parameter", earg->toChars());
882                 return CTFEExp::cantexp;
883             }
884 
885             /* vx is a variable that is declared in fd.
886              * It means that fd is recursively called. e.g.
887              *
888              *  void fd(int n, ref int v = dummy) {
889              *      int vx;
890              *      if (n == 1) fd(2, vx);
891              *  }
892              *  fd(1);
893              *
894              * The old value of vx on the stack in fd(1)
895              * should be saved at the start of fd(2, vx) call.
896              */
897             int oldadr = vx->ctfeAdrOnStack;
898 
899             ctfeStack.push(vx);
900             assert(!hasValue(vx));  // vx is made uninitialized
901 
902             // Bugzilla 14299: v->ctfeAdrOnStack should be saved already
903             // in the stack before the overwrite.
904             v->ctfeAdrOnStack = oldadr;
905             assert(hasValue(v));    // ref parameter v should refer existing value.
906         }
907         else
908         {
909             // Value parameters and non-trivial references
910             setValueWithoutChecking(v, earg);
911         }
912     }
913 
914     if (fd->vresult)
915         ctfeStack.push(fd->vresult);
916 
917     // Enter the function
918     ++CtfeStatus::callDepth;
919     if (CtfeStatus::callDepth > CtfeStatus::maxCallDepth)
920         CtfeStatus::maxCallDepth = CtfeStatus::callDepth;
921 
922     Expression *e = NULL;
923     while (1)
924     {
925         if (CtfeStatus::callDepth > CTFE_RECURSION_LIMIT)
926         {
927             // This is a compiler error. It must not be suppressed.
928             global.gag = 0;
929             fd->error("CTFE recursion limit exceeded");
930             e = CTFEExp::cantexp;
931             break;
932         }
933         e = interpret(pue, fd->fbody, &istatex);
934 
935         if (istatex.start)
936         {
937             fd->error("CTFE internal error: failed to resume at statement %s", istatex.start->toChars());
938             return CTFEExp::cantexp;
939         }
940 
941         /* This is how we deal with a recursive statement AST
942          * that has arbitrary goto statements in it.
943          * Bubble up a 'result' which is the target of the goto
944          * statement, then go recursively down the AST looking
945          * for that statement, then execute starting there.
946          */
947         if (CTFEExp::isGotoExp(e))
948         {
949             istatex.start = istatex.gotoTarget; // set starting statement
950             istatex.gotoTarget = NULL;
951         }
952         else
953         {
954             assert(!e || (e->op != TOKcontinue && e->op != TOKbreak));
955             break;
956         }
957     }
958     // If fell off the end of a void function, return void
959     if (!e && tf->next->ty == Tvoid)
960         e = CTFEExp::voidexp;
961     if (tf->isref && e->op == TOKvar && ((VarExp *)e)->var == fd->vthis)
962         e = thisarg;
963     assert(e != NULL);
964 
965     // Leave the function
966     --CtfeStatus::callDepth;
967 
968     ctfeStack.endFrame();
969 
970     // If it generated an uncaught exception, report error.
971     if (!istate && e->op == TOKthrownexception)
972     {
973         if (e == pue->exp())
974             e = pue->copy();
975         ((ThrownExceptionExp *)e)->generateUncaughtError();
976         e = CTFEExp::cantexp;
977     }
978 
979     return e;
980 }
981 
982 class Interpreter : public Visitor
983 {
984 public:
985     InterState *istate;
986     CtfeGoal goal;
987 
988     Expression *result;
989     UnionExp *pue;              // storage for `result`
990 
Interpreter(UnionExp * pue,InterState * istate,CtfeGoal goal)991     Interpreter(UnionExp *pue, InterState *istate, CtfeGoal goal)
992         : istate(istate), goal(goal), pue(pue)
993     {
994         result = NULL;
995     }
996 
997     // If e is TOKthrowexception or TOKcantexp,
998     // set it to 'result' and returns true.
exceptionOrCant(Expression * e)999     bool exceptionOrCant(Expression *e)
1000     {
1001         if (exceptionOrCantInterpret(e))
1002         {
1003             // Make sure e is not pointing to a stack temporary
1004             result = (e->op == TOKcantexp) ? CTFEExp::cantexp : e;
1005             return true;
1006         }
1007         return false;
1008     }
1009 
copyArrayOnWrite(Expressions * exps,Expressions * original)1010     static Expressions *copyArrayOnWrite(Expressions *exps, Expressions *original)
1011     {
1012         if (exps == original)
1013         {
1014             if (!original)
1015                 exps = new Expressions();
1016             else
1017                 exps = original->copy();
1018             ++CtfeStatus::numArrayAllocs;
1019         }
1020         return exps;
1021     }
1022 
1023     /******************************** Statement ***************************/
1024 
visit(Statement * s)1025     void visit(Statement *s)
1026     {
1027         if (istate->start)
1028         {
1029             if (istate->start != s)
1030                 return;
1031             istate->start = NULL;
1032         }
1033 
1034         s->error("statement %s cannot be interpreted at compile time", s->toChars());
1035         result = CTFEExp::cantexp;
1036     }
1037 
visit(ExpStatement * s)1038     void visit(ExpStatement *s)
1039     {
1040         if (istate->start)
1041         {
1042             if (istate->start != s)
1043                 return;
1044             istate->start = NULL;
1045         }
1046 
1047         Expression *e = interpret(pue, s->exp, istate, ctfeNeedNothing);
1048         if (exceptionOrCant(e))
1049             return;
1050     }
1051 
visit(CompoundStatement * s)1052     void visit(CompoundStatement *s)
1053     {
1054         if (istate->start == s)
1055             istate->start = NULL;
1056 
1057         const size_t dim = s->statements ? s->statements->dim : 0;
1058         for (size_t i = 0; i < dim; i++)
1059         {
1060             Statement *sx = (*s->statements)[i];
1061             result = interpret(pue, sx, istate);
1062             if (result)
1063                 break;
1064         }
1065     }
1066 
visit(UnrolledLoopStatement * s)1067     void visit(UnrolledLoopStatement *s)
1068     {
1069         if (istate->start == s)
1070             istate->start = NULL;
1071 
1072         const size_t dim = s->statements ? s->statements->dim : 0;
1073         for (size_t i = 0; i < dim; i++)
1074         {
1075             Statement *sx = (*s->statements)[i];
1076             Expression *e = interpret(pue, sx, istate);
1077             if (!e)                 // suceeds to interpret, or goto target
1078                 continue;           // was not fonnd when istate->start != NULL
1079             if (exceptionOrCant(e))
1080                 return;
1081             if (e->op == TOKbreak)
1082             {
1083                 if (istate->gotoTarget && istate->gotoTarget != s)
1084                 {
1085                     result = e;     // break at a higher level
1086                     return;
1087                 }
1088                 istate->gotoTarget = NULL;
1089                 result = NULL;
1090                 return;
1091             }
1092             if (e->op == TOKcontinue)
1093             {
1094                 if (istate->gotoTarget && istate->gotoTarget != s)
1095                 {
1096                     result = e;     // continue at a higher level
1097                     return;
1098                 }
1099                 istate->gotoTarget = NULL;
1100                 continue;
1101             }
1102 
1103             // expression from return statement, or thrown exception
1104             result = e;
1105             break;
1106         }
1107     }
1108 
visit(IfStatement * s)1109     void visit(IfStatement *s)
1110     {
1111         if (istate->start == s)
1112             istate->start = NULL;
1113         if (istate->start)
1114         {
1115             Expression *e = NULL;
1116             e = interpret(s->ifbody, istate);
1117             if (!e && istate->start)
1118                 e = interpret(s->elsebody, istate);
1119             result = e;
1120             return;
1121         }
1122 
1123         UnionExp ue;
1124         Expression *e = interpret(&ue, s->condition, istate);
1125         assert(e);
1126         if (exceptionOrCant(e))
1127             return;
1128 
1129         if (isTrueBool(e))
1130             result = interpret(pue, s->ifbody, istate);
1131         else if (e->isBool(false))
1132             result = interpret(pue, s->elsebody, istate);
1133         else
1134         {
1135             // no error, or assert(0)?
1136             result = CTFEExp::cantexp;
1137         }
1138     }
1139 
visit(ScopeStatement * s)1140     void visit(ScopeStatement *s)
1141     {
1142         if (istate->start == s)
1143             istate->start = NULL;
1144 
1145         result = interpret(pue, s->statement, istate);
1146     }
1147 
1148     /**
1149       Given an expression e which is about to be returned from the current
1150       function, generate an error if it contains pointers to local variables.
1151 
1152       Only checks expressions passed by value (pointers to local variables
1153       may already be stored in members of classes, arrays, or AAs which
1154       were passed as mutable function parameters).
1155       Returns:
1156          true if it is safe to return, false if an error was generated.
1157     */
1158 
stopPointersEscaping(Loc loc,Expression * e)1159     static bool stopPointersEscaping(Loc loc, Expression *e)
1160     {
1161         if (!e->type->hasPointers())
1162             return true;
1163         if (isPointer(e->type))
1164         {
1165             Expression *x = e;
1166             if (e->op == TOKaddress)
1167                 x = ((AddrExp *)e)->e1;
1168             VarDeclaration *v;
1169             while (x->op == TOKvar &&
1170                 (v = ((VarExp *)x)->var->isVarDeclaration()) != NULL)
1171             {
1172                 if (v->storage_class & STCref)
1173                 {
1174                     x = getValue(v);
1175                     if (e->op == TOKaddress)
1176                         ((AddrExp *)e)->e1 = x;
1177                     continue;
1178                 }
1179                 if (ctfeStack.isInCurrentFrame(v))
1180                 {
1181                     error(loc, "returning a pointer to a local stack variable");
1182                     return false;
1183                 }
1184                 else
1185                     break;
1186             }
1187             // TODO: If it is a TOKdotvar or TOKindex, we should check that it is not
1188             // pointing to a local struct or static array.
1189         }
1190         if (e->op == TOKstructliteral)
1191         {
1192             StructLiteralExp *se = (StructLiteralExp *)e;
1193             return stopPointersEscapingFromArray(loc, se->elements);
1194         }
1195         if (e->op == TOKarrayliteral)
1196         {
1197             return stopPointersEscapingFromArray(loc, ((ArrayLiteralExp *)e)->elements);
1198         }
1199         if (e->op == TOKassocarrayliteral)
1200         {
1201             AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
1202             if (!stopPointersEscapingFromArray(loc, aae->keys))
1203                 return false;
1204             return stopPointersEscapingFromArray(loc, aae->values);
1205         }
1206         return true;
1207     }
1208 
1209     // Check all members of an array for escaping local variables. Return false if error
stopPointersEscapingFromArray(Loc loc,Expressions * elems)1210     static bool stopPointersEscapingFromArray(Loc loc, Expressions *elems)
1211     {
1212         for (size_t i = 0; i < elems->dim; i++)
1213         {
1214             Expression *m = (*elems)[i];
1215             if (!m)
1216                 continue;
1217             if (!stopPointersEscaping(loc, m))
1218                 return false;
1219         }
1220         return true;
1221     }
1222 
visit(ReturnStatement * s)1223     void visit(ReturnStatement *s)
1224     {
1225         if (istate->start)
1226         {
1227             if (istate->start != s)
1228                 return;
1229             istate->start = NULL;
1230         }
1231 
1232         if (!s->exp)
1233         {
1234             result = CTFEExp::voidexp;
1235             return;
1236         }
1237 
1238         assert(istate && istate->fd && istate->fd->type && istate->fd->type->ty == Tfunction);
1239         TypeFunction *tf = (TypeFunction *)istate->fd->type;
1240 
1241         /* If the function returns a ref AND it's been called from an assignment,
1242          * we need to return an lvalue. Otherwise, just do an (rvalue) interpret.
1243          */
1244         if (tf->isref)
1245         {
1246             result = interpret(pue, s->exp, istate, ctfeNeedLvalue);
1247             return;
1248         }
1249         if (tf->next && tf->next->ty == Tdelegate && istate->fd->closureVars.dim > 0)
1250         {
1251             // To support this, we need to copy all the closure vars
1252             // into the delegate literal.
1253             s->error("closures are not yet supported in CTFE");
1254             result = CTFEExp::cantexp;
1255             return;
1256         }
1257 
1258         // We need to treat pointers specially, because TOKsymoff can be used to
1259         // return a value OR a pointer
1260         Expression *e = interpret(pue, s->exp, istate);
1261         if (exceptionOrCant(e))
1262             return;
1263 
1264         // Disallow returning pointers to stack-allocated variables (bug 7876)
1265         if (!stopPointersEscaping(s->loc, e))
1266         {
1267             result = CTFEExp::cantexp;
1268             return;
1269         }
1270 
1271         if (needToCopyLiteral(e))
1272             e = copyLiteral(e).copy();
1273         result = e;
1274     }
1275 
findGotoTarget(InterState * istate,Identifier * ident)1276     static Statement *findGotoTarget(InterState *istate, Identifier *ident)
1277     {
1278         Statement *target = NULL;
1279         if (ident)
1280         {
1281             LabelDsymbol *label = istate->fd->searchLabel(ident);
1282             assert(label && label->statement);
1283             LabelStatement *ls = label->statement;
1284             target = ls->gotoTarget ? ls->gotoTarget : ls->statement;
1285         }
1286         return target;
1287     }
1288 
visit(BreakStatement * s)1289     void visit(BreakStatement *s)
1290     {
1291         if (istate->start)
1292         {
1293             if (istate->start != s)
1294                 return;
1295             istate->start = NULL;
1296         }
1297 
1298         istate->gotoTarget = findGotoTarget(istate, s->ident);
1299         result = CTFEExp::breakexp;
1300     }
1301 
visit(ContinueStatement * s)1302     void visit(ContinueStatement *s)
1303     {
1304         if (istate->start)
1305         {
1306             if (istate->start != s)
1307                 return;
1308             istate->start = NULL;
1309         }
1310 
1311         istate->gotoTarget = findGotoTarget(istate, s->ident);
1312         result = CTFEExp::continueexp;
1313     }
1314 
visit(WhileStatement *)1315     void visit(WhileStatement *)
1316     {
1317         assert(0);                  // rewritten to ForStatement
1318     }
1319 
visit(DoStatement * s)1320     void visit(DoStatement *s)
1321     {
1322         if (istate->start == s)
1323             istate->start = NULL;
1324 
1325         while (1)
1326         {
1327             Expression *e = interpret(s->_body, istate);
1328             if (!e && istate->start)    // goto target was not found
1329                 return;
1330             assert(!istate->start);
1331 
1332             if (exceptionOrCant(e))
1333                 return;
1334             if (e && e->op == TOKbreak)
1335             {
1336                 if (istate->gotoTarget && istate->gotoTarget != s)
1337                 {
1338                     result = e;     // break at a higher level
1339                     return;
1340                 }
1341                 istate->gotoTarget = NULL;
1342                 break;
1343             }
1344             if (e && e->op == TOKcontinue)
1345             {
1346                 if (istate->gotoTarget && istate->gotoTarget != s)
1347                 {
1348                     result = e;     // continue at a higher level
1349                     return;
1350                 }
1351                 istate->gotoTarget = NULL;
1352                 e = NULL;
1353             }
1354             if (e)
1355             {
1356                 result = e; // bubbled up from ReturnStatement
1357                 return;
1358             }
1359 
1360             UnionExp ue;
1361             e = interpret(&ue, s->condition, istate);
1362             if (exceptionOrCant(e))
1363                 return;
1364             if (!e->isConst())
1365             {
1366                 result = CTFEExp::cantexp;
1367                 return;
1368             }
1369             if (e->isBool(false))
1370                 break;
1371             assert(isTrueBool(e));
1372         }
1373         assert(result == NULL);
1374     }
1375 
visit(ForStatement * s)1376     void visit(ForStatement *s)
1377     {
1378         if (istate->start == s)
1379             istate->start = NULL;
1380 
1381         UnionExp ueinit;
1382         Expression *ei = interpret(&ueinit, s->_init, istate);
1383         if (exceptionOrCant(ei))
1384             return;
1385         assert(!ei); // s->init never returns from function, or jumps out from it
1386 
1387         while (1)
1388         {
1389             if (s->condition && !istate->start)
1390             {
1391                 UnionExp ue;
1392                 Expression *e = interpret(&ue, s->condition, istate);
1393                 if (exceptionOrCant(e))
1394                     return;
1395                 if (e->isBool(false))
1396                     break;
1397                 assert(isTrueBool(e));
1398             }
1399 
1400             Expression *e = interpret(pue, s->_body, istate);
1401             if (!e && istate->start)    // goto target was not found
1402                 return;
1403             assert(!istate->start);
1404 
1405             if (exceptionOrCant(e))
1406                 return;
1407             if (e && e->op == TOKbreak)
1408             {
1409                 if (istate->gotoTarget && istate->gotoTarget != s)
1410                 {
1411                     result = e;     // break at a higher level
1412                     return;
1413                 }
1414                 istate->gotoTarget = NULL;
1415                 break;
1416             }
1417             if (e && e->op == TOKcontinue)
1418             {
1419                 if (istate->gotoTarget && istate->gotoTarget != s)
1420                 {
1421                     result = e;     // continue at a higher level
1422                     return;
1423                 }
1424                 istate->gotoTarget = NULL;
1425                 e = NULL;
1426             }
1427             if (e)
1428             {
1429                 result = e; // bubbled up from ReturnStatement
1430                 return;
1431             }
1432 
1433             UnionExp uei;
1434             e = interpret(&uei, s->increment, istate, ctfeNeedNothing);
1435             if (exceptionOrCant(e))
1436                 return;
1437         }
1438         assert(result == NULL);
1439     }
1440 
visit(ForeachStatement *)1441     void visit(ForeachStatement *)
1442     {
1443         assert(0);                  // rewritten to ForStatement
1444     }
1445 
visit(ForeachRangeStatement *)1446     void visit(ForeachRangeStatement *)
1447     {
1448         assert(0);                  // rewritten to ForStatement
1449     }
1450 
visit(SwitchStatement * s)1451     void visit(SwitchStatement *s)
1452     {
1453         if (istate->start == s)
1454             istate->start = NULL;
1455         if (istate->start)
1456         {
1457             Expression *e = interpret(s->_body, istate);
1458             if (istate->start)      // goto target was not found
1459                 return;
1460             if (exceptionOrCant(e))
1461                 return;
1462             if (e && e->op == TOKbreak)
1463             {
1464                 if (istate->gotoTarget && istate->gotoTarget != s)
1465                 {
1466                     result = e;     // break at a higher level
1467                     return;
1468                 }
1469                 istate->gotoTarget = NULL;
1470                 e = NULL;
1471             }
1472             result = e;
1473             return;
1474         }
1475 
1476         UnionExp uecond;
1477         Expression *econdition = interpret(&uecond, s->condition, istate);
1478         if (exceptionOrCant(econdition))
1479             return;
1480 
1481         Statement *scase = NULL;
1482         size_t dim = s->cases ? s->cases->dim : 0;
1483         for (size_t i = 0; i < dim; i++)
1484         {
1485             CaseStatement *cs = (*s->cases)[i];
1486             UnionExp uecase;
1487             Expression *ecase = interpret(&uecase, cs->exp, istate);
1488             if (exceptionOrCant(ecase))
1489                 return;
1490             if (ctfeEqual(cs->exp->loc, TOKequal, econdition, ecase))
1491             {
1492                 scase = cs;
1493                 break;
1494             }
1495         }
1496         if (!scase)
1497         {
1498             if (s->hasNoDefault)
1499                 s->error("no default or case for %s in switch statement", econdition->toChars());
1500             scase = s->sdefault;
1501         }
1502 
1503         assert(scase);
1504 
1505         /* Jump to scase
1506          */
1507         istate->start = scase;
1508         Expression *e = interpret(pue, s->_body, istate);
1509         assert(!istate->start); // jump must not fail
1510         if (e && e->op == TOKbreak)
1511         {
1512             if (istate->gotoTarget && istate->gotoTarget != s)
1513             {
1514                 result = e;     // break at a higher level
1515                 return;
1516             }
1517             istate->gotoTarget = NULL;
1518             e = NULL;
1519         }
1520         result = e;
1521     }
1522 
visit(CaseStatement * s)1523     void visit(CaseStatement *s)
1524     {
1525         if (istate->start == s)
1526             istate->start = NULL;
1527 
1528         result = interpret(pue, s->statement, istate);
1529     }
1530 
visit(DefaultStatement * s)1531     void visit(DefaultStatement *s)
1532     {
1533         if (istate->start == s)
1534             istate->start = NULL;
1535 
1536         result = interpret(pue, s->statement, istate);
1537     }
1538 
visit(GotoStatement * s)1539     void visit(GotoStatement *s)
1540     {
1541         if (istate->start)
1542         {
1543             if (istate->start != s)
1544                 return;
1545             istate->start = NULL;
1546         }
1547 
1548         assert(s->label && s->label->statement);
1549         istate->gotoTarget = s->label->statement;
1550         result = CTFEExp::gotoexp;
1551     }
1552 
visit(GotoCaseStatement * s)1553     void visit(GotoCaseStatement *s)
1554     {
1555         if (istate->start)
1556         {
1557             if (istate->start != s)
1558                 return;
1559             istate->start = NULL;
1560         }
1561 
1562         assert(s->cs);
1563         istate->gotoTarget = s->cs;
1564         result = CTFEExp::gotoexp;
1565     }
1566 
visit(GotoDefaultStatement * s)1567     void visit(GotoDefaultStatement *s)
1568     {
1569         if (istate->start)
1570         {
1571             if (istate->start != s)
1572                 return;
1573             istate->start = NULL;
1574         }
1575 
1576         assert(s->sw && s->sw->sdefault);
1577         istate->gotoTarget = s->sw->sdefault;
1578         result = CTFEExp::gotoexp;
1579     }
1580 
visit(LabelStatement * s)1581     void visit(LabelStatement *s)
1582     {
1583         if (istate->start == s)
1584             istate->start = NULL;
1585 
1586         result = interpret(pue, s->statement, istate);
1587     }
1588 
visit(TryCatchStatement * s)1589     void visit(TryCatchStatement *s)
1590     {
1591         if (istate->start == s)
1592             istate->start = NULL;
1593         if (istate->start)
1594         {
1595             Expression *e = NULL;
1596             e = interpret(pue, s->_body, istate);
1597             for (size_t i = 0; i < s->catches->dim; i++)
1598             {
1599                 if (e || !istate->start)    // goto target was found
1600                     break;
1601                 Catch *ca = (*s->catches)[i];
1602                 e = interpret(ca->handler, istate);
1603             }
1604             result = e;
1605             return;
1606         }
1607 
1608         Expression *e = interpret(pue, s->_body, istate);
1609 
1610         // An exception was thrown
1611         if (e && e->op == TOKthrownexception)
1612         {
1613             ThrownExceptionExp *ex = (ThrownExceptionExp *)e;
1614             Type *extype = ex->thrown->originalClass()->type;
1615 
1616             // Search for an appropriate catch clause.
1617             for (size_t i = 0; i < s->catches->dim; i++)
1618             {
1619                 Catch *ca = (*s->catches)[i];
1620                 Type *catype = ca->type;
1621                 if (!catype->equals(extype) && !catype->isBaseOf(extype, NULL))
1622                     continue;
1623 
1624                 // Execute the handler
1625                 if (ca->var)
1626                 {
1627                     ctfeStack.push(ca->var);
1628                     setValue(ca->var, ex->thrown);
1629                 }
1630                 e = interpret(ca->handler, istate);
1631                 if (CTFEExp::isGotoExp(e))
1632                 {
1633                     /* This is an optimization that relies on the locality of the jump target.
1634                      * If the label is in the same catch handler, the following scan
1635                      * would find it quickly and can reduce jump cost.
1636                      * Otherwise, the catch block may be unnnecessary scanned again
1637                      * so it would make CTFE speed slower.
1638                      */
1639                     InterState istatex = *istate;
1640                     istatex.start = istate->gotoTarget; // set starting statement
1641                     istatex.gotoTarget = NULL;
1642                     Expression *eh = interpret(ca->handler, &istatex);
1643                     if (!istatex.start)
1644                     {
1645                         istate->gotoTarget = NULL;
1646                         e = eh;
1647                     }
1648                 }
1649                 break;
1650             }
1651         }
1652         result = e;
1653     }
1654 
isAnErrorException(ClassDeclaration * cd)1655     static bool isAnErrorException(ClassDeclaration *cd)
1656     {
1657         return cd == ClassDeclaration::errorException || ClassDeclaration::errorException->isBaseOf(cd, NULL);
1658     }
1659 
chainExceptions(ThrownExceptionExp * oldest,ThrownExceptionExp * newest)1660     static ThrownExceptionExp *chainExceptions(ThrownExceptionExp *oldest, ThrownExceptionExp *newest)
1661     {
1662         // Little sanity check to make sure it's really a Throwable
1663         ClassReferenceExp *boss = oldest->thrown;
1664         const int next = 4;                         // index of Throwable.next
1665         assert((*boss->value->elements)[next]->type->ty == Tclass); // Throwable.next
1666         ClassReferenceExp *collateral = newest->thrown;
1667         if ( isAnErrorException(collateral->originalClass()) &&
1668             !isAnErrorException(boss->originalClass()))
1669         {
1670             /* Find the index of the Error.bypassException field
1671              */
1672             int bypass = next + 1;
1673             if ((*collateral->value->elements)[bypass]->type->ty == Tuns32)
1674                 bypass += 1;  // skip over _refcount field
1675             assert((*collateral->value->elements)[bypass]->type->ty == Tclass);
1676 
1677             // The new exception bypass the existing chain
1678             (*collateral->value->elements)[bypass] = boss;
1679             return newest;
1680         }
1681         while ((*boss->value->elements)[next]->op == TOKclassreference)
1682         {
1683             boss = (ClassReferenceExp *)(*boss->value->elements)[next];
1684         }
1685         (*boss->value->elements)[next] = collateral;
1686         return oldest;
1687     }
1688 
visit(TryFinallyStatement * s)1689     void visit(TryFinallyStatement *s)
1690     {
1691         if (istate->start == s)
1692             istate->start = NULL;
1693         if (istate->start)
1694         {
1695             Expression *e = NULL;
1696             e = interpret(pue, s->_body, istate);
1697             // Jump into/out from finalbody is disabled in semantic analysis.
1698             // and jump inside will be handled by the ScopeStatement == finalbody.
1699             result = e;
1700             return;
1701         }
1702 
1703         Expression *ex = interpret(s->_body, istate);
1704         if (CTFEExp::isCantExp(ex))
1705         {
1706             result = ex;
1707             return;
1708         }
1709         while (CTFEExp::isGotoExp(ex))
1710         {
1711             // If the goto target is within the body, we must not interpret the finally statement,
1712             // because that will call destructors for objects within the scope, which we should not do.
1713             InterState istatex = *istate;
1714             istatex.start = istate->gotoTarget; // set starting statement
1715             istatex.gotoTarget = NULL;
1716             Expression *bex = interpret(s->_body, &istatex);
1717             if (istatex.start)
1718             {
1719               // The goto target is outside the current scope.
1720               break;
1721             }
1722             // The goto target was within the body.
1723             if (CTFEExp::isCantExp(bex))
1724             {
1725                 result = bex;
1726                 return;
1727             }
1728             *istate = istatex;
1729             ex = bex;
1730         }
1731         Expression *ey = interpret(s->finalbody, istate);
1732         if (CTFEExp::isCantExp(ey))
1733         {
1734             result = ey;
1735             return;
1736         }
1737         if (ey && ey->op == TOKthrownexception)
1738         {
1739             // Check for collided exceptions
1740             if (ex && ex->op == TOKthrownexception)
1741                 ex = chainExceptions((ThrownExceptionExp *)ex, (ThrownExceptionExp *)ey);
1742             else
1743                 ex = ey;
1744         }
1745         result = ex;
1746     }
1747 
visit(ThrowStatement * s)1748     void visit(ThrowStatement *s)
1749     {
1750         if (istate->start)
1751         {
1752             if (istate->start != s)
1753                 return;
1754             istate->start = NULL;
1755         }
1756 
1757         Expression *e = interpret(s->exp, istate);
1758         if (exceptionOrCant(e))
1759             return;
1760 
1761         assert(e->op == TOKclassreference);
1762         result = new ThrownExceptionExp(s->loc, (ClassReferenceExp *)e);
1763     }
1764 
visit(OnScopeStatement *)1765     void visit(OnScopeStatement *)
1766     {
1767         assert(0);
1768     }
1769 
visit(WithStatement * s)1770     void visit(WithStatement *s)
1771     {
1772         if (istate->start == s)
1773             istate->start = NULL;
1774         if (istate->start)
1775         {
1776             result = s->_body ? interpret(s->_body, istate) : NULL;
1777             return;
1778         }
1779 
1780         // If it is with(Enum) {...}, just execute the body.
1781         if (s->exp->op == TOKscope || s->exp->op == TOKtype)
1782         {
1783             result = interpret(pue, s->_body, istate);
1784             return;
1785         }
1786 
1787         Expression *e = interpret(s->exp, istate);
1788         if (exceptionOrCant(e))
1789             return;
1790 
1791         if (s->wthis->type->ty == Tpointer && s->exp->type->ty != Tpointer)
1792         {
1793             e = new AddrExp(s->loc, e, s->wthis->type);
1794         }
1795         ctfeStack.push(s->wthis);
1796         setValue(s->wthis, e);
1797         e = interpret(s->_body, istate);
1798         if (CTFEExp::isGotoExp(e))
1799         {
1800             /* This is an optimization that relies on the locality of the jump target.
1801              * If the label is in the same WithStatement, the following scan
1802              * would find it quickly and can reduce jump cost.
1803              * Otherwise, the statement body may be unnnecessary scanned again
1804              * so it would make CTFE speed slower.
1805              */
1806             InterState istatex = *istate;
1807             istatex.start = istate->gotoTarget; // set starting statement
1808             istatex.gotoTarget = NULL;
1809             Expression *ex = interpret(s->_body, &istatex);
1810             if (!istatex.start)
1811             {
1812                 istate->gotoTarget = NULL;
1813                 e = ex;
1814             }
1815         }
1816         ctfeStack.pop(s->wthis);
1817         result = e;
1818     }
1819 
visit(AsmStatement * s)1820     void visit(AsmStatement *s)
1821     {
1822         if (istate->start)
1823         {
1824             if (istate->start != s)
1825                 return;
1826             istate->start = NULL;
1827         }
1828 
1829         s->error("asm statements cannot be interpreted at compile time");
1830         result = CTFEExp::cantexp;
1831     }
1832 
visit(ImportStatement * s)1833     void visit(ImportStatement *s)
1834     {
1835         if (istate->start)
1836         {
1837             if (istate->start != s)
1838                 return;
1839             istate->start = NULL;
1840         }
1841     }
1842 
1843     /******************************** Expression ***************************/
1844 
visit(Expression * e)1845     void visit(Expression *e)
1846     {
1847         e->error("cannot interpret %s at compile time", e->toChars());
1848         result = CTFEExp::cantexp;
1849     }
1850 
visit(ThisExp * e)1851     void visit(ThisExp *e)
1852     {
1853         if (goal == ctfeNeedLvalue)
1854         {
1855             // We might end up here with istate being zero (see bugzilla 16382)
1856             if (istate && istate->fd->vthis)
1857             {
1858                 result = new VarExp(e->loc, istate->fd->vthis);
1859                 result->type = e->type;
1860             }
1861             else
1862                 result = e;
1863             return;
1864         }
1865 
1866         result = ctfeStack.getThis();
1867         if (result)
1868         {
1869             assert(result->op == TOKstructliteral ||
1870                    result->op == TOKclassreference);
1871             return;
1872         }
1873         e->error("value of 'this' is not known at compile time");
1874         result = CTFEExp::cantexp;
1875     }
1876 
visit(NullExp * e)1877     void visit(NullExp *e)
1878     {
1879         result = e;
1880     }
1881 
visit(IntegerExp * e)1882     void visit(IntegerExp *e)
1883     {
1884         result = e;
1885     }
1886 
visit(RealExp * e)1887     void visit(RealExp *e)
1888     {
1889         result = e;
1890     }
1891 
visit(ComplexExp * e)1892     void visit(ComplexExp *e)
1893     {
1894         result = e;
1895     }
1896 
visit(StringExp * e)1897     void visit(StringExp *e)
1898     {
1899         /* Attempts to modify string literals are prevented
1900          * in BinExp::interpretAssignCommon.
1901          */
1902         result = e;
1903     }
1904 
visit(FuncExp * e)1905     void visit(FuncExp *e)
1906     {
1907         result = e;
1908     }
1909 
visit(SymOffExp * e)1910     void visit(SymOffExp *e)
1911     {
1912         if (e->var->isFuncDeclaration() && e->offset == 0)
1913         {
1914             result = e;
1915             return;
1916         }
1917         if (isTypeInfo_Class(e->type) && e->offset == 0)
1918         {
1919             result = e;
1920             return;
1921         }
1922         if (e->type->ty != Tpointer)
1923         {
1924             // Probably impossible
1925             e->error("cannot interpret %s at compile time", e->toChars());
1926             result = CTFEExp::cantexp;
1927             return;
1928         }
1929         Type *pointee = ((TypePointer *)e->type)->next;
1930         if (e->var->isThreadlocal())
1931         {
1932             e->error("cannot take address of thread-local variable %s at compile time", e->var->toChars());
1933             result = CTFEExp::cantexp;
1934             return;
1935         }
1936         // Check for taking an address of a shared variable.
1937         // If the shared variable is an array, the offset might not be zero.
1938         Type *fromType = NULL;
1939         if (e->var->type->ty == Tarray || e->var->type->ty == Tsarray)
1940         {
1941             fromType = ((TypeArray *)(e->var->type))->next;
1942         }
1943         if (e->var->isDataseg() &&
1944             ((e->offset == 0 && isSafePointerCast(e->var->type, pointee)) ||
1945              (fromType && isSafePointerCast(fromType, pointee))))
1946         {
1947             result = e;
1948             return;
1949         }
1950         Expression *val = getVarExp(e->loc, istate, e->var, goal);
1951         if (exceptionOrCant(val))
1952             return;
1953         if (val->type->ty == Tarray || val->type->ty == Tsarray)
1954         {
1955             // Check for unsupported type painting operations
1956             Type *elemtype = ((TypeArray *)(val->type))->next;
1957             d_uns64 elemsize = elemtype->size();
1958 
1959             // It's OK to cast from fixed length to fixed length array, eg &int[n] to int[d]*.
1960             if (val->type->ty == Tsarray && pointee->ty == Tsarray &&
1961                 elemsize == pointee->nextOf()->size())
1962             {
1963                 size_t d = (size_t)((TypeSArray *)pointee)->dim->toInteger();
1964                 Expression *elwr = new IntegerExp(e->loc, e->offset / elemsize,     Type::tsize_t);
1965                 Expression *eupr = new IntegerExp(e->loc, e->offset / elemsize + d, Type::tsize_t);
1966 
1967                 // Create a CTFE pointer &val[ofs..ofs+d]
1968                 SliceExp *se = new SliceExp(e->loc, val, elwr, eupr);
1969                 se->type = pointee;
1970                 new(pue) AddrExp(e->loc, se, e->type);
1971                 result = pue->exp();
1972                 return;
1973             }
1974 
1975             if (!isSafePointerCast(elemtype, pointee))
1976             {
1977                 // It's also OK to cast from &string to string*.
1978                 if (e->offset == 0 && isSafePointerCast(e->var->type, pointee))
1979                 {
1980                     // Create a CTFE pointer &var
1981                     VarExp *ve = new VarExp(e->loc, e->var);
1982                     ve->type = elemtype;
1983                     new(pue) AddrExp(e->loc, ve, e->type);
1984                     result = pue->exp();
1985                     return;
1986                 }
1987                 e->error("reinterpreting cast from %s to %s is not supported in CTFE",
1988                     val->type->toChars(), e->type->toChars());
1989                 result = CTFEExp::cantexp;
1990                 return;
1991             }
1992 
1993             const dinteger_t sz = pointee->size();
1994             dinteger_t indx = e->offset / sz;
1995             assert(sz * indx == e->offset);
1996             Expression *aggregate = NULL;
1997             if (val->op == TOKarrayliteral || val->op == TOKstring)
1998             {
1999                 aggregate = val;
2000             }
2001             else if (val->op == TOKslice)
2002             {
2003                 aggregate = ((SliceExp *)val)->e1;
2004                 UnionExp uelwr;
2005                 Expression *lwr = interpret(&uelwr, ((SliceExp *)val)->lwr, istate);
2006                 indx += lwr->toInteger();
2007             }
2008             if (aggregate)
2009             {
2010                 // Create a CTFE pointer &aggregate[ofs]
2011                 IntegerExp *ofs = new IntegerExp(e->loc, indx, Type::tsize_t);
2012                 IndexExp *ei = new IndexExp(e->loc, aggregate, ofs);
2013                 ei->type = elemtype;
2014                 new(pue) AddrExp(e->loc, ei, e->type);
2015                 result = pue->exp();
2016                 return;
2017             }
2018         }
2019         else if (e->offset == 0 && isSafePointerCast(e->var->type, pointee))
2020         {
2021             // Create a CTFE pointer &var
2022             VarExp *ve = new VarExp(e->loc, e->var);
2023             ve->type = e->var->type;
2024             new(pue) AddrExp(e->loc, ve, e->type);
2025             result = pue->exp();
2026             return;
2027         }
2028 
2029         e->error("cannot convert &%s to %s at compile time", e->var->type->toChars(), e->type->toChars());
2030         result = CTFEExp::cantexp;
2031     }
2032 
visit(AddrExp * e)2033     void visit(AddrExp *e)
2034     {
2035         if (e->e1->op == TOKvar && ((VarExp *)e->e1)->var->isDataseg())
2036         {
2037             // Normally this is already done by optimize()
2038             // Do it here in case optimize(WANTvalue) wasn't run before CTFE
2039             new(pue) SymOffExp(e->loc, ((VarExp *)e->e1)->var, 0);
2040             result = pue->exp();
2041             result->type = e->type;
2042             return;
2043         }
2044         Expression *er = interpret(e->e1, istate, ctfeNeedLvalue);
2045         if (er->op == TOKvar && ((VarExp *)er)->var == istate->fd->vthis)
2046             er = interpret(er, istate);
2047         if (exceptionOrCant(er))
2048             return;
2049 
2050         // Return a simplified address expression
2051         new(pue) AddrExp(e->loc, er, e->type);
2052         result = pue->exp();
2053     }
2054 
visit(DelegateExp * e)2055     void visit(DelegateExp *e)
2056     {
2057         // TODO: Really we should create a CTFE-only delegate expression
2058         // of a pointer and a funcptr.
2059 
2060         // If it is &nestedfunc, just return it
2061         // TODO: We should save the context pointer
2062         if (e->e1->op == TOKvar && ((VarExp *)e->e1)->var == e->func)
2063         {
2064             result = e;
2065             return;
2066         }
2067 
2068         Expression *er = interpret(pue, e->e1, istate);
2069         if (exceptionOrCant(er))
2070             return;
2071         if (er == e->e1)
2072         {
2073             // If it has already been CTFE'd, just return it
2074             result = e;
2075         }
2076         else
2077         {
2078             er = (er == pue->exp()) ? pue->copy() : er;
2079             new(pue) DelegateExp(e->loc, er, e->func, false);
2080             result = pue->exp();
2081             result->type = e->type;
2082         }
2083     }
2084 
getVarExp(Loc loc,InterState * istate,Declaration * d,CtfeGoal goal)2085     static Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal)
2086     {
2087         Expression *e = CTFEExp::cantexp;
2088         if (VarDeclaration *v = d->isVarDeclaration())
2089         {
2090             /* Magic variable __ctfe always returns true when interpreting
2091              */
2092             if (v->ident == Id::ctfe)
2093                 return new IntegerExp(loc, 1, Type::tbool);
2094 
2095             if (!v->originalType && v->semanticRun < PASSsemanticdone) // semantic() not yet run
2096             {
2097                 v->semantic(NULL);
2098                 if (v->type->ty == Terror)
2099                     return CTFEExp::cantexp;
2100             }
2101 
2102             if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) &&
2103                 !hasValue(v) &&
2104                 v->_init && !v->isCTFE())
2105             {
2106                 if (v->inuse)
2107                 {
2108                     error(loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
2109                     return CTFEExp::cantexp;
2110                 }
2111                 if (v->_scope)
2112                 {
2113                     v->inuse++;
2114                     v->_init = ::semantic(v->_init, v->_scope, v->type, INITinterpret); // might not be run on aggregate members
2115                     v->inuse--;
2116                 }
2117                 e = initializerToExpression(v->_init, v->type);
2118                 if (!e)
2119                     return CTFEExp::cantexp;
2120                 assert(e->type);
2121 
2122                 if (e->op == TOKconstruct || e->op == TOKblit)
2123                 {
2124                     AssignExp *ae = (AssignExp *)e;
2125                     e = ae->e2;
2126                 }
2127 
2128                 if (e->op == TOKerror)
2129                 {
2130                     // FIXME: Ultimately all errors should be detected in prior semantic analysis stage.
2131                 }
2132                 else if (v->isDataseg() || (v->storage_class & STCmanifest))
2133                 {
2134                     /* Bugzilla 14304: e is a value that is not yet owned by CTFE.
2135                      * Mark as "cached", and use it directly during interpretation.
2136                      */
2137                     e = scrubCacheValue(e);
2138                     ctfeStack.saveGlobalConstant(v, e);
2139                 }
2140                 else
2141                 {
2142                     v->inuse++;
2143                     e = interpret(e, istate);
2144                     v->inuse--;
2145                     if (CTFEExp::isCantExp(e) && !global.gag && !CtfeStatus::stackTraceCallsToSuppress)
2146                         errorSupplemental(loc, "while evaluating %s.init", v->toChars());
2147                     if (exceptionOrCantInterpret(e))
2148                         return e;
2149                 }
2150             }
2151             else if (v->isCTFE() && !hasValue(v))
2152             {
2153                 if (v->_init && v->type->size() != 0)
2154                 {
2155                     if (v->_init->isVoidInitializer())
2156                     {
2157                         // var should have been initialized when it was created
2158                         error(loc, "CTFE internal error: trying to access uninitialized var");
2159                         assert(0);
2160                         return CTFEExp::cantexp;
2161                     }
2162                     e = initializerToExpression(v->_init);
2163                 }
2164                 else
2165                     e = v->type->defaultInitLiteral(e->loc);
2166 
2167                 e = interpret(e, istate);
2168             }
2169             else if (!(v->isDataseg() || v->storage_class & STCmanifest) && !v->isCTFE() && !istate)
2170             {
2171                 error(loc, "variable %s cannot be read at compile time", v->toChars());
2172                 return CTFEExp::cantexp;
2173             }
2174             else
2175             {
2176                 e = hasValue(v) ? getValue(v) : NULL;
2177                 if (!e && !v->isCTFE() && v->isDataseg())
2178                 {
2179                     error(loc, "static variable %s cannot be read at compile time", v->toChars());
2180                     return CTFEExp::cantexp;
2181                 }
2182                 if (!e)
2183                 {
2184                     assert(!(v->_init && v->_init->isVoidInitializer()));
2185                     // CTFE initiated from inside a function
2186                     error(loc, "variable %s cannot be read at compile time", v->toChars());
2187                     return CTFEExp::cantexp;
2188                 }
2189                 if (e->op == TOKvoid)
2190                 {
2191                     VoidInitExp *ve = (VoidInitExp *)e;
2192                     error(loc, "cannot read uninitialized variable %s in ctfe", v->toPrettyChars());
2193                     errorSupplemental(ve->var->loc, "%s was uninitialized and used before set", ve->var->toChars());
2194                     return CTFEExp::cantexp;
2195                 }
2196                 if (goal != ctfeNeedLvalue && (v->isRef() || v->isOut()))
2197                     e = interpret(e, istate, goal);
2198             }
2199             if (!e)
2200                 e = CTFEExp::cantexp;
2201         }
2202         else if (SymbolDeclaration *s = d->isSymbolDeclaration())
2203         {
2204             // Struct static initializers, for example
2205             e = s->dsym->type->defaultInitLiteral(loc);
2206             if (e->op == TOKerror)
2207                 error(loc, "CTFE failed because of previous errors in %s.init", s->toChars());
2208             e = ::semantic(e, NULL);
2209             if (e->op == TOKerror)
2210                 e = CTFEExp::cantexp;
2211             else // Convert NULL to CTFEExp
2212                 e = interpret(e, istate, goal);
2213         }
2214         else
2215             error(loc, "cannot interpret declaration %s at compile time", d->toChars());
2216         return e;
2217     }
2218 
visit(VarExp * e)2219     void visit(VarExp *e)
2220     {
2221         if (e->var->isFuncDeclaration())
2222         {
2223             result = e;
2224             return;
2225         }
2226 
2227         if (goal == ctfeNeedLvalue)
2228         {
2229             VarDeclaration *v = e->var->isVarDeclaration();
2230             if (v && !v->isDataseg() && !v->isCTFE() && !istate)
2231             {
2232                 e->error("variable %s cannot be read at compile time", v->toChars());
2233                 result = CTFEExp::cantexp;
2234                 return;
2235             }
2236             if (v && !hasValue(v))
2237             {
2238                 if (!v->isCTFE() && v->isDataseg())
2239                     e->error("static variable %s cannot be read at compile time", v->toChars());
2240                 else     // CTFE initiated from inside a function
2241                     e->error("variable %s cannot be read at compile time", v->toChars());
2242                 result = CTFEExp::cantexp;
2243                 return;
2244             }
2245             if (v && (v->storage_class & (STCout | STCref)) && hasValue(v))
2246             {
2247                 // Strip off the nest of ref variables
2248                 Expression *ev = getValue(v);
2249                 if (ev->op == TOKvar || ev->op == TOKindex || ev->op == TOKdotvar)
2250                 {
2251                     result = interpret(pue, ev, istate, goal);
2252                     return;
2253                 }
2254             }
2255             result = e;
2256             return;
2257         }
2258         result = getVarExp(e->loc, istate, e->var, goal);
2259         if (exceptionOrCant(result))
2260             return;
2261         if ((e->var->storage_class & (STCref | STCout)) == 0 &&
2262             e->type->baseElemOf()->ty != Tstruct)
2263         {
2264             /* Ultimately, STCref|STCout check should be enough to see the
2265              * necessity of type repainting. But currently front-end paints
2266              * non-ref struct variables by the const type.
2267              *
2268              *  auto foo(ref const S cs);
2269              *  S s;
2270              *  foo(s); // VarExp('s') will have const(S)
2271              */
2272             // A VarExp may include an implicit cast. It must be done explicitly.
2273             result = paintTypeOntoLiteral(pue, e->type, result);
2274         }
2275     }
2276 
visit(DeclarationExp * e)2277     void visit(DeclarationExp *e)
2278     {
2279         Dsymbol *s = e->declaration;
2280         if (VarDeclaration *v = s->isVarDeclaration())
2281         {
2282             if (TupleDeclaration *td = v->toAlias()->isTupleDeclaration())
2283             {
2284                 result = NULL;
2285 
2286                 // Reserve stack space for all tuple members
2287                 if (!td->objects)
2288                     return;
2289                 for (size_t i = 0; i < td->objects->dim; ++i)
2290                 {
2291                     RootObject * o = (*td->objects)[i];
2292                     Expression *ex = isExpression(o);
2293                     DsymbolExp *ds = (ex && ex->op == TOKdsymbol) ? (DsymbolExp *)ex : NULL;
2294                     VarDeclaration *v2 = ds ? ds->s->isVarDeclaration() : NULL;
2295                     assert(v2);
2296                     if (v2->isDataseg() && !v2->isCTFE())
2297                         continue;
2298 
2299                     ctfeStack.push(v2);
2300                     if (v2->_init)
2301                     {
2302                         Expression *einit;
2303                         if (ExpInitializer *ie = v2->_init->isExpInitializer())
2304                         {
2305                             einit = interpret(ie->exp, istate, goal);
2306                             if (exceptionOrCant(einit))
2307                                 return;
2308                         }
2309                         else if (v2->_init->isVoidInitializer())
2310                         {
2311                             einit = voidInitLiteral(v2->type, v2).copy();
2312                         }
2313                         else
2314                         {
2315                             e->error("declaration %s is not yet implemented in CTFE", e->toChars());
2316                             result = CTFEExp::cantexp;
2317                             return;
2318                         }
2319                         setValue(v2, einit);
2320                     }
2321                 }
2322                 return;
2323             }
2324             if (v->isStatic())
2325             {
2326                 // Just ignore static variables which aren't read or written yet
2327                 result = NULL;
2328                 return;
2329             }
2330             if (!(v->isDataseg() || v->storage_class & STCmanifest) || v->isCTFE())
2331                 ctfeStack.push(v);
2332             if (v->_init)
2333             {
2334                 if (ExpInitializer *ie = v->_init->isExpInitializer())
2335                 {
2336                     result = interpret(ie->exp, istate, goal);
2337                 }
2338                 else if (v->_init->isVoidInitializer())
2339                 {
2340                     result = voidInitLiteral(v->type, v).copy();
2341                     // There is no AssignExp for void initializers,
2342                     // so set it here.
2343                     setValue(v, result);
2344                 }
2345                 else
2346                 {
2347                     e->error("declaration %s is not yet implemented in CTFE", e->toChars());
2348                     result = CTFEExp::cantexp;
2349                 }
2350             }
2351             else if (v->type->size() == 0)
2352             {
2353                 // Zero-length arrays don't need an initializer
2354                 result = v->type->defaultInitLiteral(e->loc);
2355             }
2356             else
2357             {
2358                 e->error("variable %s cannot be modified at compile time", v->toChars());
2359                 result = CTFEExp::cantexp;
2360             }
2361             return;
2362         }
2363         if (s->isAttribDeclaration() ||
2364             s->isTemplateMixin() ||
2365             s->isTupleDeclaration())
2366         {
2367             // Check for static struct declarations, which aren't executable
2368             AttribDeclaration *ad = e->declaration->isAttribDeclaration();
2369             if (ad && ad->decl && ad->decl->dim == 1)
2370             {
2371                 Dsymbol *sparent = (*ad->decl)[0];
2372                 if (sparent->isAggregateDeclaration() ||
2373                     sparent->isTemplateDeclaration() ||
2374                     sparent->isAliasDeclaration())
2375                 {
2376                     result = NULL;
2377                     return;         // static (template) struct declaration. Nothing to do.
2378                 }
2379             }
2380 
2381             // These can be made to work, too lazy now
2382             e->error("declaration %s is not yet implemented in CTFE", e->toChars());
2383             result = CTFEExp::cantexp;
2384             return;
2385         }
2386 
2387         // Others should not contain executable code, so are trivial to evaluate
2388         result = NULL;
2389     }
2390 
visit(TypeidExp * e)2391     void visit(TypeidExp *e)
2392     {
2393         if (isType(e->obj))
2394         {
2395             result = e;
2396             return;
2397         }
2398         if (Expression *ex = isExpression(e->obj))
2399         {
2400             result = interpret(pue, ex, istate);
2401             if (exceptionOrCant(ex))
2402                 return;
2403 
2404             if (result->op == TOKnull)
2405             {
2406                 e->error("null pointer dereference evaluating typeid. '%s' is null", ex->toChars());
2407                 result = CTFEExp::cantexp;
2408                 return;
2409             }
2410             if (result->op != TOKclassreference)
2411             {
2412                 e->error("CTFE internal error: determining classinfo");
2413                 result = CTFEExp::cantexp;
2414                 return;
2415             }
2416 
2417             ClassDeclaration *cd = ((ClassReferenceExp *)result)->originalClass();
2418             assert(cd);
2419 
2420             new(pue) TypeidExp(e->loc, cd->type);
2421             result = pue->exp();
2422             result->type = e->type;
2423             return;
2424         }
2425         visit((Expression *)e);
2426     }
2427 
visit(TupleExp * e)2428     void visit(TupleExp *e)
2429     {
2430         if (exceptionOrCant(interpret(e->e0, istate, ctfeNeedNothing)))
2431             return;
2432 
2433         Expressions *expsx = e->exps;
2434         for (size_t i = 0; i < expsx->dim; i++)
2435         {
2436             Expression *exp = (*expsx)[i];
2437             Expression *ex = interpret(exp, istate);
2438             if (exceptionOrCant(ex))
2439                 return;
2440 
2441             // A tuple of assignments can contain void (Bug 5676).
2442             if (goal == ctfeNeedNothing)
2443                 continue;
2444             if (ex->op == TOKvoidexp)
2445             {
2446                 e->error("CTFE internal error: void element %s in tuple", exp->toChars());
2447                 assert(0);
2448             }
2449 
2450             /* If any changes, do Copy On Write
2451              */
2452             if (ex != exp)
2453             {
2454                 expsx = copyArrayOnWrite(expsx, e->exps);
2455                 (*expsx)[i] = ex;
2456             }
2457         }
2458         if (expsx != e->exps)
2459         {
2460             expandTuples(expsx);
2461             new(pue) TupleExp(e->loc, expsx);
2462             result = pue->exp();
2463             result->type = new TypeTuple(expsx);
2464         }
2465         else
2466             result = e;
2467     }
2468 
visit(ArrayLiteralExp * e)2469     void visit(ArrayLiteralExp *e)
2470     {
2471         if (e->ownedByCtfe >= OWNEDctfe)    // We've already interpreted all the elements
2472         {
2473             result = e;
2474             return;
2475         }
2476 
2477         Type *tn = e->type->toBasetype()->nextOf()->toBasetype();
2478         bool wantCopy = (tn->ty == Tsarray || tn->ty == Tstruct);
2479 
2480         Expression *basis = interpret(e->basis, istate);
2481         if (exceptionOrCant(basis))
2482             return;
2483 
2484         Expressions *expsx = e->elements;
2485         size_t dim = expsx ? expsx->dim : 0;
2486         for (size_t i = 0; i < dim; i++)
2487         {
2488             Expression *exp = (*expsx)[i];
2489             Expression *ex;
2490             if (!exp)
2491             {
2492                 ex = copyLiteral(basis).copy();
2493             }
2494             else
2495             {
2496                 // segfault bug 6250
2497                 assert(exp->op != TOKindex || ((IndexExp *)exp)->e1 != e);
2498 
2499                 ex = interpret(exp, istate);
2500                 if (exceptionOrCant(ex))
2501                     return;
2502 
2503                 /* Each elements should have distinct CFE memory.
2504                  *  int[1] z = 7;
2505                  *  int[1][] pieces = [z,z];    // here
2506                  */
2507                 if (wantCopy)
2508                     ex = copyLiteral(ex).copy();
2509             }
2510 
2511             /* If any changes, do Copy On Write
2512              */
2513             if (ex != exp)
2514             {
2515                 expsx = copyArrayOnWrite(expsx, e->elements);
2516                 (*expsx)[i] = ex;
2517             }
2518         }
2519 
2520         if (expsx != e->elements)
2521         {
2522             // todo: all tuple expansions should go in semantic phase.
2523             expandTuples(expsx);
2524             if (expsx->dim != dim)
2525             {
2526                 e->error("CTFE internal error: invalid array literal");
2527                 result = CTFEExp::cantexp;
2528                 return;
2529             }
2530             new(pue) ArrayLiteralExp(e->loc, e->type, basis, expsx);
2531             ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
2532             ale->ownedByCtfe = OWNEDctfe;
2533             result = ale;
2534         }
2535         else if (((TypeNext *)e->type)->next->mod & (MODconst | MODimmutable))
2536         {
2537             // If it's immutable, we don't need to dup it
2538             result = e;
2539         }
2540         else
2541         {
2542             *pue = copyLiteral(e);
2543             result = pue->exp();
2544         }
2545     }
2546 
visit(AssocArrayLiteralExp * e)2547     void visit(AssocArrayLiteralExp *e)
2548     {
2549         if (e->ownedByCtfe >= OWNEDctfe)    // We've already interpreted all the elements
2550         {
2551             result = e;
2552             return;
2553         }
2554 
2555         Expressions *keysx = e->keys;
2556         Expressions *valuesx = e->values;
2557         for (size_t i = 0; i < keysx->dim; i++)
2558         {
2559             Expression *ekey = (*keysx)[i];
2560             Expression *evalue = (*valuesx)[i];
2561 
2562             Expression *ek = interpret(ekey, istate);
2563             if (exceptionOrCant(ek))
2564                 return;
2565             Expression *ev = interpret(evalue, istate);
2566             if (exceptionOrCant(ev))
2567                 return;
2568 
2569             /* If any changes, do Copy On Write
2570              */
2571             if (ek != ekey ||
2572                 ev != evalue)
2573             {
2574                 keysx = copyArrayOnWrite(keysx, e->keys);
2575                 valuesx = copyArrayOnWrite(valuesx, e->values);
2576                 (*keysx)[i] = ek;
2577                 (*valuesx)[i] = ev;
2578             }
2579         }
2580         if (keysx != e->keys)
2581             expandTuples(keysx);
2582         if (valuesx != e->values)
2583             expandTuples(valuesx);
2584         if (keysx->dim != valuesx->dim)
2585         {
2586             e->error("CTFE internal error: invalid AA");
2587             result = CTFEExp::cantexp;
2588             return;
2589         }
2590 
2591         /* Remove duplicate keys
2592          */
2593         for (size_t i = 1; i < keysx->dim; i++)
2594         {
2595             Expression *ekey = (*keysx)[i - 1];
2596             for (size_t j = i; j < keysx->dim; j++)
2597             {
2598                 Expression *ekey2 = (*keysx)[j];
2599                 if (!ctfeEqual(e->loc, TOKequal, ekey, ekey2))
2600                     continue;
2601 
2602                 // Remove ekey
2603                 keysx = copyArrayOnWrite(keysx, e->keys);
2604                 valuesx = copyArrayOnWrite(valuesx, e->values);
2605                 keysx->remove(i - 1);
2606                 valuesx->remove(i - 1);
2607 
2608                 i -= 1;         // redo the i'th iteration
2609                 break;
2610             }
2611         }
2612 
2613         if (keysx != e->keys ||
2614             valuesx != e->values)
2615         {
2616             assert(keysx != e->keys &&
2617                    valuesx != e->values);
2618             AssocArrayLiteralExp *ae = new AssocArrayLiteralExp(e->loc, keysx, valuesx);
2619             ae->type = e->type;
2620             ae->ownedByCtfe = OWNEDctfe;
2621             result = ae;
2622         }
2623         else
2624         {
2625             *pue = copyLiteral(e);
2626             result = pue->exp();
2627         }
2628     }
2629 
visit(StructLiteralExp * e)2630     void visit(StructLiteralExp *e)
2631     {
2632         if (e->ownedByCtfe >= OWNEDctfe)
2633         {
2634             result = e;
2635             return;
2636         }
2637 
2638         size_t dim = e->elements ? e->elements->dim : 0;
2639         Expressions *expsx = e->elements;
2640 
2641         if (dim != e->sd->fields.dim)
2642         {
2643             // guaranteed by AggregateDeclaration.fill and TypeStruct.defaultInitLiteral
2644             assert(e->sd->isNested() && dim == e->sd->fields.dim - 1);
2645 
2646             /* If a nested struct has no initialized hidden pointer,
2647                 * set it to null to match the runtime behaviour.
2648                  */
2649             NullExp *ne = new NullExp(e->loc);
2650             ne->type = e->sd->vthis->type;
2651 
2652             expsx = copyArrayOnWrite(expsx, e->elements);
2653             expsx->push(ne);
2654             ++dim;
2655         }
2656         assert(dim == e->sd->fields.dim);
2657 
2658         for (size_t i = 0; i < dim; i++)
2659         {
2660             VarDeclaration *v = e->sd->fields[i];
2661             Expression *exp = (*expsx)[i];
2662             Expression *ex = NULL;
2663             if (!exp)
2664             {
2665                 ex = voidInitLiteral(v->type, v).copy();
2666             }
2667             else
2668             {
2669                 ex = interpret(exp, istate);
2670                 if (exceptionOrCant(ex))
2671                     return;
2672                 if ((v->type->ty != ex->type->ty) && v->type->ty == Tsarray)
2673                 {
2674                     // Block assignment from inside struct literals
2675                     TypeSArray *tsa = (TypeSArray *)v->type;
2676                     size_t len = (size_t)tsa->dim->toInteger();
2677                     UnionExp ue;
2678                     ex = createBlockDuplicatedArrayLiteral(&ue, ex->loc, v->type, ex, len);
2679                     if (ex == ue.exp())
2680                         ex = ue.copy();
2681                 }
2682             }
2683 
2684             /* If any changes, do Copy On Write
2685              */
2686             if (ex != exp)
2687             {
2688                 expsx = copyArrayOnWrite(expsx, e->elements);
2689                 (*expsx)[i] = ex;
2690             }
2691         }
2692 
2693         if (expsx != e->elements)
2694         {
2695             expandTuples(expsx);
2696             if (expsx->dim != e->sd->fields.dim)
2697             {
2698                 e->error("CTFE internal error: invalid struct literal");
2699                 result = CTFEExp::cantexp;
2700                 return;
2701             }
2702             new(pue) StructLiteralExp(e->loc, e->sd, expsx);
2703             StructLiteralExp *sle = (StructLiteralExp *)pue->exp();
2704             sle->type = e->type;
2705             sle->ownedByCtfe = OWNEDctfe;
2706             sle->origin = e->origin;
2707             result = sle;
2708         }
2709         else
2710         {
2711             *pue = copyLiteral(e);
2712             result = pue->exp();
2713         }
2714     }
2715 
2716     // Create an array literal of type 'newtype' with dimensions given by
2717     // 'arguments'[argnum..$]
recursivelyCreateArrayLiteral(UnionExp * pue,Loc loc,Type * newtype,InterState * istate,Expressions * arguments,int argnum)2718     static Expression *recursivelyCreateArrayLiteral(UnionExp *pue, Loc loc, Type *newtype, InterState *istate,
2719         Expressions *arguments, int argnum)
2720     {
2721         Expression *lenExpr = interpret(pue, (*arguments)[argnum], istate);
2722         if (exceptionOrCantInterpret(lenExpr))
2723             return lenExpr;
2724         size_t len = (size_t)(lenExpr->toInteger());
2725         Type *elemType = ((TypeArray *)newtype)->next;
2726         if (elemType->ty == Tarray && argnum < (int)arguments->dim - 1)
2727         {
2728             Expression *elem = recursivelyCreateArrayLiteral(pue, loc, elemType, istate,
2729                 arguments, argnum + 1);
2730             if (exceptionOrCantInterpret(elem))
2731                 return elem;
2732 
2733             Expressions *elements = new Expressions();
2734             elements->setDim(len);
2735             for (size_t i = 0; i < len; i++)
2736                  (*elements)[i] = copyLiteral(elem).copy();
2737             new(pue) ArrayLiteralExp(loc, newtype, elements);
2738             ArrayLiteralExp *ae = (ArrayLiteralExp *)pue->exp();
2739             ae->ownedByCtfe = OWNEDctfe;
2740             return ae;
2741         }
2742         assert(argnum == (int)arguments->dim - 1);
2743         if (elemType->ty == Tchar || elemType->ty == Twchar || elemType->ty == Tdchar)
2744         {
2745             const unsigned ch = (unsigned)elemType->defaultInitLiteral(loc)->toInteger();
2746             const unsigned char sz = (unsigned char)elemType->size();
2747             return createBlockDuplicatedStringLiteral(pue, loc, newtype, ch, len, sz);
2748         }
2749         else
2750         {
2751             Expression *el = interpret(elemType->defaultInitLiteral(loc), istate);
2752             return createBlockDuplicatedArrayLiteral(pue, loc, newtype, el, len);
2753         }
2754     }
2755 
visit(NewExp * e)2756     void visit(NewExp *e)
2757     {
2758         if (e->allocator)
2759         {
2760             e->error("member allocators not supported by CTFE");
2761             result = CTFEExp::cantexp;
2762             return;
2763         }
2764 
2765         Expression *epre = interpret(pue, e->argprefix, istate, ctfeNeedNothing);
2766         if (exceptionOrCant(epre))
2767             return;
2768 
2769         if (e->newtype->ty == Tarray && e->arguments)
2770         {
2771             result = recursivelyCreateArrayLiteral(pue, e->loc, e->newtype, istate, e->arguments, 0);
2772             return;
2773         }
2774         if (e->newtype->toBasetype()->ty == Tstruct)
2775         {
2776             if (e->member)
2777             {
2778                 Expression *se = e->newtype->defaultInitLiteral(e->loc);
2779                 se = interpret(se, istate);
2780                 if (exceptionOrCant(se))
2781                     return;
2782                 result = interpretFunction(pue, e->member, istate, e->arguments, se);
2783 
2784                 // Repaint as same as CallExp::interpret() does.
2785                 result->loc = e->loc;
2786             }
2787             else
2788             {
2789                 StructDeclaration *sd = ((TypeStruct *)e->newtype->toBasetype())->sym;
2790                 Expressions *exps = new Expressions();
2791                 exps->reserve(sd->fields.dim);
2792                 if (e->arguments)
2793                 {
2794                     exps->setDim(e->arguments->dim);
2795                     for (size_t i = 0; i < exps->dim; i++)
2796                     {
2797                         Expression *ex = (*e->arguments)[i];
2798                         ex = interpret(ex, istate);
2799                         if (exceptionOrCant(ex))
2800                             return;
2801                         (*exps)[i] = ex;
2802                     }
2803                 }
2804                 sd->fill(e->loc, exps, false);
2805 
2806                 StructLiteralExp *se = new StructLiteralExp(e->loc, sd, exps, e->newtype);
2807                 se->type = e->newtype;
2808                 se->ownedByCtfe = OWNEDctfe;
2809                 result = interpret(pue, se, istate);
2810             }
2811             if (exceptionOrCant(result))
2812                 return;
2813             Expression *ev = (result == pue->exp()) ? pue->copy() : result;
2814             new(pue) AddrExp(e->loc, ev, e->type);
2815             result = pue->exp();
2816             return;
2817         }
2818         if (e->newtype->toBasetype()->ty == Tclass)
2819         {
2820             ClassDeclaration *cd = ((TypeClass *)e->newtype->toBasetype())->sym;
2821             size_t totalFieldCount = 0;
2822             for (ClassDeclaration *c = cd; c; c = c->baseClass)
2823                 totalFieldCount += c->fields.dim;
2824             Expressions *elems = new Expressions;
2825             elems->setDim(totalFieldCount);
2826             size_t fieldsSoFar = totalFieldCount;
2827             for (ClassDeclaration *c = cd; c; c = c->baseClass)
2828             {
2829                 fieldsSoFar -= c->fields.dim;
2830                 for (size_t i = 0; i < c->fields.dim; i++)
2831                 {
2832                     VarDeclaration *v = c->fields[i];
2833                     if (v->inuse)
2834                     {
2835                         e->error("circular reference to '%s'", v->toPrettyChars());
2836                         result = CTFEExp::cantexp;
2837                         return;
2838                     }
2839                     Expression *m;
2840                     if (v->_init)
2841                     {
2842                         if (v->_init->isVoidInitializer())
2843                             m = voidInitLiteral(v->type, v).copy();
2844                         else
2845                             m = v->getConstInitializer(true);
2846                     }
2847                     else
2848                         m = v->type->defaultInitLiteral(e->loc);
2849                     if (exceptionOrCant(m))
2850                         return;
2851                     (*elems)[fieldsSoFar+i] = copyLiteral(m).copy();
2852                 }
2853             }
2854             // Hack: we store a ClassDeclaration instead of a StructDeclaration.
2855             // We probably won't get away with this.
2856             StructLiteralExp *se = new StructLiteralExp(e->loc, (StructDeclaration *)cd, elems, e->newtype);
2857             se->ownedByCtfe = OWNEDctfe;
2858             new(pue) ClassReferenceExp(e->loc, se, e->type);
2859             Expression *eref = pue->exp();
2860             if (e->member)
2861             {
2862                 // Call constructor
2863                 if (!e->member->fbody)
2864                 {
2865                     Expression *ctorfail = evaluateIfBuiltin(pue, istate, e->loc, e->member, e->arguments, eref);
2866                     if (ctorfail)
2867                     {
2868                         if (exceptionOrCant(ctorfail))
2869                             return;
2870                         result = eref;
2871                         return;
2872                     }
2873                     e->member->error("%s cannot be constructed at compile time, because the constructor has no available source code", e->newtype->toChars());
2874                     result = CTFEExp::cantexp;
2875                     return;
2876                 }
2877                 UnionExp ue;
2878                 Expression *ctorfail = interpretFunction(&ue, e->member, istate, e->arguments, eref);
2879                 if (exceptionOrCant(ctorfail))
2880                     return;
2881 
2882                 /* Bugzilla 14465: Repaint the loc, because a super() call
2883                  * in the constructor modifies the loc of ClassReferenceExp
2884                  * in CallExp::interpret().
2885                  */
2886                 eref->loc = e->loc;
2887             }
2888             result = eref;
2889             return;
2890         }
2891         if (e->newtype->toBasetype()->isscalar())
2892         {
2893             Expression *newval;
2894             if (e->arguments && e->arguments->dim)
2895                 newval = (*e->arguments)[0];
2896             else
2897                 newval = e->newtype->defaultInitLiteral(e->loc);
2898             newval = interpret(newval, istate);
2899             if (exceptionOrCant(newval))
2900                 return;
2901 
2902             // Create a CTFE pointer &[newval][0]
2903             Expressions *elements = new Expressions();
2904             elements->setDim(1);
2905             (*elements)[0] = newval;
2906             ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, e->newtype->arrayOf(), elements);
2907             ae->ownedByCtfe = OWNEDctfe;
2908 
2909             IndexExp *ei = new IndexExp(e->loc, ae, new IntegerExp(Loc(), 0, Type::tsize_t));
2910             ei->type = e->newtype;
2911             new(pue) AddrExp(e->loc, ei, e->type);
2912             result = pue->exp();
2913             return;
2914         }
2915         e->error("cannot interpret %s at compile time", e->toChars());
2916         result = CTFEExp::cantexp;
2917     }
2918 
visit(UnaExp * e)2919     void visit(UnaExp *e)
2920     {
2921         UnionExp ue;
2922         Expression *e1 = interpret(&ue, e->e1, istate);
2923         if (exceptionOrCant(e1))
2924             return;
2925         switch (e->op)
2926         {
2927             case TOKneg:    *pue = Neg(e->type, e1);  break;
2928             case TOKtilde:  *pue = Com(e->type, e1);  break;
2929             case TOKnot:    *pue = Not(e->type, e1);  break;
2930             default:        assert(0);
2931         }
2932         result = (*pue).exp();
2933     }
2934 
visit(DotTypeExp * e)2935     void visit(DotTypeExp *e)
2936     {
2937         UnionExp ue;
2938         Expression *e1 = interpret(&ue, e->e1, istate);
2939         if (exceptionOrCant(e1))
2940             return;
2941 
2942         if (e1 == e->e1)
2943             result = e;  // optimize: reuse this CTFE reference
2944         else
2945         {
2946             DotTypeExp *edt = (DotTypeExp *)e->copy();
2947             edt->e1 = (e1 == ue.exp()) ? e1->copy() : e1; // don't return pointer to ue
2948             result = edt;
2949         }
2950     }
2951 
evalOperand(UnionExp * pue,Expression * e,Expression * ex,Expression * & er)2952     bool evalOperand(UnionExp *pue, Expression *e, Expression *ex, Expression *&er)
2953     {
2954         er = interpret(pue, ex, istate);
2955         if (exceptionOrCant(er))
2956             return false;
2957         if (er->isConst() != 1)
2958         {
2959             if (er->op == TOKarrayliteral)
2960                 // Until we get it to work, issue a reasonable error message
2961                 e->error("cannot interpret array literal expression %s at compile time", e->toChars());
2962             else
2963                 e->error("CTFE internal error: non-constant value %s", ex->toChars());
2964             result = CTFEExp::cantexp;
2965             return false;
2966         }
2967         return true;
2968     }
2969 
interpretCommon(BinExp * e,fp_t fp)2970     void interpretCommon(BinExp *e, fp_t fp)
2971     {
2972         if (e->e1->type->ty == Tpointer && e->e2->type->ty == Tpointer && e->op == TOKmin)
2973         {
2974             UnionExp ue1;
2975             Expression *e1 = interpret(&ue1, e->e1, istate);
2976             if (exceptionOrCant(e1))
2977                 return;
2978             UnionExp ue2;
2979             Expression *e2 = interpret(&ue2, e->e2, istate);
2980             if (exceptionOrCant(e2))
2981                 return;
2982             *pue = pointerDifference(e->loc, e->type, e1, e2);
2983             result = (*pue).exp();
2984             return;
2985         }
2986         if (e->e1->type->ty == Tpointer && e->e2->type->isintegral())
2987         {
2988             UnionExp ue1;
2989             Expression *e1 = interpret(&ue1, e->e1, istate);
2990             if (exceptionOrCant(e1))
2991                 return;
2992             UnionExp ue2;
2993             Expression *e2 = interpret(&ue2, e->e2, istate);
2994             if (exceptionOrCant(e2))
2995                 return;
2996             *pue = pointerArithmetic(e->loc, e->op, e->type, e1, e2);
2997             result = (*pue).exp();
2998             return;
2999         }
3000         if (e->e2->type->ty == Tpointer && e->e1->type->isintegral() && e->op == TOKadd)
3001         {
3002             UnionExp ue1;
3003             Expression *e1 = interpret(&ue1, e->e1, istate);
3004             if (exceptionOrCant(e1))
3005                 return;
3006             UnionExp ue2;
3007             Expression *e2 = interpret(&ue2, e->e2, istate);
3008             if (exceptionOrCant(e2))
3009                 return;
3010             *pue = pointerArithmetic(e->loc, e->op, e->type, e2, e1);
3011             result = (*pue).exp();
3012             return;
3013         }
3014         if (e->e1->type->ty == Tpointer || e->e2->type->ty == Tpointer)
3015         {
3016             e->error("pointer expression %s cannot be interpreted at compile time", e->toChars());
3017             result = CTFEExp::cantexp;
3018             return;
3019         }
3020 
3021         UnionExp ue1;
3022         Expression *e1;
3023         if (!evalOperand(&ue1, e, e->e1, e1))
3024             return;
3025         UnionExp ue2;
3026         Expression *e2;
3027         if (!evalOperand(&ue2, e, e->e2, e2))
3028             return;
3029 
3030         if (e->op == TOKshr || e->op == TOKshl || e->op == TOKushr)
3031         {
3032             const sinteger_t i2 = e2->toInteger();
3033             const d_uns64 sz = e1->type->size() * 8;
3034             if (i2 < 0 || (d_uns64)i2 >= sz)
3035             {
3036                 e->error("shift by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1);
3037                 result = CTFEExp::cantexp;
3038                 return;
3039             }
3040         }
3041         *pue = (*fp)(e->loc, e->type, e1, e2);
3042         result = (*pue).exp();
3043         if (CTFEExp::isCantExp(result))
3044             e->error("%s cannot be interpreted at compile time", e->toChars());
3045     }
3046 
interpretCompareCommon(BinExp * e,fp2_t fp)3047     void interpretCompareCommon(BinExp *e, fp2_t fp)
3048     {
3049         UnionExp ue1;
3050         UnionExp ue2;
3051         if (e->e1->type->ty == Tpointer && e->e2->type->ty == Tpointer)
3052         {
3053             Expression *e1 = interpret(&ue1, e->e1, istate);
3054             if (exceptionOrCant(e1))
3055                 return;
3056             Expression *e2 = interpret(&ue2, e->e2, istate);
3057             if (exceptionOrCant(e2))
3058                 return;
3059             //printf("e1 = %s %s, e2 = %s %s\n", e1->type->toChars(), e1->toChars(), e2->type->toChars(), e2->toChars());
3060             dinteger_t ofs1, ofs2;
3061             Expression *agg1 = getAggregateFromPointer(e1, &ofs1);
3062             Expression *agg2 = getAggregateFromPointer(e2, &ofs2);
3063             //printf("agg1 = %p %s, agg2 = %p %s\n", agg1, agg1->toChars(), agg2, agg2->toChars());
3064             const int cmp = comparePointers(e->op, agg1, ofs1, agg2, ofs2);
3065             if (cmp == -1)
3066             {
3067                 char dir = (e->op == TOKgt || e->op == TOKge) ? '<' : '>';
3068                 e->error("the ordering of pointers to unrelated memory blocks is indeterminate in CTFE."
3069                          " To check if they point to the same memory block, use both > and < inside && or ||, "
3070                          "eg (%s && %s %c= %s + 1)",
3071                     e->toChars(), e->e1->toChars(), dir, e->e2->toChars());
3072                 result = CTFEExp::cantexp;
3073                 return;
3074             }
3075             new(pue) IntegerExp(e->loc, cmp, e->type);
3076             result = (*pue).exp();
3077             return;
3078         }
3079         Expression *e1 = interpret(&ue1, e->e1, istate);
3080         if (exceptionOrCant(e1))
3081             return;
3082         if (!isCtfeComparable(e1))
3083         {
3084             e->error("cannot compare %s at compile time", e1->toChars());
3085             result = CTFEExp::cantexp;
3086             return;
3087         }
3088         Expression *e2 = interpret(&ue2, e->e2, istate);
3089         if (exceptionOrCant(e2))
3090             return;
3091         if (!isCtfeComparable(e2))
3092         {
3093             e->error("cannot compare %s at compile time", e2->toChars());
3094             result = CTFEExp::cantexp;
3095             return;
3096         }
3097         const int cmp = (*fp)(e->loc, e->op, e1, e2);
3098         new(pue) IntegerExp(e->loc, cmp, e->type);
3099         result = (*pue).exp();
3100     }
3101 
visit(BinExp * e)3102     void visit(BinExp *e)
3103     {
3104         switch (e->op)
3105         {
3106         case TOKadd:  interpretCommon(e, &Add);     return;
3107         case TOKmin:  interpretCommon(e, &Min);     return;
3108         case TOKmul:  interpretCommon(e, &Mul);     return;
3109         case TOKdiv:  interpretCommon(e, &Div);     return;
3110         case TOKmod:  interpretCommon(e, &Mod);     return;
3111         case TOKshl:  interpretCommon(e, &Shl);     return;
3112         case TOKshr:  interpretCommon(e, &Shr);     return;
3113         case TOKushr: interpretCommon(e, &Ushr);    return;
3114         case TOKand:  interpretCommon(e, &And);     return;
3115         case TOKor:   interpretCommon(e, &Or);      return;
3116         case TOKxor:  interpretCommon(e, &Xor);     return;
3117         case TOKpow:  interpretCommon(e, &Pow);     return;
3118         case TOKequal:
3119         case TOKnotequal:
3120             interpretCompareCommon(e, &ctfeEqual);
3121             return;
3122         case TOKidentity:
3123         case TOKnotidentity:
3124             interpretCompareCommon(e, &ctfeIdentity);
3125             return;
3126         case TOKlt:
3127         case TOKle:
3128         case TOKgt:
3129         case TOKge:
3130             interpretCompareCommon(e, &ctfeCmp);
3131             return;
3132         default:
3133             printf("be = '%s' %s at [%s]\n", Token::toChars(e->op), e->toChars(), e->loc.toChars());
3134             assert(0);
3135             return;
3136         }
3137     }
3138 
3139     /* Helper functions for BinExp::interpretAssignCommon
3140      */
3141 
3142     // Returns the variable which is eventually modified, or NULL if an rvalue.
3143     // thisval is the current value of 'this'.
findParentVar(Expression * e)3144     static VarDeclaration *findParentVar(Expression *e)
3145     {
3146         for (;;)
3147         {
3148             if (e->op == TOKvar)
3149                 break;
3150             if (e->op == TOKindex)
3151                 e = ((IndexExp *)e)->e1;
3152             else if (e->op == TOKdotvar)
3153                 e = ((DotVarExp *)e)->e1;
3154             else if (e->op == TOKdotti)
3155                 e = ((DotTemplateInstanceExp *)e)->e1;
3156             else if (e->op == TOKslice)
3157                 e = ((SliceExp *)e)->e1;
3158             else
3159                 return NULL;
3160         }
3161         VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
3162         assert(v);
3163         return v;
3164     }
3165 
3166     void interpretAssignCommon(BinExp *e, fp_t fp, int post = 0)
3167     {
3168         result = CTFEExp::cantexp;
3169         Expression *e1 = e->e1;
3170         if (!istate)
3171         {
3172             e->error("value of %s is not known at compile time", e1->toChars());
3173             return;
3174         }
3175 
3176         ++CtfeStatus::numAssignments;
3177 
3178         /* Before we begin, we need to know if this is a reference assignment
3179          * (dynamic array, AA, or class) or a value assignment.
3180          * Determining this for slice assignments are tricky: we need to know
3181          * if it is a block assignment (a[] = e) rather than a direct slice
3182          * assignment (a[] = b[]). Note that initializers of multi-dimensional
3183          * static arrays can have 2D block assignments (eg, int[7][7] x = 6;).
3184          * So we need to recurse to determine if it is a block assignment.
3185          */
3186         bool isBlockAssignment = false;
3187         if (e1->op == TOKslice)
3188         {
3189             // a[] = e can have const e. So we compare the naked types.
3190             Type *tdst = e1->type->toBasetype();
3191             Type *tsrc = e->e2->type->toBasetype();
3192             while (tdst->ty == Tsarray || tdst->ty == Tarray)
3193             {
3194                 tdst = ((TypeArray *)tdst)->next->toBasetype();
3195                 if (tsrc->equivalent(tdst))
3196                 {
3197                     isBlockAssignment = true;
3198                     break;
3199                 }
3200             }
3201         }
3202 
3203         // ---------------------------------------
3204         //      Deal with reference assignment
3205         // ---------------------------------------
3206         // If it is a construction of a ref variable, it is a ref assignment
3207         if ((e->op == TOKconstruct || e->op == TOKblit) &&
3208             (((AssignExp *)e)->memset & referenceInit))
3209         {
3210             assert(!fp);
3211 
3212             Expression *newval = interpret(e->e2, istate, ctfeNeedLvalue);
3213             if (exceptionOrCant(newval))
3214                 return;
3215 
3216             VarDeclaration *v = ((VarExp *)e1)->var->isVarDeclaration();
3217             setValue(v, newval);
3218 
3219             // Get the value to return. Note that 'newval' is an Lvalue,
3220             // so if we need an Rvalue, we have to interpret again.
3221             if (goal == ctfeNeedRvalue)
3222                 result = interpret(newval, istate);
3223             else
3224                 result = e1;    // VarExp is a CTFE reference
3225             return;
3226         }
3227 
3228         if (fp)
3229         {
3230             while (e1->op == TOKcast)
3231             {
3232                 CastExp *ce = (CastExp *)e1;
3233                 e1 = ce->e1;
3234             }
3235         }
3236 
3237         // ---------------------------------------
3238         //      Interpret left hand side
3239         // ---------------------------------------
3240         AssocArrayLiteralExp *existingAA = NULL;
3241         Expression *lastIndex = NULL;
3242         Expression *oldval = NULL;
3243         if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
3244         {
3245             // ---------------------------------------
3246             //      Deal with AA index assignment
3247             // ---------------------------------------
3248             /* This needs special treatment if the AA doesn't exist yet.
3249              * There are two special cases:
3250              * (1) If the AA is itself an index of another AA, we may need to create
3251              *     multiple nested AA literals before we can insert the new value.
3252              * (2) If the ultimate AA is null, no insertion happens at all. Instead,
3253              *     we create nested AA literals, and change it into a assignment.
3254              */
3255             IndexExp *ie = (IndexExp *)e1;
3256             int depth = 0;   // how many nested AA indices are there?
3257             while (ie->e1->op == TOKindex &&
3258                    ((IndexExp *)ie->e1)->e1->type->toBasetype()->ty == Taarray)
3259             {
3260                 assert(ie->modifiable);
3261                 ie = (IndexExp *)ie->e1;
3262                 ++depth;
3263             }
3264 
3265             // Get the AA value to be modified.
3266             Expression *aggregate = interpret(ie->e1, istate);
3267             if (exceptionOrCant(aggregate))
3268                 return;
3269             if (aggregate->op == TOKassocarrayliteral)
3270             {
3271                 existingAA = (AssocArrayLiteralExp *)aggregate;
3272 
3273                 // Normal case, ultimate parent AA already exists
3274                 // We need to walk from the deepest index up, checking that an AA literal
3275                 // already exists on each level.
3276                 lastIndex = interpret(((IndexExp *)e1)->e2, istate);
3277                 lastIndex = resolveSlice(lastIndex);    // only happens with AA assignment
3278                 if (exceptionOrCant(lastIndex))
3279                     return;
3280 
3281                 while (depth > 0)
3282                 {
3283                     // Walk the syntax tree to find the indexExp at this depth
3284                     IndexExp *xe = (IndexExp *)e1;
3285                     for (int d= 0; d < depth; ++d)
3286                         xe = (IndexExp *)xe->e1;
3287 
3288                     Expression *ekey = interpret(xe->e2, istate);
3289                     if (exceptionOrCant(ekey))
3290                         return;
3291                     UnionExp ekeyTmp;
3292                     ekey = resolveSlice(ekey, &ekeyTmp);  // only happens with AA assignment
3293 
3294                     // Look up this index in it up in the existing AA, to get the next level of AA.
3295                     AssocArrayLiteralExp *newAA = (AssocArrayLiteralExp *)findKeyInAA(e->loc, existingAA, ekey);
3296                     if (exceptionOrCant(newAA))
3297                         return;
3298                     if (!newAA)
3299                     {
3300                         // Doesn't exist yet, create an empty AA...
3301                         Expressions *keysx = new Expressions();
3302                         Expressions *valuesx = new Expressions();
3303                         newAA = new AssocArrayLiteralExp(e->loc, keysx, valuesx);
3304                         newAA->type = xe->type;
3305                         newAA->ownedByCtfe = OWNEDctfe;
3306                         //... and insert it into the existing AA.
3307                         existingAA->keys->push(ekey);
3308                         existingAA->values->push(newAA);
3309                     }
3310                     existingAA = newAA;
3311                     --depth;
3312                 }
3313 
3314                 if (fp)
3315                 {
3316                     oldval = findKeyInAA(e->loc, existingAA, lastIndex);
3317                     if (!oldval)
3318                         oldval = copyLiteral(e->e1->type->defaultInitLiteral(e->loc)).copy();
3319                 }
3320             }
3321             else
3322             {
3323                 /* The AA is currently null. 'aggregate' is actually a reference to
3324                  * whatever contains it. It could be anything: var, dotvarexp, ...
3325                  * We rewrite the assignment from:
3326                  *     aa[i][j] op= newval;
3327                  * into:
3328                  *     aa = [i:[j:T.init]];
3329                  *     aa[j] op= newval;
3330                  */
3331                 oldval = copyLiteral(e->e1->type->defaultInitLiteral(e->loc)).copy();
3332 
3333                 Expression *newaae = oldval;
3334                 while (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
3335                 {
3336                     Expression *ekey = interpret(((IndexExp *)e1)->e2, istate);
3337                     if (exceptionOrCant(ekey))
3338                         return;
3339                     ekey = resolveSlice(ekey);  // only happens with AA assignment
3340                     Expressions *keysx = new Expressions();
3341                     Expressions *valuesx = new Expressions();
3342                     keysx->push(ekey);
3343                     valuesx->push(newaae);
3344                     AssocArrayLiteralExp *aae = new AssocArrayLiteralExp(e->loc, keysx, valuesx);
3345                     aae->type = ((IndexExp *)e1)->e1->type;
3346                     aae->ownedByCtfe = OWNEDctfe;
3347                     if (!existingAA)
3348                     {
3349                         existingAA = aae;
3350                         lastIndex = ekey;
3351                     }
3352                     newaae = aae;
3353                     e1 = ((IndexExp *)e1)->e1;
3354                 }
3355 
3356                 // We must set to aggregate with newaae
3357                 e1 = interpret(e1, istate, ctfeNeedLvalue);
3358                 if (exceptionOrCant(e1))
3359                     return;
3360                 e1 = assignToLvalue(e, e1, newaae);
3361                 if (exceptionOrCant(e1))
3362                     return;
3363             }
3364             assert(existingAA && lastIndex);
3365             e1 = NULL;  // stomp
3366         }
3367         else if (e1->op == TOKarraylength)
3368         {
3369             oldval = interpret(e1, istate);
3370             if (exceptionOrCant(oldval))
3371                 return;
3372         }
3373         else if (e->op == TOKconstruct || e->op == TOKblit)
3374         {
3375             // Unless we have a simple var assignment, we're
3376             // only modifying part of the variable. So we need to make sure
3377             // that the parent variable exists.
3378             VarDeclaration *ultimateVar = findParentVar(e1);
3379             if (e1->op == TOKvar)
3380             {
3381                 VarDeclaration *v = ((VarExp *)e1)->var->isVarDeclaration();
3382                 assert(v);
3383                 if (v->storage_class & STCout)
3384                     goto L1;
3385             }
3386             else if (ultimateVar && !getValue(ultimateVar))
3387             {
3388                 Expression *ex = interpret(ultimateVar->type->defaultInitLiteral(e->loc), istate);
3389                 if (exceptionOrCant(ex))
3390                     return;
3391                 setValue(ultimateVar, ex);
3392             }
3393             else
3394                 goto L1;
3395         }
3396         else
3397         {
3398         L1:
3399             e1 = interpret(e1, istate, ctfeNeedLvalue);
3400             if (exceptionOrCant(e1))
3401                 return;
3402 
3403             if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
3404             {
3405                 IndexExp *ie = (IndexExp *)e1;
3406                 assert(ie->e1->op == TOKassocarrayliteral);
3407                 existingAA = (AssocArrayLiteralExp *)ie->e1;
3408                 lastIndex = ie->e2;
3409             }
3410         }
3411 
3412         // ---------------------------------------
3413         //      Interpret right hand side
3414         // ---------------------------------------
3415         Expression *newval = interpret(e->e2, istate);
3416         if (exceptionOrCant(newval))
3417             return;
3418         if (e->op == TOKblit && newval->op == TOKint64)
3419         {
3420             Type *tbn = e->type->baseElemOf();
3421             if (tbn->ty == Tstruct)
3422             {
3423                 /* Look for special case of struct being initialized with 0.
3424                  */
3425                 newval = e->type->defaultInitLiteral(e->loc);
3426                 if (newval->op == TOKerror)
3427                 {
3428                     result = CTFEExp::cantexp;
3429                     return;
3430                 }
3431                 newval = interpret(newval, istate); // copy and set ownedByCtfe flag
3432                 if (exceptionOrCant(newval))
3433                     return;
3434             }
3435         }
3436 
3437         // ----------------------------------------------------
3438         //  Deal with read-modify-write assignments.
3439         //  Set 'newval' to the final assignment value
3440         //  Also determine the return value (except for slice
3441         //  assignments, which are more complicated)
3442         // ----------------------------------------------------
3443         if (fp)
3444         {
3445             if (!oldval)
3446             {
3447                 // Load the left hand side after interpreting the right hand side.
3448                 oldval = interpret(e1, istate);
3449                 if (exceptionOrCant(oldval))
3450                     return;
3451             }
3452 
3453             if (e->e1->type->ty != Tpointer)
3454             {
3455                 // ~= can create new values (see bug 6052)
3456                 if (e->op == TOKcatass)
3457                 {
3458                     // We need to dup it and repaint the type. For a dynamic array
3459                     // we can skip duplication, because it gets copied later anyway.
3460                     if (newval->type->ty != Tarray)
3461                     {
3462                         newval = copyLiteral(newval).copy();
3463                         newval->type = e->e2->type; // repaint type
3464                     }
3465                     else
3466                     {
3467                         newval = paintTypeOntoLiteral(e->e2->type, newval);
3468                         newval = resolveSlice(newval);
3469                     }
3470                 }
3471                 oldval = resolveSlice(oldval);
3472 
3473                 newval = (*fp)(e->loc, e->type, oldval, newval).copy();
3474             }
3475             else if (e->e2->type->isintegral() &&
3476                 (e->op == TOKaddass ||
3477                  e->op == TOKminass ||
3478                  e->op == TOKplusplus ||
3479                  e->op == TOKminusminus))
3480             {
3481                 newval = pointerArithmetic(e->loc, e->op, e->type, oldval, newval).copy();
3482             }
3483             else
3484             {
3485                 e->error("pointer expression %s cannot be interpreted at compile time", e->toChars());
3486                 result = CTFEExp::cantexp;
3487                 return;
3488             }
3489             if (exceptionOrCant(newval))
3490             {
3491                 if (CTFEExp::isCantExp(newval))
3492                     e->error("cannot interpret %s at compile time", e->toChars());
3493                 return;
3494             }
3495         }
3496 
3497         if (existingAA)
3498         {
3499             if (existingAA->ownedByCtfe != OWNEDctfe)
3500             {
3501                 e->error("cannot modify read-only constant %s", existingAA->toChars());
3502                 result = CTFEExp::cantexp;
3503                 return;
3504             }
3505 
3506             //printf("\t+L%d existingAA = %s, lastIndex = %s, oldval = %s, newval = %s\n",
3507             //    __LINE__, existingAA->toChars(), lastIndex->toChars(), oldval ? oldval->toChars() : NULL, newval->toChars());
3508             assignAssocArrayElement(e->loc, existingAA, lastIndex, newval);
3509 
3510             // Determine the return value
3511             result = ctfeCast(pue, e->loc, e->type, e->type, fp && post ? oldval : newval);
3512             return;
3513         }
3514         if (e1->op == TOKarraylength)
3515         {
3516             /* Change the assignment from:
3517              *  arr.length = n;
3518              * into:
3519              *  arr = new_length_array; (result is n)
3520              */
3521 
3522             // Determine the return value
3523             result = ctfeCast(pue, e->loc, e->type, e->type, fp && post ? oldval : newval);
3524             if (exceptionOrCant(result))
3525                 return;
3526 
3527             if (result == pue->exp())
3528                 result = pue->copy();
3529 
3530             size_t oldlen = (size_t)oldval->toInteger();
3531             size_t newlen = (size_t)newval->toInteger();
3532             if (oldlen == newlen) // no change required -- we're done!
3533                 return;
3534 
3535             // We have changed it into a reference assignment
3536             // Note that returnValue is still the new length.
3537             e1 = ((ArrayLengthExp *)e1)->e1;
3538             Type *t = e1->type->toBasetype();
3539             if (t->ty != Tarray)
3540             {
3541                 e->error("%s is not yet supported at compile time", e->toChars());
3542                 result = CTFEExp::cantexp;
3543                 return;
3544             }
3545             e1 = interpret(e1, istate, ctfeNeedLvalue);
3546             if (exceptionOrCant(e1))
3547                 return;
3548 
3549             if (oldlen != 0)    // Get the old array literal.
3550                 oldval = interpret(e1, istate);
3551             newval = changeArrayLiteralLength(e->loc, (TypeArray *)t, oldval,
3552                 oldlen,  newlen).copy();
3553 
3554             e1 = assignToLvalue(e, e1, newval);
3555             if (exceptionOrCant(e1))
3556                 return;
3557 
3558             return;
3559         }
3560 
3561         if (!isBlockAssignment)
3562         {
3563             newval = ctfeCast(pue, e->loc, e->type, e->type, newval);
3564             if (exceptionOrCant(newval))
3565                 return;
3566             if (newval == pue->exp())
3567                 newval = pue->copy();
3568 
3569             // Determine the return value
3570             if (goal == ctfeNeedLvalue)     // Bugzilla 14371
3571                 result = e1;
3572             else
3573             {
3574                 result = ctfeCast(pue, e->loc, e->type, e->type, fp && post ? oldval : newval);
3575                 if (result == pue->exp())
3576                     result = pue->copy();
3577             }
3578             if (exceptionOrCant(result))
3579                 return;
3580         }
3581         if (exceptionOrCant(newval))
3582             return;
3583 
3584         /* Block assignment or element-wise assignment.
3585          */
3586         if (e1->op == TOKslice ||
3587             e1->op == TOKvector ||
3588             e1->op == TOKarrayliteral ||
3589             e1->op == TOKstring ||
3590             (e1->op == TOKnull && e1->type->toBasetype()->ty == Tarray))
3591         {
3592             // Note that slice assignments don't support things like ++, so
3593             // we don't need to remember 'returnValue'.
3594             result = interpretAssignToSlice(pue, e, e1, newval, isBlockAssignment);
3595             if (exceptionOrCant(result))
3596                 return;
3597             if (e->e1->op == TOKslice)
3598             {
3599                 Expression *e1x = interpret(((SliceExp*)e->e1)->e1, istate, ctfeNeedLvalue);
3600                 if (e1x->op == TOKdotvar)
3601                 {
3602                     DotVarExp *dve = (DotVarExp*)e1x;
3603                     Expression *ex = dve->e1;
3604                     StructLiteralExp *sle = ex->op == TOKstructliteral  ? ((StructLiteralExp  *)ex)
3605                                           : ex->op == TOKclassreference ? ((ClassReferenceExp *)ex)->value
3606                                           : NULL;
3607                     VarDeclaration *v = dve->var->isVarDeclaration();
3608                     if (!sle || !v)
3609                     {
3610                         e->error("CTFE internal error: dotvar slice assignment");
3611                         result = CTFEExp::cantexp;
3612                         return;
3613                     }
3614                     stompOverlappedFields(sle, v);
3615                 }
3616             }
3617             return;
3618         }
3619 
3620         assert(result);
3621 
3622         /* Assignment to a CTFE reference.
3623          */
3624         if (Expression *ex = assignToLvalue(e, e1, newval))
3625             result = ex;
3626 
3627         return;
3628     }
3629 
3630     /* Set all sibling fields which overlap with v to VoidExp.
3631      */
stompOverlappedFields(StructLiteralExp * sle,VarDeclaration * v)3632     void stompOverlappedFields(StructLiteralExp *sle, VarDeclaration *v)
3633     {
3634         if (!v->overlapped)
3635             return;
3636 
3637         for (size_t i = 0; i < sle->sd->fields.dim; i++)
3638         {
3639             VarDeclaration *v2 = sle->sd->fields[i];
3640             if (v == v2 || !v->isOverlappedWith(v2))
3641                 continue;
3642             Expression *e = (*sle->elements)[i];
3643             if (e->op != TOKvoid)
3644                 (*sle->elements)[i] = voidInitLiteral(e->type, v).copy();
3645         }
3646     }
3647 
assignToLvalue(BinExp * e,Expression * e1,Expression * newval)3648     Expression *assignToLvalue(BinExp *e, Expression *e1, Expression *newval)
3649     {
3650         VarDeclaration *vd = NULL;
3651         Expression **payload = NULL;    // dead-store to prevent spurious warning
3652         Expression *oldval;
3653 
3654         if (e1->op == TOKvar)
3655         {
3656             vd = ((VarExp *)e1)->var->isVarDeclaration();
3657             oldval = getValue(vd);
3658         }
3659         else if (e1->op == TOKdotvar)
3660         {
3661             /* Assignment to member variable of the form:
3662              *  e.v = newval
3663              */
3664             Expression *ex = ((DotVarExp *)e1)->e1;
3665             StructLiteralExp *sle =
3666                 ex->op == TOKstructliteral  ? ((StructLiteralExp  *)ex):
3667                 ex->op == TOKclassreference ? ((ClassReferenceExp *)ex)->value
3668                 : NULL;
3669             VarDeclaration *v = ((DotVarExp *)e1)->var->isVarDeclaration();
3670             if (!sle || !v)
3671             {
3672                 e->error("CTFE internal error: dotvar assignment");
3673                 return CTFEExp::cantexp;
3674             }
3675             if (sle->ownedByCtfe != OWNEDctfe)
3676             {
3677                 e->error("cannot modify read-only constant %s", sle->toChars());
3678                 return CTFEExp::cantexp;
3679             }
3680 
3681             int fieldi = ex->op == TOKstructliteral
3682                 ? findFieldIndexByName(sle->sd, v)
3683                 : ((ClassReferenceExp *)ex)->findFieldIndexByName(v);
3684             if (fieldi == -1)
3685             {
3686                 e->error("CTFE internal error: cannot find field %s in %s", v->toChars(), ex->toChars());
3687                 return CTFEExp::cantexp;
3688             }
3689             assert(0 <= fieldi && fieldi < (int)sle->elements->dim);
3690 
3691             // If it's a union, set all other members of this union to void
3692             stompOverlappedFields(sle, v);
3693 
3694             payload = &(*sle->elements)[fieldi];
3695             oldval = *payload;
3696         }
3697         else if (e1->op == TOKindex)
3698         {
3699             IndexExp *ie = (IndexExp *)e1;
3700             assert(ie->e1->type->toBasetype()->ty != Taarray);
3701 
3702             Expression *aggregate;
3703             uinteger_t indexToModify;
3704             if (!resolveIndexing(ie, istate, &aggregate, &indexToModify, true))
3705             {
3706                 return CTFEExp::cantexp;
3707             }
3708             size_t index = (size_t)indexToModify;
3709 
3710             if (aggregate->op == TOKstring)
3711             {
3712                 StringExp *existingSE = (StringExp *)aggregate;
3713                 if (existingSE->ownedByCtfe != OWNEDctfe)
3714                 {
3715                     e->error("cannot modify read-only string literal %s", ie->e1->toChars());
3716                     return CTFEExp::cantexp;
3717                 }
3718                 void *s = existingSE->string;
3719                 dinteger_t value = newval->toInteger();
3720                 switch (existingSE->sz)
3721                 {
3722                     case 1:     (( utf8_t *)s)[index] = ( utf8_t)value; break;
3723                     case 2:     ((utf16_t *)s)[index] = (utf16_t)value; break;
3724                     case 4:     ((utf32_t *)s)[index] = (utf32_t)value; break;
3725                     default:    assert(0);                              break;
3726                 }
3727                 return NULL;
3728             }
3729             if (aggregate->op != TOKarrayliteral)
3730             {
3731                 e->error("index assignment %s is not yet supported in CTFE ", e->toChars());
3732                 return CTFEExp::cantexp;
3733             }
3734 
3735             ArrayLiteralExp *existingAE = (ArrayLiteralExp *)aggregate;
3736             if (existingAE->ownedByCtfe != OWNEDctfe)
3737             {
3738                 e->error("cannot modify read-only constant %s", existingAE->toChars());
3739                 return CTFEExp::cantexp;
3740             }
3741 
3742             payload = &(*existingAE->elements)[index];
3743             oldval = *payload;
3744         }
3745         else
3746         {
3747             e->error("%s cannot be evaluated at compile time", e->toChars());
3748             return CTFEExp::cantexp;
3749         }
3750 
3751         Type *t1b = e1->type->toBasetype();
3752         bool wantCopy = t1b->baseElemOf()->ty == Tstruct;
3753 
3754         if (newval->op == TOKstructliteral && oldval)
3755         {
3756             newval = copyLiteral(newval).copy();
3757             assignInPlace(oldval, newval);
3758         }
3759         else if (wantCopy && e->op == TOKassign)
3760         {
3761             // Currently postblit/destructor calls on static array are done
3762             // in the druntime internal functions so they don't appear in AST.
3763             // Therefore interpreter should handle them specially.
3764 
3765             assert(oldval);
3766         #if 1   // todo: instead we can directly access to each elements of the slice
3767             newval = resolveSlice(newval);
3768             if (CTFEExp::isCantExp(newval))
3769             {
3770                 e->error("CTFE internal error: assignment %s", e->toChars());
3771                 return CTFEExp::cantexp;
3772             }
3773         #endif
3774             assert(oldval->op == TOKarrayliteral);
3775             assert(newval->op == TOKarrayliteral);
3776 
3777             Expressions *oldelems = ((ArrayLiteralExp *)oldval)->elements;
3778             Expressions *newelems = ((ArrayLiteralExp *)newval)->elements;
3779             assert(oldelems->dim == newelems->dim);
3780 
3781             Type *elemtype = oldval->type->nextOf();
3782             for (size_t i = 0; i < newelems->dim; i++)
3783             {
3784                 Expression *oldelem = (*oldelems)[i];
3785                 Expression *newelem = paintTypeOntoLiteral(elemtype, (*newelems)[i]);
3786                 // Bugzilla 9245
3787                 if (e->e2->isLvalue())
3788                 {
3789                     if (Expression *ex = evaluatePostblit(istate, newelem))
3790                         return ex;
3791                 }
3792                 // Bugzilla 13661
3793                 if (Expression *ex = evaluateDtor(istate, oldelem))
3794                     return ex;
3795                 (*oldelems)[i] = newelem;
3796             }
3797         }
3798         else
3799         {
3800             // e1 has its own payload, so we have to create a new literal.
3801             if (wantCopy)
3802                 newval = copyLiteral(newval).copy();
3803 
3804             if (t1b->ty == Tsarray && e->op == TOKconstruct && e->e2->isLvalue())
3805             {
3806                 // Bugzilla 9245
3807                 if (Expression *ex = evaluatePostblit(istate, newval))
3808                     return ex;
3809             }
3810 
3811             oldval = newval;
3812         }
3813 
3814         if (vd)
3815             setValue(vd, oldval);
3816         else
3817             *payload = oldval;
3818 
3819         // Blit assignment should return the newly created value.
3820         if (e->op == TOKblit)
3821             return oldval;
3822 
3823         return NULL;
3824     }
3825 
3826     /*************
3827      * Deal with assignments of the form:
3828      *  dest[] = newval
3829      *  dest[low..upp] = newval
3830      * where newval has already been interpreted
3831      *
3832      * This could be a slice assignment or a block assignment, and
3833      * dest could be either an array literal, or a string.
3834      *
3835      * Returns TOKcantexp on failure. If there are no errors,
3836      * it returns aggregate[low..upp], except that as an optimisation,
3837      * if goal == ctfeNeedNothing, it will return NULL
3838      */
interpretAssignToSlice(UnionExp * pue,BinExp * e,Expression * e1,Expression * newval,bool isBlockAssignment)3839     Expression *interpretAssignToSlice(UnionExp *pue, BinExp *e,
3840         Expression *e1, Expression *newval, bool isBlockAssignment)
3841     {
3842         dinteger_t lowerbound;
3843         dinteger_t upperbound;
3844 
3845         Expression *aggregate;
3846         dinteger_t firstIndex;
3847 
3848         if (e1->op == TOKslice)
3849         {
3850             // ------------------------------
3851             //   aggregate[] = newval
3852             //   aggregate[low..upp] = newval
3853             // ------------------------------
3854 
3855             SliceExp *se = (SliceExp *)e1;
3856         #if 1   // should be move in interpretAssignCommon as the evaluation of e1
3857             Expression *oldval = interpret(se->e1, istate);
3858 
3859             // Set the $ variable
3860             uinteger_t dollar = resolveArrayLength(oldval);
3861             if (se->lengthVar)
3862             {
3863                 Expression *dollarExp = new IntegerExp(e1->loc, dollar, Type::tsize_t);
3864                 ctfeStack.push(se->lengthVar);
3865                 setValue(se->lengthVar, dollarExp);
3866             }
3867             Expression *lwr = interpret(se->lwr, istate);
3868             if (exceptionOrCantInterpret(lwr))
3869             {
3870                 if (se->lengthVar)
3871                     ctfeStack.pop(se->lengthVar);
3872                 return lwr;
3873             }
3874             Expression *upr = interpret(se->upr, istate);
3875             if (exceptionOrCantInterpret(upr))
3876             {
3877                 if (se->lengthVar)
3878                     ctfeStack.pop(se->lengthVar);
3879                 return upr;
3880             }
3881             if (se->lengthVar)
3882                 ctfeStack.pop(se->lengthVar); // $ is defined only in [L..U]
3883 
3884             unsigned dim = (unsigned)dollar;
3885             lowerbound = (int)(lwr ? lwr->toInteger() : 0);
3886             upperbound = (size_t)(upr ? upr->toInteger() : dim);
3887 
3888             if ((int)lowerbound < 0 || dim < upperbound)
3889             {
3890                 e->error("array bounds [0..%d] exceeded in slice [%d..%d]",
3891                     dim, lowerbound, upperbound);
3892                 return CTFEExp::cantexp;
3893             }
3894         #endif
3895             aggregate = oldval;
3896             firstIndex = lowerbound;
3897 
3898             if (aggregate->op == TOKslice)
3899             {
3900                 // Slice of a slice --> change the bounds
3901                 SliceExp *oldse = (SliceExp *)aggregate;
3902                 if (oldse->upr->toInteger() < upperbound + oldse->lwr->toInteger())
3903                 {
3904                     e->error("slice [%d..%d] exceeds array bounds [0..%lld]",
3905                         lowerbound, upperbound,
3906                         oldse->upr->toInteger() - oldse->lwr->toInteger());
3907                     return CTFEExp::cantexp;
3908                 }
3909                 aggregate = oldse->e1;
3910                 firstIndex = lowerbound + oldse->lwr->toInteger();
3911             }
3912         }
3913         else
3914         {
3915             if (e1->op == TOKarrayliteral)
3916             {
3917                 lowerbound = 0;
3918                 upperbound = ((ArrayLiteralExp *)e1)->elements->dim;
3919             }
3920             else if (e1->op == TOKstring)
3921             {
3922                 lowerbound = 0;
3923                 upperbound = ((StringExp *)e1)->len;
3924             }
3925             else if (e1->op == TOKnull)
3926             {
3927                 lowerbound = 0;
3928                 upperbound = 0;
3929             }
3930             else
3931                 assert(0);
3932 
3933             aggregate = e1;
3934             firstIndex = lowerbound;
3935         }
3936         if (upperbound == lowerbound)
3937             return newval;
3938 
3939         // For slice assignment, we check that the lengths match.
3940         if (!isBlockAssignment)
3941         {
3942             size_t srclen = (size_t)resolveArrayLength(newval);
3943             if (srclen != (upperbound - lowerbound))
3944             {
3945                 e->error("array length mismatch assigning [0..%d] to [%d..%d]",
3946                     srclen, lowerbound, upperbound);
3947                 return CTFEExp::cantexp;
3948             }
3949         }
3950 
3951         if (aggregate->op == TOKstring)
3952         {
3953             StringExp *existingSE = (StringExp *)aggregate;
3954             if (existingSE->ownedByCtfe != OWNEDctfe)
3955             {
3956                 e->error("cannot modify read-only string literal %s", existingSE->toChars());
3957                 return CTFEExp::cantexp;
3958             }
3959 
3960             if (newval->op == TOKslice)
3961             {
3962                 SliceExp *se = (SliceExp *)newval;
3963                 Expression *aggr2 = se->e1;
3964                 const dinteger_t srclower = se->lwr->toInteger();
3965                 const dinteger_t srcupper = se->upr->toInteger();
3966 
3967                 if (aggregate == aggr2 &&
3968                     lowerbound < srcupper && srclower < upperbound)
3969                 {
3970                     e->error("overlapping slice assignment [%d..%d] = [%llu..%llu]",
3971                         lowerbound, upperbound, srclower, srcupper);
3972                     return CTFEExp::cantexp;
3973                 }
3974             #if 1   // todo: instead we can directly access to each elements of the slice
3975                 Expression *orignewval = newval;
3976                 newval = resolveSlice(newval);
3977                 if (CTFEExp::isCantExp(newval))
3978                 {
3979                     e->error("CTFE internal error: slice %s", orignewval->toChars());
3980                     return CTFEExp::cantexp;
3981                 }
3982             #endif
3983                 assert(newval->op != TOKslice);
3984             }
3985             if (newval->op == TOKstring)
3986             {
3987                 sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, (size_t)firstIndex);
3988                 return newval;
3989             }
3990             if (newval->op == TOKarrayliteral)
3991             {
3992                 /* Mixed slice: it was initialized as a string literal.
3993                  * Now a slice of it is being set with an array literal.
3994                  */
3995                 sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, (size_t)firstIndex);
3996                 return newval;
3997             }
3998 
3999             // String literal block slice assign
4000             dinteger_t value = newval->toInteger();
4001             void *s = existingSE->string;
4002             for (size_t i = 0; i < upperbound - lowerbound; i++)
4003             {
4004                 switch (existingSE->sz)
4005                 {
4006                     case 1:     (( utf8_t *)s)[(size_t)(i + firstIndex)] = ( utf8_t)value;  break;
4007                     case 2:     ((utf16_t *)s)[(size_t)(i + firstIndex)] = (utf16_t)value;  break;
4008                     case 4:     ((utf32_t *)s)[(size_t)(i + firstIndex)] = (utf32_t)value;  break;
4009                     default:    assert(0);                                                  break;
4010                 }
4011             }
4012             if (goal == ctfeNeedNothing)
4013                 return NULL; // avoid creating an unused literal
4014             SliceExp *retslice = new SliceExp(e->loc, existingSE,
4015                 new IntegerExp(e->loc, firstIndex, Type::tsize_t),
4016                 new IntegerExp(e->loc, firstIndex + upperbound - lowerbound, Type::tsize_t));
4017             retslice->type = e->type;
4018             return interpret(pue, retslice, istate);
4019         }
4020         if (aggregate->op == TOKarrayliteral)
4021         {
4022             ArrayLiteralExp *existingAE = (ArrayLiteralExp *)aggregate;
4023             if (existingAE->ownedByCtfe != OWNEDctfe)
4024             {
4025                 e->error("cannot modify read-only constant %s", existingAE->toChars());
4026                 return CTFEExp::cantexp;
4027             }
4028 
4029             if (newval->op == TOKslice && !isBlockAssignment)
4030             {
4031                 SliceExp *se = (SliceExp *)newval;
4032                 Expression *aggr2 = se->e1;
4033                 const dinteger_t srclower = se->lwr->toInteger();
4034                 const dinteger_t srcupper = se->upr->toInteger();
4035                 const bool wantCopy = (newval->type->toBasetype()->nextOf()->baseElemOf()->ty == Tstruct);
4036 
4037                 //printf("oldval = %p %s[%d..%u]\nnewval = %p %s[%llu..%llu] wantCopy = %d\n",
4038                 //    aggregate, aggregate->toChars(), lowerbound, upperbound,
4039                 //    aggr2, aggr2->toChars(), srclower, srcupper, wantCopy);
4040                 if (wantCopy)
4041                 {
4042                     // Currently overlapping for struct array is allowed.
4043                     // The order of elements processing depends on the overlapping.
4044                     // See bugzilla 14024.
4045                     assert(aggr2->op == TOKarrayliteral);
4046                     Expressions *oldelems = existingAE->elements;
4047                     Expressions *newelems = ((ArrayLiteralExp *)aggr2)->elements;
4048 
4049                     Type *elemtype = aggregate->type->nextOf();
4050                     bool needsPostblit = e->e2->isLvalue();
4051 
4052                     if (aggregate == aggr2 &&
4053                         srclower < lowerbound && lowerbound < srcupper)
4054                     {
4055                         // reverse order
4056                         for (size_t i = upperbound - lowerbound; 0 < i--; )
4057                         {
4058                             Expression *oldelem = (*oldelems)[(size_t)(i + firstIndex)];
4059                             Expression *newelem = (*newelems)[(size_t)(i + srclower)];
4060                             newelem = copyLiteral(newelem).copy();
4061                             newelem->type = elemtype;
4062                             if (needsPostblit)
4063                             {
4064                                 if (Expression *x = evaluatePostblit(istate, newelem))
4065                                     return x;
4066                             }
4067                             if (Expression *x = evaluateDtor(istate, oldelem))
4068                                 return x;
4069                             (*oldelems)[lowerbound + i] = newelem;
4070                         }
4071                     }
4072                     else
4073                     {
4074                         // normal order
4075                         for (size_t i = 0; i < upperbound - lowerbound; i++)
4076                         {
4077                             Expression *oldelem = (*oldelems)[(size_t)(i + firstIndex)];
4078                             Expression *newelem = (*newelems)[(size_t)(i + srclower)];
4079                             newelem = copyLiteral(newelem).copy();
4080                             newelem->type = elemtype;
4081                             if (needsPostblit)
4082                             {
4083                                 if (Expression *x = evaluatePostblit(istate, newelem))
4084                                     return x;
4085                             }
4086                             if (Expression *x = evaluateDtor(istate, oldelem))
4087                                 return x;
4088                             (*oldelems)[lowerbound + i] = newelem;
4089                         }
4090                     }
4091 
4092                     //assert(0);
4093                     return newval;  // oldval?
4094                 }
4095                 if (aggregate == aggr2 &&
4096                     lowerbound < srcupper && srclower < upperbound)
4097                 {
4098                     e->error("overlapping slice assignment [%d..%d] = [%llu..%llu]",
4099                         lowerbound, upperbound, srclower, srcupper);
4100                     return CTFEExp::cantexp;
4101                 }
4102             #if 1   // todo: instead we can directly access to each elements of the slice
4103                 Expression *orignewval = newval;
4104                 newval = resolveSlice(newval);
4105                 if (CTFEExp::isCantExp(newval))
4106                 {
4107                     e->error("CTFE internal error: slice %s", orignewval->toChars());
4108                     return CTFEExp::cantexp;
4109                 }
4110             #endif
4111                 // no overlapping
4112                 //length?
4113                 assert(newval->op != TOKslice);
4114             }
4115             if (newval->op == TOKstring && !isBlockAssignment)
4116             {
4117                 /* Mixed slice: it was initialized as an array literal of chars/integers.
4118                  * Now a slice of it is being set with a string.
4119                  */
4120                 sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, (size_t)firstIndex);
4121                 return newval;
4122             }
4123             if (newval->op == TOKarrayliteral && !isBlockAssignment)
4124             {
4125                 Expressions *oldelems = existingAE->elements;
4126                 Expressions *newelems = ((ArrayLiteralExp *)newval)->elements;
4127                 Type *elemtype = existingAE->type->nextOf();
4128                 bool needsPostblit = e->op != TOKblit && e->e2->isLvalue();
4129                 for (size_t j = 0; j < newelems->dim; j++)
4130                 {
4131                     Expression *newelem = (*newelems)[j];
4132                     newelem = paintTypeOntoLiteral(elemtype, newelem);
4133                     if (needsPostblit)
4134                     {
4135                         Expression *x = evaluatePostblit(istate, newelem);
4136                         if (exceptionOrCantInterpret(x))
4137                             return x;
4138                     }
4139                     (*oldelems)[(size_t)(j + firstIndex)] = newelem;
4140                 }
4141                 return newval;
4142             }
4143 
4144             /* Block assignment, initialization of static arrays
4145              *   x[] = newval
4146              *  x may be a multidimensional static array. (Note that this
4147              *  only happens with array literals, never with strings).
4148              */
4149             struct RecursiveBlock
4150             {
4151                 InterState *istate;
4152                 Expression *newval;
4153                 bool refCopy;
4154                 bool needsPostblit;
4155                 bool needsDtor;
4156 
4157                 Expression *assignTo(ArrayLiteralExp *ae)
4158                 {
4159                     return assignTo(ae, 0, ae->elements->dim);
4160                 }
4161 
4162                 Expression *assignTo(ArrayLiteralExp *ae, size_t lwr, size_t upr)
4163                 {
4164                     Expressions *w = ae->elements;
4165 
4166                     assert(ae->type->ty == Tsarray ||
4167                            ae->type->ty == Tarray);
4168                     bool directblk = ((TypeArray *)ae->type)->next->equivalent(newval->type);
4169 
4170                     for (size_t k = lwr; k < upr; k++)
4171                     {
4172                         if (!directblk && (*w)[k]->op == TOKarrayliteral)
4173                         {
4174                             // Multidimensional array block assign
4175                             if (Expression *ex = assignTo((ArrayLiteralExp *)(*w)[k]))
4176                                 return ex;
4177                         }
4178                         else if (refCopy)
4179                         {
4180                             (*w)[k] = newval;
4181                         }
4182                         else if (!needsPostblit && !needsDtor)
4183                         {
4184                             assignInPlace((*w)[k], newval);
4185                         }
4186                         else
4187                         {
4188                             Expression *oldelem = (*w)[k];
4189                             Expression *tmpelem = needsDtor ? copyLiteral(oldelem).copy() : NULL;
4190 
4191                             assignInPlace(oldelem, newval);
4192 
4193                             if (needsPostblit)
4194                             {
4195                                 if (Expression *ex = evaluatePostblit(istate, oldelem))
4196                                     return ex;
4197                             }
4198                             if (needsDtor)
4199                             {
4200                                 // Bugzilla 14860
4201                                 if (Expression *ex = evaluateDtor(istate, tmpelem))
4202                                     return ex;
4203                             }
4204                         }
4205                     }
4206                     return NULL;
4207                 }
4208             };
4209 
4210             Type *tn = newval->type->toBasetype();
4211             bool wantRef = (tn->ty == Tarray || isAssocArray(tn) ||tn->ty == Tclass);
4212             bool cow = newval->op != TOKstructliteral &&
4213                        newval->op != TOKarrayliteral &&
4214                        newval->op != TOKstring;
4215             Type *tb = tn->baseElemOf();
4216             StructDeclaration *sd = (tb->ty == Tstruct ? ((TypeStruct *)tb)->sym : NULL);
4217 
4218             RecursiveBlock rb;
4219             rb.istate = istate;
4220             rb.newval = newval;
4221             rb.refCopy = wantRef || cow;
4222             rb.needsPostblit = sd && sd->postblit && e->op != TOKblit && e->e2->isLvalue();
4223             rb.needsDtor = sd && sd->dtor && e->op == TOKassign;
4224 
4225             if (Expression *ex = rb.assignTo(existingAE, lowerbound, upperbound))
4226                 return ex;
4227 
4228             if (goal == ctfeNeedNothing)
4229                 return NULL; // avoid creating an unused literal
4230             SliceExp *retslice = new SliceExp(e->loc, existingAE,
4231                 new IntegerExp(e->loc, firstIndex, Type::tsize_t),
4232                 new IntegerExp(e->loc, firstIndex + upperbound - lowerbound, Type::tsize_t));
4233             retslice->type = e->type;
4234             return interpret(pue, retslice, istate);
4235         }
4236 
4237         e->error("slice operation %s = %s cannot be evaluated at compile time",
4238             e1->toChars(), newval->toChars());
4239         return CTFEExp::cantexp;
4240     }
4241 
visit(AssignExp * e)4242     void visit(AssignExp *e)
4243     {
4244         interpretAssignCommon(e, NULL);
4245     }
4246 
visit(BinAssignExp * e)4247     void visit(BinAssignExp *e)
4248     {
4249         switch (e->op)
4250         {
4251         case TOKaddass:  interpretAssignCommon(e, &Add);        return;
4252         case TOKminass:  interpretAssignCommon(e, &Min);        return;
4253         case TOKcatass:  interpretAssignCommon(e, &ctfeCat);    return;
4254         case TOKmulass:  interpretAssignCommon(e, &Mul);        return;
4255         case TOKdivass:  interpretAssignCommon(e, &Div);        return;
4256         case TOKmodass:  interpretAssignCommon(e, &Mod);        return;
4257         case TOKshlass:  interpretAssignCommon(e, &Shl);        return;
4258         case TOKshrass:  interpretAssignCommon(e, &Shr);        return;
4259         case TOKushrass: interpretAssignCommon(e, &Ushr);       return;
4260         case TOKandass:  interpretAssignCommon(e, &And);        return;
4261         case TOKorass:   interpretAssignCommon(e, &Or);         return;
4262         case TOKxorass:  interpretAssignCommon(e, &Xor);        return;
4263         case TOKpowass:  interpretAssignCommon(e, &Pow);        return;
4264         default:
4265             assert(0);
4266             return;
4267         }
4268     }
4269 
visit(PostExp * e)4270     void visit(PostExp *e)
4271     {
4272         if (e->op == TOKplusplus)
4273             interpretAssignCommon(e, &Add, 1);
4274         else
4275             interpretAssignCommon(e, &Min, 1);
4276     }
4277 
4278     /* Return 1 if e is a p1 > p2 or p1 >= p2 pointer comparison;
4279      *       -1 if e is a p1 < p2 or p1 <= p2 pointer comparison;
4280      *        0 otherwise
4281      */
isPointerCmpExp(Expression * e,Expression ** p1,Expression ** p2)4282     static int isPointerCmpExp(Expression *e, Expression **p1, Expression **p2)
4283     {
4284         int ret = 1;
4285         while (e->op == TOKnot)
4286         {
4287             ret *= -1;
4288             e = ((NotExp *)e)->e1;
4289         }
4290         switch (e->op)
4291         {
4292         case TOKlt:
4293         case TOKle:
4294             ret *= -1;
4295             /* fall through */
4296         case TOKgt:
4297         case TOKge:
4298             *p1 = ((BinExp *)e)->e1;
4299             *p2 = ((BinExp *)e)->e2;
4300             if (!(isPointer((*p1)->type) && isPointer((*p2)->type)))
4301                 ret = 0;
4302             break;
4303         default:
4304             ret = 0;
4305             break;
4306         }
4307         return ret;
4308     }
4309 
4310     /** Negate a relational operator, eg >= becomes <
4311      */
reverseRelation(TOK op)4312     static TOK reverseRelation(TOK op)
4313     {
4314         switch (op)
4315         {
4316             case TOKge: return TOKlt;
4317             case TOKgt: return TOKle;
4318             case TOKle: return TOKgt;
4319             case TOKlt: return TOKge;
4320             default:
4321                 return assert(0), TOKreserved;
4322         }
4323     }
4324 
4325     /** If this is a four pointer relation, evaluate it, else return NULL.
4326      *
4327      *  This is an expression of the form (p1 > q1 && p2 < q2) or (p1 < q1 || p2 > q2)
4328      *  where p1, p2 are expressions yielding pointers to memory block p,
4329      *  and q1, q2 are expressions yielding pointers to memory block q.
4330      *  This expression is valid even if p and q are independent memory
4331      *  blocks and are therefore not normally comparable; the && form returns true
4332      *  if [p1..p2] lies inside [q1..q2], and false otherwise; the || form returns
4333      *  true if [p1..p2] lies outside [q1..q2], and false otherwise.
4334      *
4335      *  Within the expression, any ordering of p1, p2, q1, q2 is permissible;
4336      *  the comparison operators can be any of >, <, <=, >=, provided that
4337      *  both directions (p > q and p < q) are checked. Additionally the
4338      *  relational sub-expressions can be negated, eg
4339      *  (!(q1 < p1) && p2 <= q2) is valid.
4340      */
interpretFourPointerRelation(UnionExp * pue,BinExp * e)4341     void interpretFourPointerRelation(UnionExp *pue, BinExp *e)
4342     {
4343         assert(e->op == TOKandand || e->op == TOKoror);
4344 
4345         /*  It can only be an isInside expression, if both e1 and e2 are
4346          *  directional pointer comparisons.
4347          *  Note that this check can be made statically; it does not depends on
4348          *  any runtime values. This allows a JIT implementation to compile a
4349          *  special AndAndPossiblyInside, keeping the normal AndAnd case efficient.
4350          */
4351 
4352         // Save the pointer expressions and the comparison directions,
4353         // so we can use them later.
4354         Expression *p1 = NULL;
4355         Expression *p2 = NULL;
4356         Expression *p3 = NULL;
4357         Expression *p4 = NULL;
4358         int dir1 = isPointerCmpExp(e->e1, &p1, &p2);
4359         int dir2 = isPointerCmpExp(e->e2, &p3, &p4);
4360         if (dir1 == 0 || dir2 == 0)
4361         {
4362             result = NULL;
4363             return;
4364         }
4365 
4366         //printf("FourPointerRelation %s\n", toChars());
4367         UnionExp ue1;
4368         UnionExp ue2;
4369         UnionExp ue3;
4370         UnionExp ue4;
4371 
4372         // Evaluate the first two pointers
4373         p1 = interpret(&ue1, p1, istate);
4374         if (exceptionOrCant(p1))
4375             return;
4376         p2 = interpret(&ue2, p2, istate);
4377         if (exceptionOrCant(p2))
4378             return;
4379         dinteger_t ofs1, ofs2;
4380         Expression *agg1 = getAggregateFromPointer(p1, &ofs1);
4381         Expression *agg2 = getAggregateFromPointer(p2, &ofs2);
4382 
4383         if (!pointToSameMemoryBlock(agg1, agg2) &&
4384             agg1->op != TOKnull &&
4385             agg2->op != TOKnull)
4386         {
4387             // Here it is either CANT_INTERPRET,
4388             // or an IsInside comparison returning false.
4389             p3 = interpret(&ue3, p3, istate);
4390             if (CTFEExp::isCantExp(p3))
4391                 return;
4392             // Note that it is NOT legal for it to throw an exception!
4393             Expression *except = NULL;
4394             if (exceptionOrCantInterpret(p3))
4395                 except = p3;
4396             else
4397             {
4398                 p4 = interpret(&ue4, p4, istate);
4399                 if (CTFEExp::isCantExp(p4))
4400                 {
4401                     result = p4;
4402                     return;
4403                 }
4404                 if (exceptionOrCantInterpret(p4))
4405                     except = p4;
4406             }
4407             if (except)
4408             {
4409                 e->error("comparison %s of pointers to unrelated memory blocks remains "
4410                      "indeterminate at compile time "
4411                      "because exception %s was thrown while evaluating %s",
4412                      e->e1->toChars(), except->toChars(), e->e2->toChars());
4413                 result = CTFEExp::cantexp;
4414                 return;
4415             }
4416             dinteger_t ofs3, ofs4;
4417             Expression *agg3 = getAggregateFromPointer(p3, &ofs3);
4418             Expression *agg4 = getAggregateFromPointer(p4, &ofs4);
4419             // The valid cases are:
4420             // p1 > p2 && p3 > p4  (same direction, also for < && <)
4421             // p1 > p2 && p3 < p4  (different direction, also < && >)
4422             // Changing any > into >= doesnt affect the result
4423             if ((dir1 == dir2 && pointToSameMemoryBlock(agg1, agg4) && pointToSameMemoryBlock(agg2, agg3)) ||
4424                 (dir1 != dir2 && pointToSameMemoryBlock(agg1, agg3) && pointToSameMemoryBlock(agg2, agg4)))
4425             {
4426                 // it's a legal two-sided comparison
4427                 new(pue) IntegerExp(e->loc, (e->op == TOKandand) ?  0 : 1, e->type);
4428                 result = pue->exp();
4429                 return;
4430             }
4431             // It's an invalid four-pointer comparison. Either the second
4432             // comparison is in the same direction as the first, or else
4433             // more than two memory blocks are involved (either two independent
4434             // invalid comparisons are present, or else agg3 == agg4).
4435             e->error("comparison %s of pointers to unrelated memory blocks is "
4436                 "indeterminate at compile time, even when combined with %s.",
4437                 e->e1->toChars(), e->e2->toChars());
4438             result = CTFEExp::cantexp;
4439             return;
4440         }
4441         // The first pointer expression didn't need special treatment, so we
4442         // we need to interpret the entire expression exactly as a normal && or ||.
4443         // This is easy because we haven't evaluated e2 at all yet, and we already
4444         // know it will return a bool.
4445         // But we mustn't evaluate the pointer expressions in e1 again, in case
4446         // they have side-effects.
4447         bool nott = false;
4448         Expression *ex = e->e1;
4449         while (ex->op == TOKnot)
4450         {
4451             nott = !nott;
4452             ex = ((NotExp *)ex)->e1;
4453         }
4454         const TOK cmpop = nott ? reverseRelation(ex->op) : ex->op;
4455         const int cmp = comparePointers(cmpop, agg1, ofs1, agg2, ofs2);
4456         // We already know this is a valid comparison.
4457         assert(cmp >= 0);
4458         if ((e->op == TOKandand && cmp == 1) ||
4459             (e->op == TOKoror   && cmp == 0))
4460         {
4461             result = interpret(pue, e->e2, istate);
4462             return;
4463         }
4464         new(pue) IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
4465         result = pue->exp();
4466     }
4467 
visit(AndAndExp * e)4468     void visit(AndAndExp *e)
4469     {
4470         // Check for an insidePointer expression, evaluate it if so
4471         interpretFourPointerRelation(pue, e);
4472         if (result)
4473             return;
4474 
4475         result = interpret(e->e1, istate);
4476         if (exceptionOrCant(result))
4477             return;
4478 
4479         int res;
4480         if (result->isBool(false))
4481             res = 0;
4482         else if (isTrueBool(result))
4483         {
4484             UnionExp ue2;
4485             result = interpret(&ue2, e->e2, istate);
4486             if (exceptionOrCant(result))
4487                 return;
4488             if (result->op == TOKvoidexp)
4489             {
4490                 assert(e->type->ty == Tvoid);
4491                 result = NULL;
4492                 return;
4493             }
4494             if (result->isBool(false))
4495                 res = 0;
4496             else if (isTrueBool(result))
4497                 res = 1;
4498             else
4499             {
4500                 result->error("%s does not evaluate to a boolean", result->toChars());
4501                 result = CTFEExp::cantexp;
4502                 return;
4503             }
4504         }
4505         else
4506         {
4507             result->error("%s cannot be interpreted as a boolean", result->toChars());
4508             result = CTFEExp::cantexp;
4509             return;
4510         }
4511         if (goal != ctfeNeedNothing)
4512         {
4513             new(pue) IntegerExp(e->loc, res, e->type);
4514             result = pue->exp();
4515         }
4516     }
4517 
visit(OrOrExp * e)4518     void visit(OrOrExp *e)
4519     {
4520         // Check for an insidePointer expression, evaluate it if so
4521         interpretFourPointerRelation(pue, e);
4522         if (result)
4523             return;
4524 
4525         result = interpret(e->e1, istate);
4526         if (exceptionOrCant(result))
4527             return;
4528 
4529         int res;
4530         if (isTrueBool(result))
4531             res = 1;
4532         else if (result->isBool(false))
4533         {
4534             UnionExp ue2;
4535             result = interpret(&ue2, e->e2, istate);
4536             if (exceptionOrCant(result))
4537                 return;
4538             if (result->op == TOKvoidexp)
4539             {
4540                 assert(e->type->ty == Tvoid);
4541                 result = NULL;
4542                 return;
4543             }
4544             if (result->isBool(false))
4545                 res = 0;
4546             else if (isTrueBool(result))
4547                 res = 1;
4548             else
4549             {
4550                 result->error("%s cannot be interpreted as a boolean", result->toChars());
4551                 result = CTFEExp::cantexp;
4552                 return;
4553             }
4554         }
4555         else
4556         {
4557             result->error("%s cannot be interpreted as a boolean", result->toChars());
4558             result = CTFEExp::cantexp;
4559             return;
4560         }
4561         if (goal != ctfeNeedNothing)
4562         {
4563             new(pue) IntegerExp(e->loc, res, e->type);
4564             result = pue->exp();
4565         }
4566     }
4567 
4568     // Print a stack trace, starting from callingExp which called fd.
4569     // To shorten the stack trace, try to detect recursion.
showCtfeBackTrace(CallExp * callingExp,FuncDeclaration * fd)4570     void showCtfeBackTrace(CallExp * callingExp, FuncDeclaration *fd)
4571     {
4572         if (CtfeStatus::stackTraceCallsToSuppress > 0)
4573         {
4574             --CtfeStatus::stackTraceCallsToSuppress;
4575             return;
4576         }
4577         errorSupplemental(callingExp->loc, "called from here: %s", callingExp->toChars());
4578         // Quit if it's not worth trying to compress the stack trace
4579         if (CtfeStatus::callDepth < 6 || global.params.verbose)
4580             return;
4581         // Recursion happens if the current function already exists in the call stack.
4582         int numToSuppress = 0;
4583         int recurseCount = 0;
4584         int depthSoFar = 0;
4585         InterState *lastRecurse = istate;
4586         for (InterState * cur = istate; cur; cur = cur->caller)
4587         {
4588             if (cur->fd == fd)
4589             {
4590                 ++recurseCount;
4591                 numToSuppress = depthSoFar;
4592                 lastRecurse = cur;
4593             }
4594             ++depthSoFar;
4595         }
4596         // We need at least three calls to the same function, to make compression worthwhile
4597         if (recurseCount < 2)
4598             return;
4599         // We found a useful recursion.  Print all the calls involved in the recursion
4600         errorSupplemental(fd->loc, "%d recursive calls to function %s", recurseCount, fd->toChars());
4601         for (InterState *cur = istate; cur->fd != fd; cur = cur->caller)
4602         {
4603             errorSupplemental(cur->fd->loc, "recursively called from function %s", cur->fd->toChars());
4604         }
4605         // We probably didn't enter the recursion in this function.
4606         // Go deeper to find the real beginning.
4607         InterState * cur = istate;
4608         while (lastRecurse->caller && cur->fd == lastRecurse->caller->fd)
4609         {
4610             cur = cur->caller;
4611             lastRecurse = lastRecurse->caller;
4612             ++numToSuppress;
4613         }
4614         CtfeStatus::stackTraceCallsToSuppress = numToSuppress;
4615     }
4616 
visit(CallExp * e)4617     void visit(CallExp *e)
4618     {
4619         Expression *pthis = NULL;
4620         FuncDeclaration *fd = NULL;
4621 
4622         Expression *ecall = interpret(e->e1, istate);
4623         if (exceptionOrCant(ecall))
4624             return;
4625 
4626         if (ecall->op == TOKdotvar)
4627         {
4628             DotVarExp *dve = (DotVarExp *)ecall;
4629 
4630             // Calling a member function
4631             pthis = dve->e1;
4632             fd = dve->var->isFuncDeclaration();
4633             assert(fd);
4634 
4635             if (pthis->op == TOKdottype)
4636                 pthis = ((DotTypeExp *)dve->e1)->e1;
4637         }
4638         else if (ecall->op == TOKvar)
4639         {
4640             fd = ((VarExp *)ecall)->var->isFuncDeclaration();
4641             assert(fd);
4642 
4643             if (fd->ident == Id::__ArrayPostblit ||
4644                 fd->ident == Id::__ArrayDtor)
4645             {
4646                 assert(e->arguments->dim == 1);
4647                 Expression *ea = (*e->arguments)[0];
4648                 //printf("1 ea = %s %s\n", ea->type->toChars(), ea->toChars());
4649                 if (ea->op == TOKslice)
4650                     ea = ((SliceExp *)ea)->e1;
4651                 if (ea->op == TOKcast)
4652                     ea = ((CastExp *)ea)->e1;
4653 
4654                 //printf("2 ea = %s, %s %s\n", ea->type->toChars(), Token::toChars(ea->op), ea->toChars());
4655                 if (ea->op == TOKvar || ea->op == TOKsymoff)
4656                     result = getVarExp(e->loc, istate, ((SymbolExp *)ea)->var, ctfeNeedRvalue);
4657                 else if (ea->op == TOKaddress)
4658                     result = interpret(((AddrExp *)ea)->e1, istate);
4659                 // https://issues.dlang.org/show_bug.cgi?id=18871
4660                 // https://issues.dlang.org/show_bug.cgi?id=18819
4661                 else if (ea->op == TOKarrayliteral)
4662                     result = interpret((ArrayLiteralExp *)ea, istate);
4663                 else
4664                     assert(0);
4665                 if (CTFEExp::isCantExp(result))
4666                     return;
4667 
4668                 if (fd->ident == Id::__ArrayPostblit)
4669                     result = evaluatePostblit(istate, result);
4670                 else
4671                     result = evaluateDtor(istate, result);
4672                 if (!result)
4673                     result = CTFEExp::voidexp;
4674                 return;
4675             }
4676         }
4677         else if (ecall->op == TOKsymoff)
4678         {
4679             SymOffExp *soe = (SymOffExp *)ecall;
4680             fd = soe->var->isFuncDeclaration();
4681             assert(fd && soe->offset == 0);
4682         }
4683         else if (ecall->op == TOKdelegate)
4684         {
4685             // Calling a delegate
4686             fd = ((DelegateExp *)ecall)->func;
4687             pthis = ((DelegateExp *)ecall)->e1;
4688 
4689             // Special handling for: &nestedfunc --> DelegateExp(VarExp(nestedfunc), nestedfunc)
4690             if (pthis->op == TOKvar && ((VarExp *)pthis)->var == fd)
4691                 pthis = NULL;   // context is not necessary for CTFE
4692         }
4693         else if (ecall->op == TOKfunction)
4694         {
4695             // Calling a delegate literal
4696             fd = ((FuncExp *)ecall)->fd;
4697         }
4698         else
4699         {
4700             // delegate.funcptr()
4701             // others
4702             e->error("cannot call %s at compile time", e->toChars());
4703             result = CTFEExp::cantexp;
4704             return;
4705         }
4706 
4707         if (!fd)
4708         {
4709             e->error("CTFE internal error: cannot evaluate %s at compile time", e->toChars());
4710             result = CTFEExp::cantexp;
4711             return;
4712         }
4713         if (pthis)
4714         {
4715             // Member function call
4716 
4717             // Currently this is satisfied because closure is not yet supported.
4718             assert(!fd->isNested());
4719 
4720             if (pthis->op == TOKtypeid)
4721             {
4722                 pthis->error("static variable %s cannot be read at compile time", pthis->toChars());
4723                 result = CTFEExp::cantexp;
4724                 return;
4725             }
4726             assert(pthis);
4727 
4728             if (pthis->op == TOKnull)
4729             {
4730                 assert(pthis->type->toBasetype()->ty == Tclass);
4731                 e->error("function call through null class reference %s", pthis->toChars());
4732                 result = CTFEExp::cantexp;
4733                 return;
4734             }
4735             assert(pthis->op == TOKstructliteral || pthis->op == TOKclassreference);
4736 
4737             if (fd->isVirtual() && !e->directcall)
4738             {
4739                 // Make a virtual function call.
4740                 // Get the function from the vtable of the original class
4741                 assert(pthis->op == TOKclassreference);
4742                 ClassDeclaration *cd = ((ClassReferenceExp *)pthis)->originalClass();
4743 
4744                 // We can't just use the vtable index to look it up, because
4745                 // vtables for interfaces don't get populated until the glue layer.
4746                 fd = cd->findFunc(fd->ident, (TypeFunction *)fd->type);
4747                 assert(fd);
4748             }
4749         }
4750 
4751         if (fd && fd->semanticRun >= PASSsemantic3done && fd->semantic3Errors)
4752         {
4753             e->error("CTFE failed because of previous errors in %s", fd->toChars());
4754             result = CTFEExp::cantexp;
4755             return;
4756         }
4757 
4758         // Check for built-in functions
4759         result = evaluateIfBuiltin(pue, istate, e->loc, fd, e->arguments, pthis);
4760         if (result)
4761             return;
4762 
4763         if (!fd->fbody)
4764         {
4765             e->error("%s cannot be interpreted at compile time,"
4766                 " because it has no available source code", fd->toChars());
4767             result = CTFEExp::cantexp;
4768             return;
4769         }
4770 
4771         result = interpretFunction(pue, fd, istate, e->arguments, pthis);
4772         if (result->op == TOKvoidexp)
4773             return;
4774         if (!exceptionOrCantInterpret(result))
4775         {
4776             if (goal != ctfeNeedLvalue) // Peel off CTFE reference if it's unnecessary
4777             {
4778                 if (result == pue->exp())
4779                     result = pue->copy();
4780                 result = interpret(pue, result, istate);
4781             }
4782         }
4783         if (!exceptionOrCantInterpret(result))
4784         {
4785             result = paintTypeOntoLiteral(e->type, result);
4786             result->loc = e->loc;
4787         }
4788         else if (CTFEExp::isCantExp(result) && !global.gag)
4789             showCtfeBackTrace(e, fd);   // Print a stack trace.
4790     }
4791 
endTempStackFrame(InterState * pistateComma)4792     void endTempStackFrame(InterState *pistateComma)
4793     {
4794         // If we created a temporary stack frame, end it now.
4795         if (istate == pistateComma)
4796             ctfeStack.endFrame();
4797     }
4798 
visit(CommaExp * e)4799     void visit(CommaExp *e)
4800     {
4801         CommaExp *firstComma = e;
4802         while (firstComma->e1->op == TOKcomma)
4803             firstComma = (CommaExp *)firstComma->e1;
4804 
4805         // If it creates a variable, and there's no context for
4806         // the variable to be created in, we need to create one now.
4807         InterState istateComma;
4808         if (!istate && firstComma->e1->op == TOKdeclaration)
4809         {
4810             ctfeStack.startFrame(NULL);
4811             istate = &istateComma;
4812         }
4813 
4814         result = CTFEExp::cantexp;
4815 
4816         // If the comma returns a temporary variable, it needs to be an lvalue
4817         // (this is particularly important for struct constructors)
4818         if (e->e1->op == TOKdeclaration && e->e2->op == TOKvar &&
4819             ((DeclarationExp *)e->e1)->declaration == ((VarExp*)e->e2)->var &&
4820             ((VarExp*)e->e2)->var->storage_class & STCctfe)  // same as Expression::isTemp
4821         {
4822             VarExp *ve = (VarExp *)e->e2;
4823             VarDeclaration *v = ve->var->isVarDeclaration();
4824             ctfeStack.push(v);
4825             if (!v->_init && !getValue(v))
4826             {
4827                 setValue(v, copyLiteral(v->type->defaultInitLiteral(e->loc)).copy());
4828             }
4829             if (!getValue(v))
4830             {
4831                 Expression *newval = initializerToExpression(v->_init);
4832                 // Bug 4027. Copy constructors are a weird case where the
4833                 // initializer is a void function (the variable is modified
4834                 // through a reference parameter instead).
4835                 newval = interpret(newval, istate);
4836                 if (exceptionOrCant(newval))
4837                     return endTempStackFrame(&istateComma);
4838                 if (newval->op != TOKvoidexp)
4839                 {
4840                     // v isn't necessarily null.
4841                     setValueWithoutChecking(v, copyLiteral(newval).copy());
4842                 }
4843             }
4844         }
4845         else
4846         {
4847             UnionExp ue;
4848             Expression *e1 = interpret(&ue, e->e1, istate, ctfeNeedNothing);
4849             if (exceptionOrCant(e1))
4850                 return endTempStackFrame(&istateComma);
4851         }
4852         result = interpret(pue, e->e2, istate, goal);
4853         return endTempStackFrame(&istateComma);
4854     }
4855 
visit(CondExp * e)4856     void visit(CondExp *e)
4857     {
4858         UnionExp uecond;
4859         Expression *econd;
4860         econd = interpret(&uecond, e->econd, istate);
4861         if (exceptionOrCant(econd))
4862             return;
4863 
4864         if (isPointer(e->econd->type))
4865         {
4866             if (econd->op != TOKnull)
4867             {
4868                 new(&uecond) IntegerExp(e->loc, 1, Type::tbool);
4869                 econd = uecond.exp();
4870             }
4871         }
4872 
4873         if (isTrueBool(econd))
4874             result = interpret(pue, e->e1, istate, goal);
4875         else if (econd->isBool(false))
4876             result = interpret(pue, e->e2, istate, goal);
4877         else
4878         {
4879             e->error("%s does not evaluate to boolean result at compile time", e->econd->toChars());
4880             result = CTFEExp::cantexp;
4881         }
4882     }
4883 
visit(ArrayLengthExp * e)4884     void visit(ArrayLengthExp *e)
4885     {
4886         UnionExp ue1;
4887         Expression *e1 = interpret(&ue1, e->e1, istate);
4888         assert(e1);
4889         if (exceptionOrCant(e1))
4890             return;
4891         if (e1->op != TOKstring &&
4892             e1->op != TOKarrayliteral &&
4893             e1->op != TOKslice &&
4894             e1->op != TOKnull)
4895         {
4896             e->error("%s cannot be evaluated at compile time", e->toChars());
4897             result = CTFEExp::cantexp;
4898             return;
4899         }
4900         new(pue) IntegerExp(e->loc, resolveArrayLength(e1), e->type);
4901         result = pue->exp();
4902     }
4903 
4904     /**
4905      * Interpret the vector expression as an array literal.
4906      * Params:
4907      *    pue = non-null pointer to temporary storage that can be used to store the return value
4908      *    e = Expression to interpret
4909      * Returns:
4910      *    resulting array literal or 'e' if unable to interpret
4911      */
interpretVectorToArray(UnionExp * pue,VectorExp * e)4912     static Expression *interpretVectorToArray(UnionExp *pue, VectorExp *e)
4913     {
4914         if (e->e1->op == TOKarrayliteral)
4915             return (ArrayLiteralExp *)e->e1;
4916         if (e->e1->op == TOKint64 || e->e1->op == TOKfloat64)
4917         {
4918             // Convert literal __vector(int) -> __vector([array])
4919             Expressions *elements = new Expressions();
4920             elements->setDim(e->dim);
4921             for (size_t i = 0; i < elements->dim; i++)
4922                 (*elements)[i] = copyLiteral(e->e1).copy();
4923             TypeSArray *type = NULL;
4924             if (e->type->ty == Tvector)
4925             {
4926                 TypeVector *tv = (TypeVector *)e->type;
4927                 if (tv->basetype->ty == Tsarray)
4928                     type = (TypeSArray *)tv->basetype;
4929             }
4930             else if (e->type->ty == Tsarray)
4931                 type = (TypeSArray *)e->type;
4932             assert(type);
4933             new(pue) ArrayLiteralExp(e->loc, type, elements);
4934             ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
4935             ale->ownedByCtfe = OWNEDctfe;
4936             return ale;
4937         }
4938         return e;
4939     }
4940 
visit(VectorExp * e)4941     void visit(VectorExp *e)
4942     {
4943         if (e->ownedByCtfe >= OWNEDctfe) // We've already interpreted all the elements
4944         {
4945             result = e;
4946             return;
4947         }
4948         Expression *e1 = interpret(pue, e->e1, istate);
4949         assert(e1);
4950         if (exceptionOrCant(e1))
4951             return;
4952         if (e1->op != TOKarrayliteral && e1->op != TOKint64 && e1->op != TOKfloat64)
4953         {
4954             e->error("`%s` cannot be evaluated at compile time", e->toChars());
4955             result = CTFEExp::cantexp;
4956             return;
4957         }
4958         if (e1 == pue->exp())
4959             e1 = pue->copy();
4960         new(pue) VectorExp(e->loc, e1, e->to);
4961         VectorExp *ve = (VectorExp *)pue->exp();
4962         ve->type = e->type;
4963         ve->dim = e->dim;
4964         ve->ownedByCtfe = OWNEDctfe;
4965         result = ve;
4966     }
4967 
visit(VectorArrayExp * e)4968     void visit(VectorArrayExp *e)
4969     {
4970         Expression *e1 = interpret(pue, e->e1, istate);
4971         assert(e1);
4972         if (exceptionOrCant(e1))
4973             return;
4974         if (e1->op == TOKvector)
4975         {
4976             VectorExp *ve = (VectorExp *)e1;
4977             result = interpretVectorToArray(pue, ve);
4978             if (result->op != TOKvector)
4979                 return;
4980         }
4981         e->error("`%s` cannot be evaluated at compile time", e->toChars());
4982         result = CTFEExp::cantexp;
4983     }
4984 
visit(DelegatePtrExp * e)4985     void visit(DelegatePtrExp *e)
4986     {
4987         Expression *e1 = interpret(pue, e->e1, istate);
4988         assert(e1);
4989         if (exceptionOrCant(e1))
4990             return;
4991         e->error("%s cannot be evaluated at compile time", e->toChars());
4992         result = CTFEExp::cantexp;
4993     }
4994 
visit(DelegateFuncptrExp * e)4995     void visit(DelegateFuncptrExp *e)
4996     {
4997         Expression *e1 = interpret(pue, e->e1, istate);
4998         assert(e1);
4999         if (exceptionOrCant(e1))
5000             return;
5001         e->error("%s cannot be evaluated at compile time", e->toChars());
5002         result = CTFEExp::cantexp;
5003     }
5004 
resolveIndexing(IndexExp * e,InterState * istate,Expression ** pagg,uinteger_t * pidx,bool modify)5005     static bool resolveIndexing(IndexExp *e, InterState *istate, Expression **pagg, uinteger_t *pidx, bool modify)
5006     {
5007         assert(e->e1->type->toBasetype()->ty != Taarray);
5008 
5009         if (e->e1->type->toBasetype()->ty == Tpointer)
5010         {
5011             // Indexing a pointer. Note that there is no $ in this case.
5012             Expression *e1 = interpret(e->e1, istate);
5013             if (exceptionOrCantInterpret(e1))
5014                 return false;
5015 
5016             Expression *e2 = interpret(e->e2, istate);
5017             if (exceptionOrCantInterpret(e2))
5018                 return false;
5019             sinteger_t indx = e2->toInteger();
5020 
5021             dinteger_t ofs;
5022             Expression *agg = getAggregateFromPointer(e1, &ofs);
5023 
5024             if (agg->op == TOKnull)
5025             {
5026                 e->error("cannot index through null pointer %s", e->e1->toChars());
5027                 return false;
5028             }
5029             if (agg->op == TOKint64)
5030             {
5031                 e->error("cannot index through invalid pointer %s of value %s",
5032                     e->e1->toChars(), e1->toChars());
5033                 return false;
5034             }
5035             // Pointer to a non-array variable
5036             if (agg->op == TOKsymoff)
5037             {
5038                 e->error("mutable variable %s cannot be %s at compile time, even through a pointer",
5039                     (modify ? "modified" : "read"), ((SymOffExp *)agg)->var->toChars());
5040                 return false;
5041             }
5042 
5043             if (agg->op == TOKarrayliteral || agg->op == TOKstring)
5044             {
5045                 dinteger_t len = resolveArrayLength(agg);
5046                 if (ofs + indx >= len)
5047                 {
5048                     e->error("pointer index [%lld] exceeds allocated memory block [0..%lld]",
5049                         ofs + indx, len);
5050                     return false;
5051                 }
5052             }
5053             else
5054             {
5055                 if (ofs + indx != 0)
5056                 {
5057                     e->error("pointer index [%lld] lies outside memory block [0..1]",
5058                         ofs + indx);
5059                     return false;
5060                 }
5061             }
5062             *pagg = agg;
5063             *pidx = ofs + indx;
5064             return true;
5065         }
5066 
5067         Expression *e1 = interpret(e->e1, istate);
5068         if (exceptionOrCantInterpret(e1))
5069             return false;
5070         if (e1->op == TOKnull)
5071         {
5072             e->error("cannot index null array %s", e->e1->toChars());
5073             return false;
5074         }
5075         if (e1->op == TOKvector)
5076         {
5077             UnionExp ue;
5078             e1 = interpretVectorToArray(&ue, (VectorExp *)e1);
5079             e1 = (e1 == ue.exp()) ? ue.copy() : e1;
5080         }
5081 
5082         // Set the $ variable, and find the array literal to modify
5083         if (e1->op != TOKarrayliteral &&
5084             e1->op != TOKstring &&
5085             e1->op != TOKslice &&
5086             e1->op != TOKvector)
5087         {
5088             e->error("cannot determine length of %s at compile time",
5089                 e->e1->toChars());
5090             return false;
5091         }
5092 
5093         dinteger_t len = resolveArrayLength(e1);
5094         if (e->lengthVar)
5095         {
5096             Expression *dollarExp = new IntegerExp(e->loc, len, Type::tsize_t);
5097             ctfeStack.push(e->lengthVar);
5098             setValue(e->lengthVar, dollarExp);
5099         }
5100         Expression *e2 = interpret(e->e2, istate);
5101         if (e->lengthVar)
5102             ctfeStack.pop(e->lengthVar); // $ is defined only inside []
5103         if (exceptionOrCantInterpret(e2))
5104             return false;
5105         if (e2->op != TOKint64)
5106         {
5107             e->error("CTFE internal error: non-integral index [%s]", e->e2->toChars());
5108             return false;
5109         }
5110 
5111         if (e1->op == TOKslice)
5112         {
5113             // Simplify index of slice: agg[lwr..upr][indx] --> agg[indx']
5114             uinteger_t index = e2->toInteger();
5115             uinteger_t ilwr = ((SliceExp *)e1)->lwr->toInteger();
5116             uinteger_t iupr = ((SliceExp *)e1)->upr->toInteger();
5117 
5118             if (index > iupr - ilwr)
5119             {
5120                 e->error("index %llu exceeds array length %llu", index, iupr - ilwr);
5121                 return false;
5122             }
5123             *pagg = ((SliceExp *)e1)->e1;
5124             *pidx = index + ilwr;
5125         }
5126         else
5127         {
5128             *pagg = e1;
5129             *pidx = e2->toInteger();
5130             if (len <= *pidx)
5131             {
5132                 e->error("array index %lld is out of bounds [0..%lld]",
5133                     *pidx, len);
5134                 return false;
5135             }
5136         }
5137         return true;
5138     }
5139 
visit(IndexExp * e)5140     void visit(IndexExp *e)
5141     {
5142         if (e->e1->type->toBasetype()->ty == Tpointer)
5143         {
5144             Expression *agg;
5145             uinteger_t indexToAccess;
5146             if (!resolveIndexing(e, istate, &agg, &indexToAccess, false))
5147             {
5148                 result = CTFEExp::cantexp;
5149                 return;
5150             }
5151             if (agg->op == TOKarrayliteral || agg->op == TOKstring)
5152             {
5153                 if (goal == ctfeNeedLvalue)
5154                 {
5155                     // if we need a reference, IndexExp shouldn't be interpreting
5156                     // the expression to a value, it should stay as a reference
5157                     new(pue) IndexExp(e->loc, agg, new IntegerExp(e->e2->loc, indexToAccess, e->e2->type));
5158                     result = pue->exp();
5159                     result->type = e->type;
5160                     return;
5161                 }
5162                 result = ctfeIndex(e->loc, e->type, agg, indexToAccess);
5163                 return;
5164             }
5165             else
5166             {
5167                 assert(indexToAccess == 0);
5168                 result = interpret(agg, istate, goal);
5169                 if (exceptionOrCant(result))
5170                     return;
5171                 result = paintTypeOntoLiteral(e->type, result);
5172                 return;
5173             }
5174         }
5175 
5176         if (e->e1->type->toBasetype()->ty == Taarray)
5177         {
5178             Expression *e1 = interpret(e->e1, istate);
5179             if (exceptionOrCant(e1))
5180                 return;
5181             if (e1->op == TOKnull)
5182             {
5183                 if (goal == ctfeNeedLvalue && e1->type->ty == Taarray && e->modifiable)
5184                 {
5185                     assert(0);  // does not reach here?
5186                     return;
5187                 }
5188                 e->error("cannot index null array %s", e->e1->toChars());
5189                 result = CTFEExp::cantexp;
5190                 return;
5191             }
5192             Expression *e2 = interpret(e->e2, istate);
5193             if (exceptionOrCant(e2))
5194                 return;
5195 
5196             if (goal == ctfeNeedLvalue)
5197             {
5198                 // Pointer or reference of a scalar type
5199                 if (e1 == e->e1 && e2 == e->e2)
5200                     result = e;
5201                 else
5202                 {
5203                     new(pue) IndexExp(e->loc, e1, e2);
5204                     result = pue->exp();
5205                     result->type = e->type;
5206                 }
5207                 return;
5208             }
5209 
5210             assert(e1->op == TOKassocarrayliteral);
5211             UnionExp e2tmp;
5212             e2 = resolveSlice(e2, &e2tmp);
5213             result = findKeyInAA(e->loc, (AssocArrayLiteralExp *)e1, e2);
5214             if (!result)
5215             {
5216                 e->error("key %s not found in associative array %s", e2->toChars(), e->e1->toChars());
5217                 result = CTFEExp::cantexp;
5218             }
5219             return;
5220         }
5221 
5222         Expression *agg;
5223         uinteger_t indexToAccess;
5224         if (!resolveIndexing(e, istate, &agg, &indexToAccess, false))
5225         {
5226             result = CTFEExp::cantexp;
5227             return;
5228         }
5229 
5230         if (goal == ctfeNeedLvalue)
5231         {
5232             Expression *e2 = new IntegerExp(e->e2->loc, indexToAccess, Type::tsize_t);
5233             new(pue) IndexExp(e->loc, agg, e2);
5234             result = pue->exp();
5235             result->type = e->type;
5236             return;
5237         }
5238 
5239         result = ctfeIndex(e->loc, e->type, agg, indexToAccess);
5240         if (exceptionOrCant(result))
5241             return;
5242         if (result->op == TOKvoid)
5243         {
5244             e->error("%s is used before initialized", e->toChars());
5245             errorSupplemental(result->loc, "originally uninitialized here");
5246             result = CTFEExp::cantexp;
5247             return;
5248         }
5249         result = paintTypeOntoLiteral(e->type, result);
5250     }
5251 
visit(SliceExp * e)5252     void visit(SliceExp *e)
5253     {
5254         if (e->e1->type->toBasetype()->ty == Tpointer)
5255         {
5256             // Slicing a pointer. Note that there is no $ in this case.
5257             Expression *e1 = interpret(e->e1, istate);
5258             if (exceptionOrCant(e1))
5259                 return;
5260             if (e1->op == TOKint64)
5261             {
5262                 e->error("cannot slice invalid pointer %s of value %s", e->e1->toChars(), e1->toChars());
5263                 result = CTFEExp::cantexp;
5264                 return;
5265             }
5266 
5267             /* Evaluate lower and upper bounds of slice
5268              */
5269             Expression *lwr = interpret(e->lwr, istate);
5270             if (exceptionOrCant(lwr))
5271                 return;
5272             Expression *upr = interpret(e->upr, istate);
5273             if (exceptionOrCant(upr))
5274                 return;
5275             uinteger_t ilwr = lwr->toInteger();
5276             uinteger_t iupr = upr->toInteger();
5277 
5278             dinteger_t ofs;
5279             Expression *agg = getAggregateFromPointer(e1, &ofs);
5280             ilwr += ofs;
5281             iupr += ofs;
5282             if (agg->op == TOKnull)
5283             {
5284                 if (iupr == ilwr)
5285                 {
5286                     result = new NullExp(e->loc);
5287                     result->type = e->type;
5288                     return;
5289                 }
5290                 e->error("cannot slice null pointer %s", e->e1->toChars());
5291                 result = CTFEExp::cantexp;
5292                 return;
5293             }
5294             if (agg->op == TOKsymoff)
5295             {
5296                 e->error("slicing pointers to static variables is not supported in CTFE");
5297                 result = CTFEExp::cantexp;
5298                 return;
5299             }
5300             if (agg->op != TOKarrayliteral && agg->op != TOKstring)
5301             {
5302                 e->error("pointer %s cannot be sliced at compile time (it does not point to an array)", e->e1->toChars());
5303                 result = CTFEExp::cantexp;
5304                 return;
5305             }
5306             assert(agg->op == TOKarrayliteral || agg->op == TOKstring);
5307             dinteger_t len = ArrayLength(Type::tsize_t, agg).exp()->toInteger();
5308             //Type *pointee = ((TypePointer *)agg->type)->next;
5309             if (iupr > (len + 1) || iupr < ilwr)
5310             {
5311                 e->error("pointer slice [%lld..%lld] exceeds allocated memory block [0..%lld]", ilwr, iupr, len);
5312                 result = CTFEExp::cantexp;
5313                 return;
5314             }
5315             if (ofs != 0)
5316             {
5317                 lwr = new IntegerExp(e->loc, ilwr, lwr->type);
5318                 upr = new IntegerExp(e->loc, iupr, upr->type);
5319             }
5320             new(pue) SliceExp(e->loc, agg, lwr, upr);
5321             result = pue->exp();
5322             result->type = e->type;
5323             return;
5324         }
5325 
5326         Expression *e1 = interpret(e->e1, istate);
5327         if (exceptionOrCant(e1))
5328             return;
5329 
5330         if (!e->lwr)
5331         {
5332             result = paintTypeOntoLiteral(e->type, e1);
5333             return;
5334         }
5335 
5336         if (e1->op == TOKvector)
5337         {
5338             e1 = interpretVectorToArray(pue, (VectorExp *)e1);
5339             e1 = (e1 == pue->exp()) ? pue->copy() : e1;
5340         }
5341 
5342         /* Set the $ variable
5343          */
5344         if (e1->op != TOKarrayliteral && e1->op != TOKstring && e1->op != TOKnull && e1->op != TOKslice && e1->op != TOKvector)
5345         {
5346             e->error("cannot determine length of %s at compile time", e1->toChars());
5347             result = CTFEExp::cantexp;
5348             return;
5349         }
5350         uinteger_t dollar = resolveArrayLength(e1);
5351         if (e->lengthVar)
5352         {
5353             IntegerExp *dollarExp = new IntegerExp(e->loc, dollar, Type::tsize_t);
5354             ctfeStack.push(e->lengthVar);
5355             setValue(e->lengthVar, dollarExp);
5356         }
5357 
5358         /* Evaluate lower and upper bounds of slice
5359          */
5360         Expression *lwr = interpret(e->lwr, istate);
5361         if (exceptionOrCant(lwr))
5362         {
5363             if (e->lengthVar)
5364                 ctfeStack.pop(e->lengthVar);
5365             return;
5366         }
5367         Expression *upr = interpret(e->upr, istate);
5368         if (exceptionOrCant(upr))
5369         {
5370             if (e->lengthVar)
5371                 ctfeStack.pop(e->lengthVar);
5372             return;
5373         }
5374         if (e->lengthVar)
5375             ctfeStack.pop(e->lengthVar);    // $ is defined only inside [L..U]
5376 
5377         uinteger_t ilwr = lwr->toInteger();
5378         uinteger_t iupr = upr->toInteger();
5379         if (e1->op == TOKnull)
5380         {
5381             if (ilwr == 0 && iupr == 0)
5382             {
5383                 result = e1;
5384                 return;
5385             }
5386             e1->error("slice [%llu..%llu] is out of bounds", ilwr, iupr);
5387             result = CTFEExp::cantexp;
5388             return;
5389         }
5390         if (e1->op == TOKslice)
5391         {
5392             SliceExp *se = (SliceExp *)e1;
5393             // Simplify slice of slice:
5394             //  aggregate[lo1..up1][lwr..upr] ---> aggregate[lwr'..upr']
5395             uinteger_t lo1 = se->lwr->toInteger();
5396             uinteger_t up1 = se->upr->toInteger();
5397             if (ilwr > iupr || iupr > up1 - lo1)
5398             {
5399                 e->error("slice[%llu..%llu] exceeds array bounds[%llu..%llu]", ilwr, iupr, lo1, up1);
5400                 result = CTFEExp::cantexp;
5401                 return;
5402             }
5403             ilwr += lo1;
5404             iupr += lo1;
5405             new(pue) SliceExp(e->loc, se->e1, new IntegerExp(e->loc, ilwr, lwr->type), new IntegerExp(e->loc, iupr, upr->type));
5406             result = pue->exp();
5407             result->type = e->type;
5408             return;
5409         }
5410         if (e1->op == TOKarrayliteral || e1->op == TOKstring)
5411         {
5412             if (iupr < ilwr || dollar < iupr)
5413             {
5414                 e->error("slice [%lld..%lld] exceeds array bounds [0..%lld]", ilwr, iupr, dollar);
5415                 result = CTFEExp::cantexp;
5416                 return;
5417             }
5418         }
5419         new(pue) SliceExp(e->loc, e1, lwr, upr);
5420         result = pue->exp();
5421         result->type = e->type;
5422     }
5423 
visit(InExp * e)5424     void visit(InExp *e)
5425     {
5426         Expression *e1 = interpret(e->e1, istate);
5427         if (exceptionOrCant(e1))
5428             return;
5429         Expression *e2 = interpret(e->e2, istate);
5430         if (exceptionOrCant(e2))
5431             return;
5432         if (e2->op == TOKnull)
5433         {
5434             new(pue) NullExp(e->loc, e->type);
5435             result = pue->exp();
5436             return;
5437         }
5438         if (e2->op != TOKassocarrayliteral)
5439         {
5440             e->error("%s cannot be interpreted at compile time", e->toChars());
5441             result = CTFEExp::cantexp;
5442             return;
5443         }
5444 
5445         e1 = resolveSlice(e1);
5446         result = findKeyInAA(e->loc, (AssocArrayLiteralExp *)e2, e1);
5447         if (exceptionOrCant(result))
5448             return;
5449         if (!result)
5450         {
5451             new(pue) NullExp(e->loc, e->type);
5452             result = pue->exp();
5453         }
5454         else
5455         {
5456             // Create a CTFE pointer &aa[index]
5457             result = new IndexExp(e->loc, e2, e1);
5458             result->type = e->type->nextOf();
5459             new(pue) AddrExp(e->loc, result, e->type);
5460             result = pue->exp();
5461         }
5462     }
5463 
visit(CatExp * e)5464     void visit(CatExp *e)
5465     {
5466         UnionExp ue1;
5467         Expression *e1 = interpret(&ue1, e->e1, istate);
5468         if (exceptionOrCant(e1))
5469             return;
5470 
5471         UnionExp ue2;
5472         Expression *e2 = interpret(&ue2, e->e2, istate);
5473         if (exceptionOrCant(e2))
5474             return;
5475 
5476         UnionExp e1tmp;
5477         e1 = resolveSlice(e1, &e1tmp);
5478 
5479         UnionExp e2tmp;
5480         e2 = resolveSlice(e2, &e2tmp);
5481 
5482         /* e1 and e2 can't go on the stack because of x~[y] and [x]~y will
5483          * result in [x,y] and then x or y is on the stack.
5484          * But if they are both strings, we can, because it isn't the x~[y] case.
5485          */
5486         if (!(e1->op == TOKstring && e2->op == TOKstring))
5487         {
5488             if (e1 == ue1.exp())
5489                 e1 = ue1.copy();
5490             if (e2 == ue2.exp())
5491                 e2 = ue2.copy();
5492         }
5493 
5494         *pue = ctfeCat(e->loc, e->type, e1, e2);
5495         result = pue->exp();
5496 
5497         if (CTFEExp::isCantExp(result))
5498         {
5499             e->error("%s cannot be interpreted at compile time", e->toChars());
5500             return;
5501         }
5502         // We know we still own it, because we interpreted both e1 and e2
5503         if (result->op == TOKarrayliteral)
5504         {
5505             ArrayLiteralExp *ale = (ArrayLiteralExp *)result;
5506             ale->ownedByCtfe = OWNEDctfe;
5507 
5508             // Bugzilla 14686
5509             for (size_t i = 0; i < ale->elements->dim; i++)
5510             {
5511                 Expression *ex = evaluatePostblit(istate, (*ale->elements)[i]);
5512                 if (exceptionOrCant(ex))
5513                     return;
5514             }
5515         }
5516         if (result->op == TOKstring)
5517             ((StringExp *)result)->ownedByCtfe = OWNEDctfe;
5518     }
5519 
visit(DeleteExp * e)5520     void visit(DeleteExp *e)
5521     {
5522         result = interpret(e->e1, istate);
5523         if (exceptionOrCant(result))
5524             return;
5525 
5526         if (result->op == TOKnull)
5527         {
5528             result = CTFEExp::voidexp;
5529             return;
5530         }
5531 
5532         Type *tb = e->e1->type->toBasetype();
5533         switch (tb->ty)
5534         {
5535         case Tclass:
5536         {
5537             if (result->op != TOKclassreference)
5538             {
5539                 e->error("delete on invalid class reference '%s'", result->toChars());
5540                 result = CTFEExp::cantexp;
5541                 return;
5542             }
5543 
5544             ClassReferenceExp *cre = (ClassReferenceExp *)result;
5545             ClassDeclaration *cd = cre->originalClass();
5546             if (cd->aggDelete)
5547             {
5548                 e->error("member deallocators not supported by CTFE");
5549                 result = CTFEExp::cantexp;
5550                 return;
5551             }
5552 
5553             if (cd->dtor)
5554             {
5555                 result = interpretFunction(pue, cd->dtor, istate, NULL, cre);
5556                 if (exceptionOrCant(result))
5557                     return;
5558             }
5559             break;
5560         }
5561 
5562         case Tpointer:
5563         {
5564             tb = ((TypePointer *)tb)->next->toBasetype();
5565             if (tb->ty == Tstruct)
5566             {
5567                 if (result->op != TOKaddress ||
5568                     ((AddrExp *)result)->e1->op != TOKstructliteral)
5569                 {
5570                     e->error("delete on invalid struct pointer '%s'", result->toChars());
5571                     result = CTFEExp::cantexp;
5572                     return;
5573                 }
5574 
5575                 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
5576                 StructLiteralExp *sle = (StructLiteralExp *)((AddrExp *)result)->e1;
5577                 if (sd->aggDelete)
5578                 {
5579                     e->error("member deallocators not supported by CTFE");
5580                     result = CTFEExp::cantexp;
5581                     return;
5582                 }
5583 
5584                 if (sd->dtor)
5585                 {
5586                     result = interpretFunction(pue, sd->dtor, istate, NULL, sle);
5587                     if (exceptionOrCant(result))
5588                         return;
5589                 }
5590             }
5591             break;
5592         }
5593 
5594         case Tarray:
5595         {
5596             Type *tv = tb->nextOf()->baseElemOf();
5597             if (tv->ty == Tstruct)
5598             {
5599                 if (result->op != TOKarrayliteral)
5600                 {
5601                     e->error("delete on invalid struct array '%s'", result->toChars());
5602                     result = CTFEExp::cantexp;
5603                     return;
5604                 }
5605 
5606                 StructDeclaration *sd = ((TypeStruct *)tv)->sym;
5607                 if (sd->aggDelete)
5608                 {
5609                     e->error("member deallocators not supported by CTFE");
5610                     result = CTFEExp::cantexp;
5611                     return;
5612                 }
5613 
5614                 if (sd->dtor)
5615                 {
5616                     ArrayLiteralExp *ale = (ArrayLiteralExp *)result;
5617                     for (size_t i = 0; i < ale->elements->dim; i++)
5618                     {
5619                         Expression *el = (*ale->elements)[i];
5620                         result = interpretFunction(pue, sd->dtor, istate, NULL, el);
5621                         if (exceptionOrCant(result))
5622                             return;
5623                     }
5624                 }
5625             }
5626             break;
5627         }
5628 
5629         default:
5630             assert(0);
5631         }
5632         result = CTFEExp::voidexp;
5633     }
5634 
visit(CastExp * e)5635     void visit(CastExp *e)
5636     {
5637         Expression *e1 = interpret(e->e1, istate, goal);
5638         if (exceptionOrCant(e1))
5639             return;
5640         // If the expression has been cast to void, do nothing.
5641         if (e->to->ty == Tvoid)
5642         {
5643             result = CTFEExp::voidexp;
5644             return;
5645         }
5646         if (e->to->ty == Tpointer && e1->op != TOKnull)
5647         {
5648             Type *pointee = ((TypePointer *)e->type)->next;
5649             // Implement special cases of normally-unsafe casts
5650             if (e1->op == TOKint64)
5651             {
5652                 // Happens with Windows HANDLEs, for example.
5653                 result = paintTypeOntoLiteral(pue, e->to, e1);
5654                 return;
5655             }
5656             bool castToSarrayPointer = false;
5657             bool castBackFromVoid = false;
5658             if (e1->type->ty == Tarray || e1->type->ty == Tsarray || e1->type->ty == Tpointer)
5659             {
5660                 // Check for unsupported type painting operations
5661                 // For slices, we need the type being sliced,
5662                 // since it may have already been type painted
5663                 Type *elemtype = e1->type->nextOf();
5664                 if (e1->op == TOKslice)
5665                     elemtype = ((SliceExp *)e1)->e1->type->nextOf();
5666                 // Allow casts from X* to void *, and X** to void** for any X.
5667                 // But don't allow cast from X* to void**.
5668                 // So, we strip all matching * from source and target to find X.
5669                 // Allow casts to X* from void* only if the 'void' was originally an X;
5670                 // we check this later on.
5671                 Type *ultimatePointee = pointee;
5672                 Type *ultimateSrc = elemtype;
5673                 while (ultimatePointee->ty == Tpointer && ultimateSrc->ty == Tpointer)
5674                 {
5675                     ultimatePointee = ultimatePointee->nextOf();
5676                     ultimateSrc = ultimateSrc->nextOf();
5677                 }
5678                 if (ultimatePointee->ty == Tsarray && ultimatePointee->nextOf()->equivalent(ultimateSrc))
5679                 {
5680                     castToSarrayPointer = true;
5681                 }
5682                 else if (ultimatePointee->ty != Tvoid && ultimateSrc->ty != Tvoid &&
5683                     !isSafePointerCast(elemtype, pointee))
5684                 {
5685                     e->error("reinterpreting cast from %s* to %s* is not supported in CTFE",
5686                         elemtype->toChars(), pointee->toChars());
5687                     result = CTFEExp::cantexp;
5688                     return;
5689                 }
5690                 if (ultimateSrc->ty == Tvoid)
5691                     castBackFromVoid = true;
5692             }
5693 
5694             if (e1->op == TOKslice)
5695             {
5696                 SliceExp *se = (SliceExp *)e1;
5697                 if (se->e1->op == TOKnull)
5698                 {
5699                     result = paintTypeOntoLiteral(pue, e->type, se->e1);
5700                     return;
5701                 }
5702                 // Create a CTFE pointer &aggregate[1..2]
5703                 IndexExp *ei = new IndexExp(e->loc, se->e1, se->lwr);
5704                 ei->type = e->type->nextOf();
5705                 new(pue) AddrExp(e->loc, ei, e->type);
5706                 result = pue->exp();
5707                 return;
5708             }
5709             if (e1->op == TOKarrayliteral || e1->op == TOKstring)
5710             {
5711                 // Create a CTFE pointer &[1,2,3][0] or &"abc"[0]
5712                 IndexExp *ei = new IndexExp(e->loc, e1, new IntegerExp(e->loc, 0, Type::tsize_t));
5713                 ei->type = e->type->nextOf();
5714                 new(pue) AddrExp(e->loc, ei, e->type);
5715                 result = pue->exp();
5716                 return;
5717             }
5718             if (e1->op == TOKindex && !((IndexExp *)e1)->e1->type->equals(e1->type))
5719             {
5720                 // type painting operation
5721                 IndexExp *ie = (IndexExp *)e1;
5722                 if (castBackFromVoid)
5723                 {
5724                     // get the original type. For strings, it's just the type...
5725                     Type *origType = ie->e1->type->nextOf();
5726                     // ..but for arrays of type void*, it's the type of the element
5727                     if (ie->e1->op == TOKarrayliteral && ie->e2->op == TOKint64)
5728                     {
5729                         ArrayLiteralExp *ale = (ArrayLiteralExp *)ie->e1;
5730                         const size_t indx = (size_t)ie->e2->toInteger();
5731                         if (indx < ale->elements->dim)
5732                         {
5733                             Expression *xx = (*ale->elements)[indx];
5734                             if (xx)
5735                             {
5736                                 if (xx->op == TOKindex)
5737                                     origType = ((IndexExp *)xx)->e1->type->nextOf();
5738                                 else if (xx->op == TOKaddress)
5739                                     origType= ((AddrExp *)xx)->e1->type;
5740                                 else if (xx->op == TOKvar)
5741                                     origType = ((VarExp *)xx)->var->type;
5742                             }
5743                         }
5744                     }
5745                     if (!isSafePointerCast(origType, pointee))
5746                     {
5747                         e->error("using void* to reinterpret cast from %s* to %s* is not supported in CTFE", origType->toChars(), pointee->toChars());
5748                         result = CTFEExp::cantexp;
5749                         return;
5750                     }
5751                 }
5752                 new(pue) IndexExp(e1->loc, ie->e1, ie->e2);
5753                 result = pue->exp();
5754                 result->type = e->type;
5755                 return;
5756             }
5757             if (e1->op == TOKaddress)
5758             {
5759                 AddrExp *ae = (AddrExp *)e1;
5760                 Type *origType = ae->e1->type;
5761                 if (isSafePointerCast(origType, pointee))
5762                 {
5763                     new(pue) AddrExp(e->loc, ae->e1, e->type);
5764                     result = pue->exp();
5765                     return;
5766                 }
5767                 if (castToSarrayPointer && pointee->toBasetype()->ty == Tsarray && ae->e1->op == TOKindex)
5768                 {
5769                     // &val[idx]
5770                     dinteger_t dim = ((TypeSArray *)pointee->toBasetype())->dim->toInteger();
5771                     IndexExp *ie = (IndexExp *)ae->e1;
5772                     Expression *lwr = ie->e2;
5773                     Expression *upr = new IntegerExp(ie->e2->loc, ie->e2->toInteger() + dim, Type::tsize_t);
5774 
5775                     // Create a CTFE pointer &val[idx..idx+dim]
5776                     SliceExp *er = new SliceExp(e->loc, ie->e1, lwr, upr);
5777                     er->type = pointee;
5778                     new(pue) AddrExp(e->loc, er, e->type);
5779                     result = pue->exp();
5780                     return;
5781                 }
5782             }
5783             if (e1->op == TOKvar || e1->op == TOKsymoff)
5784             {
5785                 // type painting operation
5786                 Type *origType = ((SymbolExp *)e1)->var->type;
5787                 if (castBackFromVoid && !isSafePointerCast(origType, pointee))
5788                 {
5789                     e->error("using void* to reinterpret cast from %s* to %s* is not supported in CTFE", origType->toChars(), pointee->toChars());
5790                     result = CTFEExp::cantexp;
5791                     return;
5792                 }
5793                 if (e1->op == TOKvar)
5794                     new(pue) VarExp(e->loc, ((VarExp *)e1)->var);
5795                 else
5796                     new(pue) SymOffExp(e->loc, ((SymOffExp *)e1)->var, ((SymOffExp *)e1)->offset);
5797                 result = pue->exp();
5798                 result->type = e->to;
5799                 return;
5800             }
5801 
5802             // Check if we have a null pointer (eg, inside a struct)
5803             e1 = interpret(e1, istate);
5804             if (e1->op != TOKnull)
5805             {
5806                 e->error("pointer cast from %s to %s is not supported at compile time", e1->type->toChars(), e->to->toChars());
5807                 result = CTFEExp::cantexp;
5808                 return;
5809             }
5810         }
5811         if (e->to->ty == Tsarray && e->e1->type->ty == Tvector)
5812         {
5813             // Special handling for: cast(float[4])__vector([w, x, y, z])
5814             e1 = interpret(e->e1, istate);
5815             if (exceptionOrCant(e1))
5816                 return;
5817             assert(e1->op == TOKvector);
5818             e1 = interpretVectorToArray(pue, (VectorExp *)e1);
5819         }
5820         if (e->to->ty == Tarray && e1->op == TOKslice)
5821         {
5822             // Note that the slice may be void[], so when checking for dangerous
5823             // casts, we need to use the original type, which is se->e1.
5824             SliceExp *se = (SliceExp *)e1;
5825             if (!isSafePointerCast(se->e1->type->nextOf(), e->to->nextOf()))
5826             {
5827                 e->error("array cast from %s to %s is not supported at compile time", se->e1->type->toChars(), e->to->toChars());
5828                 result = CTFEExp::cantexp;
5829                 return;
5830             }
5831             new(pue) SliceExp(e1->loc, se->e1, se->lwr, se->upr);
5832             result = pue->exp();
5833             result->type = e->to;
5834             return;
5835         }
5836         // Disallow array type painting, except for conversions between built-in
5837         // types of identical size.
5838         if ((e->to->ty == Tsarray || e->to->ty == Tarray) && (e1->type->ty == Tsarray || e1->type->ty == Tarray) && !isSafePointerCast(e1->type->nextOf(), e->to->nextOf()))
5839         {
5840             e->error("array cast from %s to %s is not supported at compile time", e1->type->toChars(), e->to->toChars());
5841             result = CTFEExp::cantexp;
5842             return;
5843         }
5844         if (e->to->ty == Tsarray)
5845             e1 = resolveSlice(e1);
5846         Type *tobt = e->to->toBasetype();
5847         if (tobt->ty == Tbool && e1->type->ty == Tpointer)
5848         {
5849             new(pue) IntegerExp(e->loc, e1->op != TOKnull, e->to);
5850             result = pue->exp();
5851             return;
5852         }
5853         else if (tobt->isTypeBasic() && e1->op == TOKnull)
5854         {
5855             if (tobt->isintegral())
5856                 new(pue) IntegerExp(e->loc, 0, e->to);
5857             else if (tobt->isreal())
5858                 new(pue) RealExp(e->loc, CTFloat::zero, e->to);
5859             result = pue->exp();
5860             return;
5861         }
5862         result = ctfeCast(pue, e->loc, e->type, e->to, e1);
5863     }
5864 
visit(AssertExp * e)5865     void visit(AssertExp *e)
5866     {
5867         Expression *e1 = interpret(pue, e->e1, istate);
5868         if (exceptionOrCant(e1))
5869             return;
5870         if (isTrueBool(e1))
5871         {
5872         }
5873         else if (e1->isBool(false))
5874         {
5875             if (e->msg)
5876             {
5877                 UnionExp ue;
5878                 result = interpret(&ue, e->msg, istate);
5879                 if (exceptionOrCant(result))
5880                     return;
5881                 e->error("%s", result->toChars());
5882             }
5883             else
5884                 e->error("%s failed", e->toChars());
5885             result = CTFEExp::cantexp;
5886             return;
5887         }
5888         else
5889         {
5890             e->error("%s is not a compile time boolean expression", e1->toChars());
5891             result = CTFEExp::cantexp;
5892             return;
5893         }
5894         result = e1;
5895         return;
5896     }
5897 
visit(PtrExp * e)5898     void visit(PtrExp *e)
5899     {
5900         // Check for int<->float and long<->double casts.
5901         if (e->e1->op == TOKsymoff)
5902         {
5903             SymOffExp *soe = (SymOffExp *)e->e1;
5904             if (soe->offset == 0 && soe->var->isVarDeclaration() && isFloatIntPaint(e->type, soe->var->type))
5905             {
5906                 // *(cast(int*)&v), where v is a float variable
5907                 result = paintFloatInt(pue, getVarExp(e->loc, istate, soe->var, ctfeNeedRvalue), e->type);
5908                 return;
5909             }
5910         }
5911 
5912         if (e->e1->op == TOKcast)
5913         {
5914             CastExp *ce1 = (CastExp *)e->e1;
5915             if (ce1->e1->op == TOKaddress)
5916             {
5917                 AddrExp *ae11 = (AddrExp *)ce1->e1;
5918                 // *(cast(int*)&x), where x is a float expression
5919                 Expression *x = ae11->e1;
5920                 if (isFloatIntPaint(e->type, x->type))
5921                 {
5922                     result = paintFloatInt(pue, interpret(x, istate), e->type);
5923                     return;
5924                 }
5925             }
5926         }
5927 
5928         // Constant fold *(&structliteral + offset)
5929         if (e->e1->op == TOKadd)
5930         {
5931             AddExp *ae = (AddExp *)e->e1;
5932             if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
5933             {
5934                 AddrExp *ade = (AddrExp *)ae->e1;
5935                 Expression *ex = interpret(ade->e1, istate);
5936                 if (exceptionOrCant(ex))
5937                     return;
5938                 if (ex->op == TOKstructliteral)
5939                 {
5940                     StructLiteralExp *se = (StructLiteralExp *)ex;
5941                     dinteger_t offset = ae->e2->toInteger();
5942                     result = se->getField(e->type, (unsigned)offset);
5943                     if (result)
5944                         return;
5945                 }
5946             }
5947         }
5948 
5949         // It's possible we have an array bounds error. We need to make sure it
5950         // errors with this line number, not the one where the pointer was set.
5951         result = interpret(e->e1, istate);
5952         if (exceptionOrCant(result))
5953             return;
5954 
5955         if (result->op == TOKfunction)
5956             return;
5957         if (result->op == TOKsymoff)
5958         {
5959             SymOffExp *soe = (SymOffExp *)result;
5960             if (soe->offset == 0 && soe->var->isFuncDeclaration())
5961                 return;
5962             e->error("cannot dereference pointer to static variable %s at compile time", soe->var->toChars());
5963             result = CTFEExp::cantexp;
5964             return;
5965         }
5966 
5967         if (result->op != TOKaddress)
5968         {
5969             if (result->op == TOKnull)
5970                 e->error("dereference of null pointer '%s'", e->e1->toChars());
5971             else
5972                 e->error("dereference of invalid pointer '%s'", result->toChars());
5973             result = CTFEExp::cantexp;
5974             return;
5975         }
5976 
5977         // *(&x) ==> x
5978         result = ((AddrExp *)result)->e1;
5979 
5980         if (result->op == TOKslice && e->type->toBasetype()->ty == Tsarray)
5981         {
5982             /* aggr[lwr..upr]
5983              * upr may exceed the upper boundary of aggr, but the check is deferred
5984              * until those out-of-bounds elements will be touched.
5985              */
5986             return;
5987         }
5988         result = interpret(pue, result, istate, goal);
5989         if (exceptionOrCant(result))
5990             return;
5991     }
5992 
visit(DotVarExp * e)5993     void visit(DotVarExp *e)
5994     {
5995         Expression *ex = interpret(e->e1, istate);
5996         if (exceptionOrCant(ex))
5997             return;
5998 
5999         if (FuncDeclaration *f = e->var->isFuncDeclaration())
6000         {
6001             if (ex == e->e1)
6002                 result = e; // optimize: reuse this CTFE reference
6003             else
6004             {
6005                 new(pue) DotVarExp(e->loc, ex, f, false);
6006                 result = pue->exp();
6007                 result->type = e->type;
6008             }
6009             return;
6010         }
6011 
6012         VarDeclaration *v = e->var->isVarDeclaration();
6013         if (!v)
6014         {
6015             e->error("CTFE internal error: %s", e->toChars());
6016             result = CTFEExp::cantexp;
6017             return;
6018         }
6019 
6020         if (ex->op == TOKnull)
6021         {
6022             if (ex->type->toBasetype()->ty == Tclass)
6023                 e->error("class '%s' is null and cannot be dereferenced", e->e1->toChars());
6024             else
6025                 e->error("CTFE internal error: null this '%s'", e->e1->toChars());
6026             result = CTFEExp::cantexp;
6027             return;
6028         }
6029         if (ex->op != TOKstructliteral && ex->op != TOKclassreference)
6030         {
6031             e->error("%s.%s is not yet implemented at compile time", e->e1->toChars(), e->var->toChars());
6032             result = CTFEExp::cantexp;
6033             return;
6034         }
6035 
6036         StructLiteralExp *se;
6037         int i;
6038 
6039         // We can't use getField, because it makes a copy
6040         if (ex->op == TOKclassreference)
6041         {
6042             se = ((ClassReferenceExp *)ex)->value;
6043             i  = ((ClassReferenceExp *)ex)->findFieldIndexByName(v);
6044         }
6045         else
6046         {
6047             se = (StructLiteralExp *)ex;
6048             i  = findFieldIndexByName(se->sd, v);
6049         }
6050         if (i == -1)
6051         {
6052             e->error("couldn't find field %s of type %s in %s", v->toChars(), e->type->toChars(), se->toChars());
6053             result = CTFEExp::cantexp;
6054             return;
6055         }
6056 
6057         if (goal == ctfeNeedLvalue)
6058         {
6059             Expression *ev = (*se->elements)[i];
6060             if (!ev || ev->op == TOKvoid)
6061                 (*se->elements)[i] = voidInitLiteral(e->type, v).copy();
6062             // just return the (simplified) dotvar expression as a CTFE reference
6063             if (e->e1 == ex)
6064                 result = e;
6065             else
6066             {
6067                 new(pue) DotVarExp(e->loc, ex, v);
6068                 result = pue->exp();
6069                 result->type = e->type;
6070             }
6071             return;
6072         }
6073 
6074         result = (*se->elements)[i];
6075         if (!result)
6076         {
6077             // https://issues.dlang.org/show_bug.cgi?id=19897
6078             // Zero-length fields don't have an initializer.
6079             if (v->type->size() == 0)
6080                 result = voidInitLiteral(e->type, v).copy();
6081             else
6082             {
6083                 e->error("Internal Compiler Error: null field %s", v->toChars());
6084                 result = CTFEExp::cantexp;
6085                 return;
6086             }
6087         }
6088         if (result->op == TOKvoid)
6089         {
6090             VoidInitExp *ve = (VoidInitExp *)result;
6091             const char *s = ve->var->toChars();
6092             if (v->overlapped)
6093             {
6094                 e->error("reinterpretation through overlapped field %s is not allowed in CTFE", s);
6095                 result = CTFEExp::cantexp;
6096                 return;
6097             }
6098             e->error("cannot read uninitialized variable %s in CTFE", s);
6099             result = CTFEExp::cantexp;
6100             return;
6101         }
6102 
6103         if (v->type->ty != result->type->ty && v->type->ty == Tsarray)
6104         {
6105             // Block assignment from inside struct literals
6106             TypeSArray *tsa = (TypeSArray *)v->type;
6107             size_t len = (size_t)tsa->dim->toInteger();
6108             UnionExp ue;
6109             result = createBlockDuplicatedArrayLiteral(&ue, ex->loc, v->type, ex, len);
6110             if (result == ue.exp())
6111                 result = ue.copy();
6112             (*se->elements)[i] = result;
6113         }
6114     }
6115 
visit(RemoveExp * e)6116     void visit(RemoveExp *e)
6117     {
6118         Expression *agg = interpret(e->e1, istate);
6119         if (exceptionOrCant(agg))
6120             return;
6121         Expression *index = interpret(e->e2, istate);
6122         if (exceptionOrCant(index))
6123             return;
6124         if (agg->op == TOKnull)
6125         {
6126             result = CTFEExp::voidexp;
6127             return;
6128         }
6129         assert(agg->op == TOKassocarrayliteral);
6130         AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)agg;
6131         Expressions *keysx = aae->keys;
6132         Expressions *valuesx = aae->values;
6133         size_t removed = 0;
6134         for (size_t j = 0; j < valuesx->dim; ++j)
6135         {
6136             Expression *ekey = (*keysx)[j];
6137             int eq = ctfeEqual(e->loc, TOKequal, ekey, index);
6138             if (eq)
6139                 ++removed;
6140             else if (removed != 0)
6141             {
6142                 (*keysx)[j - removed] = ekey;
6143                 (*valuesx)[j - removed] = (*valuesx)[j];
6144             }
6145         }
6146         valuesx->dim = valuesx->dim - removed;
6147         keysx->dim = keysx->dim - removed;
6148         new(pue) IntegerExp(e->loc, removed ? 1 : 0, Type::tbool);
6149         result = pue->exp();
6150     }
6151 
visit(ClassReferenceExp * e)6152     void visit(ClassReferenceExp *e)
6153     {
6154         //printf("ClassReferenceExp::interpret() %s\n", e->value->toChars());
6155         result = e;
6156     }
6157 
visit(VoidInitExp * e)6158     void visit(VoidInitExp *e)
6159     {
6160         e->error("CTFE internal error: trying to read uninitialized variable");
6161         assert(0);
6162         result = CTFEExp::cantexp;
6163     }
6164 
visit(ThrownExceptionExp * e)6165     void visit(ThrownExceptionExp *e)
6166     {
6167         assert(0); // This should never be interpreted
6168         result = e;
6169     }
6170 
6171 };
6172 
6173 /********************************************
6174  * Interpret the expression.
6175  * Params:
6176  *    pue = non-null pointer to temporary storage that can be used to store the return value
6177  *    e = Expression to interpret
6178  *    istate = context
6179  *    goal = what the result will be used for
6180  * Returns:
6181  *    resulting expression
6182  */
6183 
interpret(UnionExp * pue,Expression * e,InterState * istate,CtfeGoal goal)6184 static Expression *interpret(UnionExp *pue, Expression *e, InterState *istate, CtfeGoal goal)
6185 {
6186     if (!e)
6187         return NULL;
6188     Interpreter v(pue, istate, goal);
6189     e->accept(&v);
6190     Expression *ex = v.result;
6191     assert(goal == ctfeNeedNothing || ex != NULL);
6192     return ex;
6193 }
6194 
6195 ///
interpret(Expression * e,InterState * istate,CtfeGoal goal)6196 Expression *interpret(Expression *e, InterState *istate, CtfeGoal goal)
6197 {
6198     UnionExp ue;
6199     Expression *result = interpret(&ue, e, istate, goal);
6200     if (result == ue.exp())
6201         result = ue.copy();
6202     return result;
6203 }
6204 
6205 /***********************************
6206  * Interpret the statement.
6207  * Params:
6208  *    pue = non-null pointer to temporary storage that can be used to store the return value
6209  *    s = Statement to interpret
6210  *    istate = context
6211  * Returns:
6212  *      NULL    continue to next statement
6213  *      TOKcantexp      cannot interpret statement at compile time
6214  *      !NULL   expression from return statement, or thrown exception
6215  */
6216 
interpret(UnionExp * pue,Statement * s,InterState * istate)6217 static Expression *interpret(UnionExp *pue, Statement *s, InterState *istate)
6218 {
6219     if (!s)
6220         return NULL;
6221     Interpreter v(pue, istate, ctfeNeedNothing);
6222     s->accept(&v);
6223     return v.result;
6224 }
6225 
interpret(Statement * s,InterState * istate)6226 Expression *interpret(Statement *s, InterState *istate)
6227 {
6228     UnionExp ue;
6229     Expression *result = interpret(&ue, s, istate);
6230     if (result == ue.exp())
6231         result = ue.copy();
6232     return result;
6233 }
6234 
6235 /**
6236  * All results destined for use outside of CTFE need to have their CTFE-specific
6237  * features removed.
6238  * In particular,
6239  * 1. all slices must be resolved.
6240  * 2. all .ownedByCtfe set to OWNEDcode
6241  */
scrubReturnValue(Loc loc,Expression * e)6242 Expression *scrubReturnValue(Loc loc, Expression *e)
6243 {
6244     if (e->op == TOKclassreference)
6245     {
6246         StructLiteralExp *sle = ((ClassReferenceExp*)e)->value;
6247         if (Expression *ex = scrubStructLiteral(loc, sle))
6248             return ex;
6249     }
6250     else if (e->op == TOKvoid)
6251     {
6252         error(loc, "uninitialized variable '%s' cannot be returned from CTFE", ((VoidInitExp *)e)->var->toChars());
6253         return new ErrorExp();
6254     }
6255 
6256     e = resolveSlice(e);
6257 
6258     if (e->op == TOKstructliteral)
6259     {
6260         StructLiteralExp *sle = (StructLiteralExp *)e;
6261         if (Expression *ex = scrubStructLiteral(loc, sle))
6262             return ex;
6263     }
6264     else if (e->op == TOKstring)
6265     {
6266         ((StringExp *)e)->ownedByCtfe = OWNEDcode;
6267     }
6268     else if (e->op == TOKarrayliteral)
6269     {
6270         ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
6271         ale->ownedByCtfe = OWNEDcode;
6272         if (Expression *ex = scrubArray(loc, ale->elements))
6273             return ex;
6274     }
6275     else if (e->op == TOKassocarrayliteral)
6276     {
6277         AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
6278         aae->ownedByCtfe = OWNEDcode;
6279         if (Expression *ex = scrubArray(loc, aae->keys))
6280             return ex;
6281         if (Expression *ex = scrubArray(loc, aae->values))
6282             return ex;
6283         aae->type = toBuiltinAAType(aae->type);
6284     }
6285     else if (e->op == TOKvector)
6286     {
6287         VectorExp *ve = (VectorExp *)e;
6288         ve->ownedByCtfe = OWNEDcode;
6289         if (ve->e1->op == TOKarrayliteral)
6290         {
6291             ArrayLiteralExp *ale = (ArrayLiteralExp *)ve->e1;
6292             ale->ownedByCtfe = OWNEDcode;
6293             if (Expression *ex = scrubArray(loc, ale->elements))
6294                 return ex;
6295         }
6296     }
6297     return e;
6298 }
6299 
6300 /* Returns: true if e is void,
6301  * or is an array literal or struct literal of void elements.
6302  */
6303 static bool isVoid(Expression *e, bool checkArray = false)
6304 {
6305     if (e->op == TOKvoid)
6306         return true;
6307 
6308     if (checkArray && e->type->ty != Tsarray)
6309         return false;
6310 
6311     if (e->op == TOKarrayliteral)
6312         return isEntirelyVoid(((ArrayLiteralExp *)e)->elements);
6313 
6314     if (e->op == TOKstructliteral)
6315         return isEntirelyVoid(((StructLiteralExp *)e)->elements);
6316 
6317     return false;
6318 }
6319 
6320 // Return true if every element is either void,
6321 // or is an array literal or struct literal of void elements.
isEntirelyVoid(Expressions * elems)6322 bool isEntirelyVoid(Expressions *elems)
6323 {
6324     for (size_t i = 0; i < elems->dim; i++)
6325     {
6326         Expression *e = (*elems)[i];
6327         // It can be NULL for performance reasons,
6328         // see StructLiteralExp::interpret().
6329         if (e && !isVoid(e))
6330             return false;
6331     }
6332     return true;
6333 }
6334 
6335 // Scrub all members of an array. Return false if error
scrubArray(Loc loc,Expressions * elems,bool structlit)6336 Expression *scrubArray(Loc loc, Expressions *elems, bool structlit)
6337 {
6338     for (size_t i = 0; i < elems->dim; i++)
6339     {
6340         Expression *e = (*elems)[i];
6341         // It can be NULL for performance reasons,
6342         // see StructLiteralExp::interpret().
6343         if (!e)
6344             continue;
6345 
6346         // A struct .init may contain void members.
6347         // Static array members are a weird special case (bug 10994).
6348         if (structlit && isVoid(e, true))
6349         {
6350             e = NULL;
6351         }
6352         else
6353         {
6354             e = scrubReturnValue(loc, e);
6355             if (CTFEExp::isCantExp(e) || e->op == TOKerror)
6356                 return e;
6357         }
6358         (*elems)[i] = e;
6359     }
6360     return NULL;
6361 }
6362 
scrubStructLiteral(Loc loc,StructLiteralExp * sle)6363 Expression *scrubStructLiteral(Loc loc, StructLiteralExp *sle)
6364 {
6365     sle->ownedByCtfe = OWNEDcode;
6366     if (!(sle->stageflags & stageScrub))
6367     {
6368         const int old = sle->stageflags;
6369         sle->stageflags |= stageScrub;       // prevent infinite recursion
6370         if (Expression *ex = scrubArray(loc, sle->elements, true))
6371             return ex;
6372         sle->stageflags = old;
6373     }
6374     return NULL;
6375 }
6376 
6377 /**************************************
6378  * Transitively set all .ownedByCtfe to OWNEDcache
6379  */
scrubCacheValue(Expression * e)6380 Expression *scrubCacheValue(Expression *e)
6381 {
6382     if (!e)
6383         return e;
6384 
6385     if (e->op == TOKclassreference)
6386     {
6387         StructLiteralExp *sle = ((ClassReferenceExp*)e)->value;
6388         if (Expression *ex = scrubStructLiteralCache(sle))
6389             return ex;
6390     }
6391     else if (e->op == TOKstructliteral)
6392     {
6393         StructLiteralExp *sle = (StructLiteralExp *)e;
6394         if (Expression *ex = scrubStructLiteralCache(sle))
6395             return ex;
6396     }
6397     else if (e->op == TOKstring)
6398     {
6399         ((StringExp *)e)->ownedByCtfe = OWNEDcache;
6400     }
6401     else if (e->op == TOKarrayliteral)
6402     {
6403         ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
6404         ale->ownedByCtfe = OWNEDcache;
6405         if (Expression *ex = scrubArrayCache(ale->elements))
6406             return ex;
6407     }
6408     else if (e->op == TOKassocarrayliteral)
6409     {
6410         AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
6411         aae->ownedByCtfe = OWNEDcache;
6412         if (Expression *ex = scrubArrayCache(aae->keys))
6413             return ex;
6414         if (Expression *ex = scrubArrayCache(aae->values))
6415             return ex;
6416     }
6417     else if (e->op == TOKvector)
6418     {
6419         VectorExp *ve = (VectorExp *)e;
6420         ve->ownedByCtfe = OWNEDcache;
6421         if (ve->e1->op == TOKarrayliteral)
6422         {
6423             ArrayLiteralExp *ale = (ArrayLiteralExp *)ve->e1;
6424             ale->ownedByCtfe = OWNEDcache;
6425             if (Expression *ex = scrubArrayCache(ale->elements))
6426                 return ex;
6427         }
6428     }
6429     return e;
6430 }
6431 
scrubArrayCache(Expressions * elems)6432 Expression *scrubArrayCache(Expressions *elems)
6433 {
6434     for (size_t i = 0; i < elems->dim; i++)
6435     {
6436         Expression *e = (*elems)[i];
6437         (*elems)[i] = scrubCacheValue(e);
6438     }
6439     return NULL;
6440 }
6441 
scrubStructLiteralCache(StructLiteralExp * sle)6442 Expression *scrubStructLiteralCache(StructLiteralExp *sle)
6443 {
6444     sle->ownedByCtfe = OWNEDcache;
6445     if (!(sle->stageflags & stageScrub))
6446     {
6447         const int old = sle->stageflags;
6448         sle->stageflags |= stageScrub;       // prevent infinite recursion
6449         if (Expression *ex = scrubArrayCache(sle->elements))
6450             return ex;
6451         sle->stageflags = old;
6452     }
6453     return NULL;
6454 }
6455 
6456 /******************************* Special Functions ***************************/
6457 
interpret_length(UnionExp * pue,InterState * istate,Expression * earg)6458 static Expression *interpret_length(UnionExp *pue, InterState *istate, Expression *earg)
6459 {
6460     //printf("interpret_length()\n");
6461     earg = interpret(pue, earg, istate);
6462     if (exceptionOrCantInterpret(earg))
6463         return earg;
6464     dinteger_t len = 0;
6465     if (earg->op == TOKassocarrayliteral)
6466         len = ((AssocArrayLiteralExp *)earg)->keys->dim;
6467     else
6468         assert(earg->op == TOKnull);
6469     new(pue) IntegerExp(earg->loc, len, Type::tsize_t);
6470     return pue->exp();
6471 }
6472 
interpret_keys(UnionExp * pue,InterState * istate,Expression * earg,Type * returnType)6473 static Expression *interpret_keys(UnionExp *pue, InterState *istate, Expression *earg, Type *returnType)
6474 {
6475     earg = interpret(pue, earg, istate);
6476     if (exceptionOrCantInterpret(earg))
6477         return earg;
6478     if (earg->op == TOKnull)
6479     {
6480         new(pue) NullExp(earg->loc, earg->type);
6481         return pue->exp();
6482     }
6483     if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
6484         return NULL;
6485     assert(earg->op == TOKassocarrayliteral);
6486     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
6487     ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, returnType, aae->keys);
6488     ae->ownedByCtfe = aae->ownedByCtfe;
6489     *pue = copyLiteral(ae);
6490     return pue->exp();
6491 }
6492 
interpret_values(UnionExp * pue,InterState * istate,Expression * earg,Type * returnType)6493 static Expression *interpret_values(UnionExp *pue, InterState *istate, Expression *earg, Type *returnType)
6494 {
6495     earg = interpret(pue, earg, istate);
6496     if (exceptionOrCantInterpret(earg))
6497         return earg;
6498     if (earg->op == TOKnull)
6499     {
6500         new(pue) NullExp(earg->loc, earg->type);
6501         return pue->exp();
6502     }
6503     if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
6504         return NULL;
6505     assert(earg->op == TOKassocarrayliteral);
6506     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
6507     ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, returnType, aae->values);
6508     ae->ownedByCtfe = aae->ownedByCtfe;
6509     //printf("result is %s\n", e->toChars());
6510     *pue = copyLiteral(ae);
6511     return pue->exp();
6512 }
6513 
interpret_dup(UnionExp * pue,InterState * istate,Expression * earg)6514 Expression *interpret_dup(UnionExp *pue, InterState *istate, Expression *earg)
6515 {
6516     earg = interpret(pue, earg, istate);
6517     if (exceptionOrCantInterpret(earg))
6518         return earg;
6519     if (earg->op == TOKnull)
6520     {
6521         new(pue) NullExp(earg->loc, earg->type);
6522         return pue->exp();
6523     }
6524     if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
6525         return NULL;
6526     assert(earg->op == TOKassocarrayliteral);
6527     AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)copyLiteral(earg).copy();
6528     for (size_t i = 0; i < aae->keys->dim; i++)
6529     {
6530         if (Expression *e = evaluatePostblit(istate, (*aae->keys)[i]))
6531             return e;
6532         if (Expression *e = evaluatePostblit(istate, (*aae->values)[i]))
6533             return e;
6534     }
6535     aae->type = earg->type->mutableOf(); // repaint type from const(int[int]) to const(int)[int]
6536     //printf("result is %s\n", aae->toChars());
6537     return aae;
6538 }
6539 
6540 // signature is int delegate(ref Value) OR int delegate(ref Key, ref Value)
interpret_aaApply(UnionExp * pue,InterState * istate,Expression * aa,Expression * deleg)6541 Expression *interpret_aaApply(UnionExp *pue, InterState *istate, Expression *aa, Expression *deleg)
6542 {
6543     aa = interpret(aa, istate);
6544     if (exceptionOrCantInterpret(aa))
6545         return aa;
6546     if (aa->op != TOKassocarrayliteral)
6547     {
6548         new(pue) IntegerExp(deleg->loc, 0, Type::tsize_t);
6549         return pue->exp();
6550     }
6551 
6552     FuncDeclaration *fd = NULL;
6553     Expression *pthis = NULL;
6554     if (deleg->op == TOKdelegate)
6555     {
6556         fd = ((DelegateExp *)deleg)->func;
6557         pthis = ((DelegateExp *)deleg)->e1;
6558     }
6559     else if (deleg->op == TOKfunction)
6560         fd = ((FuncExp*)deleg)->fd;
6561 
6562     assert(fd && fd->fbody);
6563     assert(fd->parameters);
6564     size_t numParams = fd->parameters->dim;
6565     assert(numParams == 1 || numParams == 2);
6566 
6567     Parameter *fparam = Parameter::getNth(((TypeFunction *)fd->type)->parameters, numParams - 1);
6568     bool wantRefValue = 0 != (fparam->storageClass & (STCout | STCref));
6569 
6570     Expressions args;
6571     args.setDim(numParams);
6572 
6573     AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)aa;
6574     if (!ae->keys || ae->keys->dim == 0)
6575         return new IntegerExp(deleg->loc, 0, Type::tsize_t);
6576     Expression *eresult;
6577 
6578     for (size_t i = 0; i < ae->keys->dim; ++i)
6579     {
6580         Expression *ekey = (*ae->keys)[i];
6581         Expression *evalue = (*ae->values)[i];
6582         if (wantRefValue)
6583         {
6584             Type *t = evalue->type;
6585             evalue = new IndexExp(deleg->loc, ae, ekey);
6586             evalue->type = t;
6587         }
6588         args[numParams - 1] = evalue;
6589         if (numParams == 2)
6590             args[0] = ekey;
6591 
6592         UnionExp ue;
6593         eresult = interpretFunction(&ue, fd, istate, &args, pthis);
6594         if (eresult == ue.exp())
6595             eresult = ue.copy();
6596         if (exceptionOrCantInterpret(eresult))
6597             return eresult;
6598 
6599         assert(eresult->op == TOKint64);
6600         if (((IntegerExp *)eresult)->getInteger() != 0)
6601             return eresult;
6602     }
6603     return eresult;
6604 }
6605 
6606 /* Decoding UTF strings for foreach loops. Duplicates the functionality of
6607  * the twelve _aApplyXXn functions in aApply.d in the runtime.
6608  */
foreachApplyUtf(UnionExp * pue,InterState * istate,Expression * str,Expression * deleg,bool rvs)6609 static Expression *foreachApplyUtf(UnionExp *pue, InterState *istate, Expression *str, Expression *deleg, bool rvs)
6610 {
6611     FuncDeclaration *fd = NULL;
6612     Expression *pthis = NULL;
6613     if (deleg->op == TOKdelegate)
6614     {
6615         fd = ((DelegateExp *)deleg)->func;
6616         pthis = ((DelegateExp *)deleg)->e1;
6617     }
6618     else if (deleg->op == TOKfunction)
6619         fd = ((FuncExp*)deleg)->fd;
6620 
6621     assert(fd && fd->fbody);
6622     assert(fd->parameters);
6623     size_t numParams = fd->parameters->dim;
6624     assert(numParams == 1 || numParams == 2);
6625     Type *charType = (*fd->parameters)[numParams-1]->type;
6626     Type *indexType = numParams == 2 ? (*fd->parameters)[0]->type
6627                                      : Type::tsize_t;
6628     size_t len = (size_t)resolveArrayLength(str);
6629     if (len == 0)
6630     {
6631         new(pue) IntegerExp(deleg->loc, 0, indexType);
6632         return pue->exp();
6633     }
6634 
6635     str = resolveSlice(str);
6636 
6637     StringExp *se = NULL;
6638     ArrayLiteralExp *ale = NULL;
6639     if (str->op == TOKstring)
6640         se = (StringExp *) str;
6641     else if (str->op == TOKarrayliteral)
6642         ale = (ArrayLiteralExp *)str;
6643     else
6644     {
6645         str->error("CTFE internal error: cannot foreach %s", str->toChars());
6646         return CTFEExp::cantexp;
6647     }
6648     Expressions args;
6649     args.setDim(numParams);
6650 
6651     Expression *eresult = NULL;         // ded-store to prevent spurious warning
6652 
6653     // Buffers for encoding; also used for decoding array literals
6654     utf8_t utf8buf[4];
6655     unsigned short utf16buf[2];
6656 
6657     size_t start = rvs ? len : 0;
6658     size_t end = rvs ? 0: len;
6659     for (size_t indx = start; indx != end;)
6660     {
6661         // Step 1: Decode the next dchar from the string.
6662 
6663         const char *errmsg = NULL; // Used for reporting decoding errors
6664         dchar_t rawvalue;   // Holds the decoded dchar
6665         size_t currentIndex = indx; // The index of the decoded character
6666 
6667         if (ale)
6668         {
6669             // If it is an array literal, copy the code points into the buffer
6670             size_t buflen = 1; // #code points in the buffer
6671             size_t n = 1;   // #code points in this char
6672             size_t sz = (size_t)ale->type->nextOf()->size();
6673 
6674             switch (sz)
6675             {
6676             case 1:
6677                 if (rvs)
6678                 {
6679                     // find the start of the string
6680                     --indx;
6681                     buflen = 1;
6682                     while (indx > 0 && buflen < 4)
6683                     {
6684                         Expression * r = (*ale->elements)[indx];
6685                         assert(r->op == TOKint64);
6686                         utf8_t x = (utf8_t)(((IntegerExp *)r)->getInteger());
6687                         if ((x & 0xC0) != 0x80)
6688                             break;
6689                         ++buflen;
6690                     }
6691                 }
6692                 else
6693                     buflen = (indx + 4 > len) ? len - indx : 4;
6694                 for (size_t i = 0; i < buflen; ++i)
6695                 {
6696                     Expression * r = (*ale->elements)[indx + i];
6697                     assert(r->op == TOKint64);
6698                     utf8buf[i] = (utf8_t)(((IntegerExp *)r)->getInteger());
6699                 }
6700                 n = 0;
6701                 errmsg = utf_decodeChar(&utf8buf[0], buflen, &n, &rawvalue);
6702                 break;
6703             case 2:
6704                 if (rvs)
6705                 {
6706                     // find the start of the string
6707                     --indx;
6708                     buflen = 1;
6709                     Expression * r = (*ale->elements)[indx];
6710                     assert(r->op == TOKint64);
6711                     unsigned short x = (unsigned short)(((IntegerExp *)r)->getInteger());
6712                     if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF)
6713                     {
6714                         --indx;
6715                         ++buflen;
6716                     }
6717                 }
6718                 else
6719                     buflen = (indx + 2 > len) ? len - indx : 2;
6720                 for (size_t i=0; i < buflen; ++i)
6721                 {
6722                     Expression * r = (*ale->elements)[indx + i];
6723                     assert(r->op == TOKint64);
6724                     utf16buf[i] = (unsigned short)(((IntegerExp *)r)->getInteger());
6725                 }
6726                 n = 0;
6727                 errmsg = utf_decodeWchar(&utf16buf[0], buflen, &n, &rawvalue);
6728                 break;
6729             case 4:
6730                 {
6731                     if (rvs)
6732                         --indx;
6733 
6734                     Expression * r = (*ale->elements)[indx];
6735                     assert(r->op == TOKint64);
6736                     rawvalue = (dchar_t)((IntegerExp *)r)->getInteger();
6737                     n = 1;
6738                 }
6739                 break;
6740             default:
6741                 assert(0);
6742             }
6743             if (!rvs)
6744                 indx += n;
6745         }
6746         else
6747         {
6748             // String literals
6749             size_t saveindx; // used for reverse iteration
6750 
6751             switch (se->sz)
6752             {
6753             case 1:
6754                 if (rvs)
6755                 {
6756                     // find the start of the string
6757                     utf8_t *s = (utf8_t *)se->string;
6758                     --indx;
6759                     while (indx > 0 && ((s[indx]&0xC0) == 0x80))
6760                         --indx;
6761                     saveindx = indx;
6762                 }
6763                 errmsg = utf_decodeChar((utf8_t *)se->string, se->len, &indx, &rawvalue);
6764                 if (rvs)
6765                     indx = saveindx;
6766                 break;
6767             case 2:
6768                 if (rvs)
6769                 {
6770                     // find the start
6771                     unsigned short *s = (unsigned short *)se->string;
6772                     --indx;
6773                     if (s[indx] >= 0xDC00 && s[indx]<= 0xDFFF)
6774                         --indx;
6775                     saveindx = indx;
6776                 }
6777                 errmsg = utf_decodeWchar((unsigned short *)se->string, se->len, &indx, &rawvalue);
6778                 if (rvs)
6779                     indx = saveindx;
6780                 break;
6781             case 4:
6782                 if (rvs)
6783                     --indx;
6784                 rawvalue = ((unsigned *)(se->string))[indx];
6785                 if (!rvs)
6786                     ++indx;
6787                 break;
6788             default:
6789                 assert(0);
6790             }
6791         }
6792         if (errmsg)
6793         {
6794             deleg->error("%s", errmsg);
6795             return CTFEExp::cantexp;
6796         }
6797 
6798         // Step 2: encode the dchar in the target encoding
6799 
6800         int charlen = 1; // How many codepoints are involved?
6801         switch (charType->size())
6802         {
6803             case 1:
6804                 charlen = utf_codeLengthChar(rawvalue);
6805                 utf_encodeChar(&utf8buf[0], rawvalue);
6806                 break;
6807             case 2:
6808                 charlen = utf_codeLengthWchar(rawvalue);
6809                 utf_encodeWchar(&utf16buf[0], rawvalue);
6810                 break;
6811             case 4:
6812                 break;
6813             default:
6814                 assert(0);
6815         }
6816         if (rvs)
6817             currentIndex = indx;
6818 
6819         // Step 3: call the delegate once for each code point
6820 
6821         // The index only needs to be set once
6822         if (numParams == 2)
6823             args[0] = new IntegerExp(deleg->loc, currentIndex, indexType);
6824 
6825         Expression *val = NULL;
6826 
6827         for (int k= 0; k < charlen; ++k)
6828         {
6829             dchar_t codepoint;
6830             switch (charType->size())
6831             {
6832                 case 1:
6833                     codepoint = utf8buf[k];
6834                     break;
6835                 case 2:
6836                     codepoint = utf16buf[k];
6837                     break;
6838                 case 4:
6839                     codepoint = rawvalue;
6840                     break;
6841                 default:
6842                     assert(0);
6843             }
6844             val = new IntegerExp(str->loc, codepoint, charType);
6845 
6846             args[numParams - 1] = val;
6847 
6848             UnionExp ue;
6849             eresult = interpretFunction(&ue, fd, istate, &args, pthis);
6850             if (eresult == ue.exp())
6851                 eresult = ue.copy();
6852             if (exceptionOrCantInterpret(eresult))
6853                 return eresult;
6854             assert(eresult->op == TOKint64);
6855             if (((IntegerExp *)eresult)->getInteger() != 0)
6856                 return eresult;
6857         }
6858     }
6859     return eresult;
6860 }
6861 
6862 /* If this is a built-in function, return the interpreted result,
6863  * Otherwise, return NULL.
6864  */
evaluateIfBuiltin(UnionExp * pue,InterState * istate,Loc loc,FuncDeclaration * fd,Expressions * arguments,Expression * pthis)6865 Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
6866     FuncDeclaration *fd, Expressions *arguments, Expression *pthis)
6867 {
6868     Expression *e = NULL;
6869     size_t nargs = arguments ? arguments->dim : 0;
6870     if (!pthis)
6871     {
6872         if (isBuiltin(fd) == BUILTINyes)
6873         {
6874             Expressions args;
6875             args.setDim(nargs);
6876             for (size_t i = 0; i < args.dim; i++)
6877             {
6878                 Expression *earg = (*arguments)[i];
6879                 earg = interpret(earg, istate);
6880                 if (exceptionOrCantInterpret(earg))
6881                     return earg;
6882                 args[i] = earg;
6883             }
6884             e = eval_builtin(loc, fd, &args);
6885             if (!e)
6886             {
6887                 error(loc, "cannot evaluate unimplemented builtin %s at compile time", fd->toChars());
6888                 e = CTFEExp::cantexp;
6889             }
6890         }
6891     }
6892     if (!pthis)
6893     {
6894         Expression *firstarg =  nargs > 0 ? (*arguments)[0] : NULL;
6895         if (firstarg && firstarg->type->toBasetype()->ty == Taarray)
6896         {
6897             TypeAArray *firstAAtype = (TypeAArray *)firstarg->type;
6898             const Identifier *id = fd->ident;
6899             if (nargs == 1)
6900             {
6901                 if (fd->ident == Id::aaLen)
6902                     return interpret_length(pue, istate, firstarg);
6903 
6904                 if (fd->toParent2()->ident == Id::object)
6905                 {
6906                     if (id == Id::keys)
6907                         return interpret_keys(pue, istate, firstarg, firstAAtype->index->arrayOf());
6908                     if (id == Id::values)
6909                         return interpret_values(pue, istate, firstarg, firstAAtype->nextOf()->arrayOf());
6910                     if (id == Id::rehash)
6911                         return interpret(pue, firstarg, istate);
6912                     if (id == Id::dup)
6913                         return interpret_dup(pue, istate, firstarg);
6914                 }
6915             }
6916             else // (nargs == 3)
6917             {
6918                 if (id == Id::_aaApply)
6919                     return interpret_aaApply(pue, istate, firstarg, (Expression *)(arguments->data[2]));
6920                 if (id == Id::_aaApply2)
6921                     return interpret_aaApply(pue, istate, firstarg, (Expression *)(arguments->data[2]));
6922             }
6923         }
6924     }
6925     if (pthis && !fd->fbody && fd->isCtorDeclaration() && fd->parent && fd->parent->parent && fd->parent->parent->ident == Id::object)
6926     {
6927         if (pthis->op == TOKclassreference && fd->parent->ident == Id::Throwable)
6928         {
6929             // At present, the constructors just copy their arguments into the struct.
6930             // But we might need some magic if stack tracing gets added to druntime.
6931             StructLiteralExp *se = ((ClassReferenceExp *)pthis)->value;
6932             assert(arguments->dim <= se->elements->dim);
6933             for (size_t i = 0; i < arguments->dim; ++i)
6934             {
6935                 e = interpret((*arguments)[i], istate);
6936                 if (exceptionOrCantInterpret(e))
6937                     return e;
6938                 (*se->elements)[i] = e;
6939             }
6940             return CTFEExp::voidexp;
6941         }
6942     }
6943     if (nargs == 1 && !pthis &&
6944         (fd->ident == Id::criticalenter || fd->ident == Id::criticalexit))
6945     {
6946         // Support synchronized{} as a no-op
6947         return CTFEExp::voidexp;
6948     }
6949     if (!pthis)
6950     {
6951         const char *id = fd->ident->toChars();
6952         size_t idlen = strlen(id);
6953         if (nargs == 2 && (idlen == 10 || idlen == 11) &&
6954             !strncmp(id, "_aApply", 7))
6955         {
6956             // Functions from aApply.d and aApplyR.d in the runtime
6957             bool rvs = (idlen == 11);   // true if foreach_reverse
6958             char c = id[idlen-3]; // char width: 'c', 'w', or 'd'
6959             char s = id[idlen-2]; // string width: 'c', 'w', or 'd'
6960             char n = id[idlen-1]; // numParams: 1 or 2.
6961             // There are 12 combinations
6962             if ((n == '1' || n == '2') &&
6963                 (c == 'c' || c == 'w' || c == 'd') &&
6964                 (s == 'c' || s == 'w' || s == 'd') && c != s)
6965             {
6966                 Expression *str = (*arguments)[0];
6967                 str = interpret(str, istate);
6968                 if (exceptionOrCantInterpret(str))
6969                     return str;
6970                 return foreachApplyUtf(pue, istate, str, (*arguments)[1], rvs);
6971             }
6972         }
6973     }
6974     return e;
6975 }
6976 
evaluatePostblit(InterState * istate,Expression * e)6977 Expression *evaluatePostblit(InterState *istate, Expression *e)
6978 {
6979     Type *tb = e->type->baseElemOf();
6980     if (tb->ty != Tstruct)
6981         return NULL;
6982     StructDeclaration *sd = ((TypeStruct *)tb)->sym;
6983     if (!sd->postblit)
6984         return NULL;
6985 
6986     if (e->op == TOKarrayliteral)
6987     {
6988         ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
6989         for (size_t i = 0; i < ale->elements->dim; i++)
6990         {
6991             e = evaluatePostblit(istate, (*ale->elements)[i]);
6992             if (e)
6993                 return e;
6994         }
6995         return NULL;
6996     }
6997     if (e->op == TOKstructliteral)
6998     {
6999         // e.__postblit()
7000         UnionExp ue;
7001         e = interpretFunction(&ue, sd->postblit, istate, NULL, e);
7002         if (e == ue.exp())
7003             e = ue.copy();
7004         if (exceptionOrCantInterpret(e))
7005             return e;
7006         return NULL;
7007     }
7008     assert(0);
7009     return NULL;
7010 }
7011 
evaluateDtor(InterState * istate,Expression * e)7012 Expression *evaluateDtor(InterState *istate, Expression *e)
7013 {
7014     Type *tb = e->type->baseElemOf();
7015     if (tb->ty != Tstruct)
7016         return NULL;
7017     StructDeclaration *sd = ((TypeStruct *)tb)->sym;
7018     if (!sd->dtor)
7019         return NULL;
7020 
7021     UnionExp ue;
7022     if (e->op == TOKarrayliteral)
7023     {
7024         ArrayLiteralExp *alex = (ArrayLiteralExp *)e;
7025         for (size_t i = alex->elements->dim; 0 < i--; )
7026             e = evaluateDtor(istate, (*alex->elements)[i]);
7027     }
7028     else if (e->op == TOKstructliteral)
7029     {
7030         // e.__dtor()
7031         e = interpretFunction(&ue, sd->dtor, istate, NULL, e);
7032     }
7033     else
7034         assert(0);
7035     if (exceptionOrCantInterpret(e))
7036     {
7037         if (e == ue.exp())
7038             e = ue.copy();
7039         return e;
7040     }
7041     return NULL;
7042 }
7043 
7044 /*************************** CTFE Sanity Checks ***************************/
7045 
7046 /* Setter functions for CTFE variable values.
7047  * These functions exist to check for compiler CTFE bugs.
7048  */
hasValue(VarDeclaration * vd)7049 bool hasValue(VarDeclaration *vd)
7050 {
7051     if (vd->ctfeAdrOnStack == -1)
7052         return false;
7053     return NULL != getValue(vd);
7054 }
7055 
getValue(VarDeclaration * vd)7056 Expression *getValue(VarDeclaration *vd)
7057 {
7058     return ctfeStack.getValue(vd);
7059 }
7060 
setValueNull(VarDeclaration * vd)7061 void setValueNull(VarDeclaration *vd)
7062 {
7063     ctfeStack.setValue(vd, NULL);
7064 }
7065 
7066 // Don't check for validity
setValueWithoutChecking(VarDeclaration * vd,Expression * newval)7067 void setValueWithoutChecking(VarDeclaration *vd, Expression *newval)
7068 {
7069     ctfeStack.setValue(vd, newval);
7070 }
7071 
setValue(VarDeclaration * vd,Expression * newval)7072 void setValue(VarDeclaration *vd, Expression *newval)
7073 {
7074     assert((vd->storage_class & (STCout | STCref))
7075             ? isCtfeReferenceValid(newval)
7076             : isCtfeValueValid(newval));
7077     ctfeStack.setValue(vd, newval);
7078 }
7079