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