1 /**
2  * Compiler implementation of the
3  * $(LINK2 http://www.dlang.org, D programming language).
4  *
5  * Copyright:   Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved
6  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
7  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source:      $(DMDSRC _init.d)
9  */
10 
11 module ddmd.init;
12 
13 import core.stdc.stdio;
14 import core.checkedint;
15 
16 import ddmd.aggregate;
17 import ddmd.arraytypes;
18 import ddmd.dcast;
19 import ddmd.declaration;
20 import ddmd.dscope;
21 import ddmd.dstruct;
22 import ddmd.dsymbol;
23 import ddmd.dtemplate;
24 import ddmd.errors;
25 import ddmd.expression;
26 import ddmd.func;
27 import ddmd.globals;
28 import ddmd.hdrgen;
29 import ddmd.id;
30 import ddmd.identifier;
31 import ddmd.mtype;
32 import ddmd.root.outbuffer;
33 import ddmd.root.rootobject;
34 import ddmd.statement;
35 import ddmd.tokens;
36 import ddmd.visitor;
37 
38 enum NeedInterpret : int
39 {
40     INITnointerpret,
41     INITinterpret,
42 }
43 
44 alias INITnointerpret = NeedInterpret.INITnointerpret;
45 alias INITinterpret = NeedInterpret.INITinterpret;
46 
47 /***********************************************************
48  */
49 extern (C++) class Initializer : RootObject
50 {
51     Loc loc;
52 
53     final extern (D) this(Loc loc)
54     {
55         this.loc = loc;
56     }
57 
58     abstract Initializer syntaxCopy();
59 
60     static Initializers* arraySyntaxCopy(Initializers* ai)
61     {
62         Initializers* a = null;
63         if (ai)
64         {
65             a = new Initializers();
66             a.setDim(ai.dim);
67             for (size_t i = 0; i < a.dim; i++)
68                 (*a)[i] = (*ai)[i].syntaxCopy();
69         }
70         return a;
71     }
72 
73     /* Translates to an expression to infer type.
74      * Returns ExpInitializer or ErrorInitializer.
75      */
76     abstract Initializer inferType(Scope* sc);
77 
78     // needInterpret is INITinterpret if must be a manifest constant, 0 if not.
79     abstract Initializer semantic(Scope* sc, Type t, NeedInterpret needInterpret);
80 
81     abstract Expression toExpression(Type t = null);
82 
83     override final const(char)* toChars()
84     {
85         OutBuffer buf;
86         HdrGenState hgs;
87         .toCBuffer(this, &buf, &hgs);
88         return buf.extractString();
89     }
90 
91     ErrorInitializer isErrorInitializer()
92     {
93         return null;
94     }
95 
96     VoidInitializer isVoidInitializer()
97     {
98         return null;
99     }
100 
101     StructInitializer isStructInitializer()
102     {
103         return null;
104     }
105 
106     ArrayInitializer isArrayInitializer()
107     {
108         return null;
109     }
110 
111     ExpInitializer isExpInitializer()
112     {
113         return null;
114     }
115 
116     void accept(Visitor v)
117     {
118         v.visit(this);
119     }
120 }
121 
122 /***********************************************************
123  */
124 extern (C++) final class VoidInitializer : Initializer
125 {
126     Type type;      // type that this will initialize to
127 
128     extern (D) this(Loc loc)
129     {
130         super(loc);
131     }
132 
133     override Initializer syntaxCopy()
134     {
135         return new VoidInitializer(loc);
136     }
137 
138     override Initializer inferType(Scope* sc)
139     {
140         error(loc, "cannot infer type from void initializer");
141         return new ErrorInitializer();
142     }
143 
144     override Initializer semantic(Scope* sc, Type t, NeedInterpret needInterpret)
145     {
146         //printf("VoidInitializer::semantic(t = %p)\n", t);
147         type = t;
148         return this;
149     }
150 
151     override Expression toExpression(Type t = null)
152     {
153         return null;
154     }
155 
156     override VoidInitializer isVoidInitializer()
157     {
158         return this;
159     }
160 
161     override void accept(Visitor v)
162     {
163         v.visit(this);
164     }
165 }
166 
167 /***********************************************************
168  */
169 extern (C++) final class ErrorInitializer : Initializer
170 {
171     extern (D) this()
172     {
173         super(Loc());
174     }
175 
176     override Initializer syntaxCopy()
177     {
178         return this;
179     }
180 
181     override Initializer inferType(Scope* sc)
182     {
183         return this;
184     }
185 
186     override Initializer semantic(Scope* sc, Type t, NeedInterpret needInterpret)
187     {
188         //printf("ErrorInitializer::semantic(t = %p)\n", t);
189         return this;
190     }
191 
192     override Expression toExpression(Type t = null)
193     {
194         return new ErrorExp();
195     }
196 
197     override ErrorInitializer isErrorInitializer()
198     {
199         return this;
200     }
201 
202     override void accept(Visitor v)
203     {
204         v.visit(this);
205     }
206 }
207 
208 /***********************************************************
209  */
210 extern (C++) final class StructInitializer : Initializer
211 {
212     Identifiers field;      // of Identifier *'s
213     Initializers value;     // parallel array of Initializer *'s
214 
215     extern (D) this(Loc loc)
216     {
217         super(loc);
218     }
219 
220     override Initializer syntaxCopy()
221     {
222         auto ai = new StructInitializer(loc);
223         assert(field.dim == value.dim);
224         ai.field.setDim(field.dim);
225         ai.value.setDim(value.dim);
226         for (size_t i = 0; i < field.dim; i++)
227         {
228             ai.field[i] = field[i];
229             ai.value[i] = value[i].syntaxCopy();
230         }
231         return ai;
232     }
233 
234     void addInit(Identifier field, Initializer value)
235     {
236         //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
237         this.field.push(field);
238         this.value.push(value);
239     }
240 
241     override Initializer inferType(Scope* sc)
242     {
243         error(loc, "cannot infer type from struct initializer");
244         return new ErrorInitializer();
245     }
246 
247     override Initializer semantic(Scope* sc, Type t, NeedInterpret needInterpret)
248     {
249         //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
250         t = t.toBasetype();
251         if (t.ty == Tsarray && t.nextOf().toBasetype().ty == Tstruct)
252             t = t.nextOf().toBasetype();
253         if (t.ty == Tstruct)
254         {
255             StructDeclaration sd = (cast(TypeStruct)t).sym;
256             if (sd.ctor)
257             {
258                 error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead", sd.kind(), sd.toChars(), sd.toChars());
259                 return new ErrorInitializer();
260             }
261             sd.size(loc);
262             if (sd.sizeok != SIZEOKdone)
263                 return new ErrorInitializer();
264             size_t nfields = sd.fields.dim - sd.isNested();
265             //expandTuples for non-identity arguments?
266             auto elements = new Expressions();
267             elements.setDim(nfields);
268             for (size_t i = 0; i < elements.dim; i++)
269                 (*elements)[i] = null;
270             // Run semantic for explicitly given initializers
271             // TODO: this part is slightly different from StructLiteralExp::semantic.
272             bool errors = false;
273             for (size_t fieldi = 0, i = 0; i < field.dim; i++)
274             {
275                 if (Identifier id = field[i])
276                 {
277                     Dsymbol s = sd.search(loc, id);
278                     if (!s)
279                     {
280                         s = sd.search_correct(id);
281                         if (s)
282                             error(loc, "'%s' is not a member of '%s', did you mean %s '%s'?", id.toChars(), sd.toChars(), s.kind(), s.toChars());
283                         else
284                             error(loc, "'%s' is not a member of '%s'", id.toChars(), sd.toChars());
285                         return new ErrorInitializer();
286                     }
287                     s = s.toAlias();
288                     // Find out which field index it is
289                     for (fieldi = 0; 1; fieldi++)
290                     {
291                         if (fieldi >= nfields)
292                         {
293                             error(loc, "%s.%s is not a per-instance initializable field", sd.toChars(), s.toChars());
294                             return new ErrorInitializer();
295                         }
296                         if (s == sd.fields[fieldi])
297                             break;
298                     }
299                 }
300                 else if (fieldi >= nfields)
301                 {
302                     error(loc, "too many initializers for %s", sd.toChars());
303                     return new ErrorInitializer();
304                 }
305                 VarDeclaration vd = sd.fields[fieldi];
306                 if ((*elements)[fieldi])
307                 {
308                     error(loc, "duplicate initializer for field '%s'", vd.toChars());
309                     errors = true;
310                     continue;
311                 }
312                 for (size_t j = 0; j < nfields; j++)
313                 {
314                     VarDeclaration v2 = sd.fields[j];
315                     if (vd.isOverlappedWith(v2) && (*elements)[j])
316                     {
317                         error(loc, "overlapping initialization for field %s and %s", v2.toChars(), vd.toChars());
318                         errors = true;
319                         continue;
320                     }
321                 }
322                 assert(sc);
323                 Initializer iz = value[i];
324                 iz = iz.semantic(sc, vd.type.addMod(t.mod), needInterpret);
325                 Expression ex = iz.toExpression();
326                 if (ex.op == TOKerror)
327                 {
328                     errors = true;
329                     continue;
330                 }
331                 value[i] = iz;
332                 (*elements)[fieldi] = ex;
333                 ++fieldi;
334             }
335             if (errors)
336                 return new ErrorInitializer();
337             auto sle = new StructLiteralExp(loc, sd, elements, t);
338             if (!sd.fill(loc, elements, false))
339                 return new ErrorInitializer();
340             sle.type = t;
341             auto ie = new ExpInitializer(loc, sle);
342             return ie.semantic(sc, t, needInterpret);
343         }
344         else if ((t.ty == Tdelegate || t.ty == Tpointer && t.nextOf().ty == Tfunction) && value.dim == 0)
345         {
346             TOK tok = (t.ty == Tdelegate) ? TOKdelegate : TOKfunction;
347             /* Rewrite as empty delegate literal { }
348              */
349             auto parameters = new Parameters();
350             Type tf = new TypeFunction(parameters, null, 0, LINKd);
351             auto fd = new FuncLiteralDeclaration(loc, Loc(), tf, tok, null);
352             fd.fbody = new CompoundStatement(loc, new Statements());
353             fd.endloc = loc;
354             Expression e = new FuncExp(loc, fd);
355             auto ie = new ExpInitializer(loc, e);
356             return ie.semantic(sc, t, needInterpret);
357         }
358         error(loc, "a struct is not a valid initializer for a %s", t.toChars());
359         return new ErrorInitializer();
360     }
361 
362     /***************************************
363      * This works by transforming a struct initializer into
364      * a struct literal. In the future, the two should be the
365      * same thing.
366      */
367     override Expression toExpression(Type t = null)
368     {
369         // cannot convert to an expression without target 'ad'
370         return null;
371     }
372 
373     override StructInitializer isStructInitializer()
374     {
375         return this;
376     }
377 
378     override void accept(Visitor v)
379     {
380         v.visit(this);
381     }
382 }
383 
384 /***********************************************************
385  */
386 extern (C++) final class ArrayInitializer : Initializer
387 {
388     Expressions index;      // indices
389     Initializers value;     // of Initializer *'s
390     uint dim;               // length of array being initialized
391     Type type;              // type that array will be used to initialize
392     bool sem;               // true if semantic() is run
393 
394     extern (D) this(Loc loc)
395     {
396         super(loc);
397     }
398 
399     override Initializer syntaxCopy()
400     {
401         //printf("ArrayInitializer::syntaxCopy()\n");
402         auto ai = new ArrayInitializer(loc);
403         assert(index.dim == value.dim);
404         ai.index.setDim(index.dim);
405         ai.value.setDim(value.dim);
406         for (size_t i = 0; i < ai.value.dim; i++)
407         {
408             ai.index[i] = index[i] ? index[i].syntaxCopy() : null;
409             ai.value[i] = value[i].syntaxCopy();
410         }
411         return ai;
412     }
413 
414     void addInit(Expression index, Initializer value)
415     {
416         this.index.push(index);
417         this.value.push(value);
418         dim = 0;
419         type = null;
420     }
421 
422     bool isAssociativeArray()
423     {
424         for (size_t i = 0; i < value.dim; i++)
425         {
426             if (index[i])
427                 return true;
428         }
429         return false;
430     }
431 
432     override Initializer inferType(Scope* sc)
433     {
434         //printf("ArrayInitializer::inferType() %s\n", toChars());
435         Expressions* keys = null;
436         Expressions* values;
437         if (isAssociativeArray())
438         {
439             keys = new Expressions();
440             keys.setDim(value.dim);
441             values = new Expressions();
442             values.setDim(value.dim);
443             for (size_t i = 0; i < value.dim; i++)
444             {
445                 Expression e = index[i];
446                 if (!e)
447                     goto Lno;
448                 (*keys)[i] = e;
449                 Initializer iz = value[i];
450                 if (!iz)
451                     goto Lno;
452                 iz = iz.inferType(sc);
453                 if (iz.isErrorInitializer())
454                     return iz;
455                 assert(iz.isExpInitializer());
456                 (*values)[i] = (cast(ExpInitializer)iz).exp;
457                 assert((*values)[i].op != TOKerror);
458             }
459             Expression e = new AssocArrayLiteralExp(loc, keys, values);
460             auto ei = new ExpInitializer(loc, e);
461             return ei.inferType(sc);
462         }
463         else
464         {
465             auto elements = new Expressions();
466             elements.setDim(value.dim);
467             elements.zero();
468             for (size_t i = 0; i < value.dim; i++)
469             {
470                 assert(!index[i]); // already asserted by isAssociativeArray()
471                 Initializer iz = value[i];
472                 if (!iz)
473                     goto Lno;
474                 iz = iz.inferType(sc);
475                 if (iz.isErrorInitializer())
476                     return iz;
477                 assert(iz.isExpInitializer());
478                 (*elements)[i] = (cast(ExpInitializer)iz).exp;
479                 assert((*elements)[i].op != TOKerror);
480             }
481             Expression e = new ArrayLiteralExp(loc, elements);
482             auto ei = new ExpInitializer(loc, e);
483             return ei.inferType(sc);
484         }
485     Lno:
486         if (keys)
487         {
488             error(loc, "not an associative array initializer");
489         }
490         else
491         {
492             error(loc, "cannot infer type from array initializer");
493         }
494         return new ErrorInitializer();
495     }
496 
497     override Initializer semantic(Scope* sc, Type t, NeedInterpret needInterpret)
498     {
499         uint length;
500         const(uint) amax = 0x80000000;
501         bool errors = false;
502         //printf("ArrayInitializer::semantic(%s)\n", t.toChars());
503         if (sem) // if semantic() already run
504             return this;
505         sem = true;
506         t = t.toBasetype();
507         switch (t.ty)
508         {
509         case Tsarray:
510         case Tarray:
511             break;
512         case Tvector:
513             t = (cast(TypeVector)t).basetype;
514             break;
515         case Taarray:
516         case Tstruct: // consider implicit constructor call
517             {
518                 Expression e;
519                 // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int])
520                 if (t.ty == Taarray || isAssociativeArray())
521                     e = toAssocArrayLiteral();
522                 else
523                     e = toExpression();
524                 if (!e) // Bugzilla 13987
525                 {
526                     error(loc, "cannot use array to initialize %s", t.toChars());
527                     goto Lerr;
528                 }
529                 auto ei = new ExpInitializer(e.loc, e);
530                 return ei.semantic(sc, t, needInterpret);
531             }
532         case Tpointer:
533             if (t.nextOf().ty != Tfunction)
534                 break;
535             goto default;
536         default:
537             error(loc, "cannot use array to initialize %s", t.toChars());
538             goto Lerr;
539         }
540         type = t;
541         length = 0;
542         for (size_t i = 0; i < index.dim; i++)
543         {
544             Expression idx = index[i];
545             if (idx)
546             {
547                 sc = sc.startCTFE();
548                 idx = idx.semantic(sc);
549                 sc = sc.endCTFE();
550                 idx = idx.ctfeInterpret();
551                 index[i] = idx;
552                 const uinteger_t idxvalue = idx.toInteger();
553                 if (idxvalue >= amax)
554                 {
555                     error(loc, "array index %llu overflow", ulong(idxvalue));
556                     errors = true;
557                 }
558                 length = cast(uint)idxvalue;
559                 if (idx.op == TOKerror)
560                     errors = true;
561             }
562             Initializer val = value[i];
563             ExpInitializer ei = val.isExpInitializer();
564             if (ei && !idx)
565                 ei.expandTuples = true;
566             val = val.semantic(sc, t.nextOf(), needInterpret);
567             if (val.isErrorInitializer())
568                 errors = true;
569             ei = val.isExpInitializer();
570             // found a tuple, expand it
571             if (ei && ei.exp.op == TOKtuple)
572             {
573                 TupleExp te = cast(TupleExp)ei.exp;
574                 index.remove(i);
575                 value.remove(i);
576                 for (size_t j = 0; j < te.exps.dim; ++j)
577                 {
578                     Expression e = (*te.exps)[j];
579                     index.insert(i + j, cast(Expression)null);
580                     value.insert(i + j, new ExpInitializer(e.loc, e));
581                 }
582                 i--;
583                 continue;
584             }
585             else
586             {
587                 value[i] = val;
588             }
589             length++;
590             if (length == 0)
591             {
592                 error(loc, "array dimension overflow");
593                 goto Lerr;
594             }
595             if (length > dim)
596                 dim = length;
597         }
598         if (t.ty == Tsarray)
599         {
600             uinteger_t edim = (cast(TypeSArray)t).dim.toInteger();
601             if (dim > edim)
602             {
603                 error(loc, "array initializer has %u elements, but array length is %llu", dim, edim);
604                 goto Lerr;
605             }
606         }
607         if (errors)
608             goto Lerr;
609         {
610             const sz = t.nextOf().size();
611             bool overflow;
612             const max = mulu(dim, sz, overflow);
613             if (overflow || max >= amax)
614             {
615                 error(loc, "array dimension %llu exceeds max of %llu", ulong(dim), ulong(amax / sz));
616                 goto Lerr;
617             }
618             return this;
619         }
620     Lerr:
621         return new ErrorInitializer();
622     }
623 
624     /********************************
625      * If possible, convert array initializer to array literal.
626      * Otherwise return NULL.
627      */
628     override Expression toExpression(Type tx = null)
629     {
630         //printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
631         //static int i; if (++i == 2) assert(0);
632         Expressions* elements;
633         uint edim;
634         const(uint) amax = 0x80000000;
635         Type t = null;
636         if (type)
637         {
638             if (type == Type.terror)
639                 return new ErrorExp();
640             t = type.toBasetype();
641             switch (t.ty)
642             {
643             case Tvector:
644                 t = (cast(TypeVector)t).basetype;
645                 goto case Tsarray;
646 
647             case Tsarray:
648                 uinteger_t adim = (cast(TypeSArray)t).dim.toInteger();
649                 if (adim >= amax)
650                     goto Lno;
651                 edim = cast(uint)adim;
652                 break;
653 
654             case Tpointer:
655             case Tarray:
656                 edim = dim;
657                 break;
658 
659             default:
660                 assert(0);
661             }
662         }
663         else
664         {
665             edim = cast(uint)value.dim;
666             for (size_t i = 0, j = 0; i < value.dim; i++, j++)
667             {
668                 if (index[i])
669                 {
670                     if (index[i].op == TOKint64)
671                     {
672                         const uinteger_t idxval = index[i].toInteger();
673                         if (idxval >= amax)
674                             goto Lno;
675                         j = cast(size_t)idxval;
676                     }
677                     else
678                         goto Lno;
679                 }
680                 if (j >= edim)
681                     edim = cast(uint)(j + 1);
682             }
683         }
684         elements = new Expressions();
685         elements.setDim(edim);
686         elements.zero();
687         for (size_t i = 0, j = 0; i < value.dim; i++, j++)
688         {
689             if (index[i])
690                 j = cast(size_t)index[i].toInteger();
691             assert(j < edim);
692             Initializer iz = value[i];
693             if (!iz)
694                 goto Lno;
695             Expression ex = iz.toExpression();
696             if (!ex)
697             {
698                 goto Lno;
699             }
700             (*elements)[j] = ex;
701         }
702         {
703             /* Fill in any missing elements with the default initializer
704              */
705             Expression _init = null;
706             for (size_t i = 0; i < edim; i++)
707             {
708                 if (!(*elements)[i])
709                 {
710                     if (!type)
711                         goto Lno;
712                     if (!_init)
713                         _init = (cast(TypeNext)t).next.defaultInit();
714                     (*elements)[i] = _init;
715                 }
716             }
717 
718             /* Expand any static array initializers that are a single expression
719              * into an array of them
720              */
721             if (t)
722             {
723                 Type tn = t.nextOf().toBasetype();
724                 if (tn.ty == Tsarray)
725                 {
726                     const dim = cast(size_t)(cast(TypeSArray)tn).dim.toInteger();
727                     Type te = tn.nextOf().toBasetype();
728                     foreach (ref e; *elements)
729                     {
730                         if (te.equals(e.type))
731                         {
732                             auto elements2 = new Expressions();
733                             elements2.setDim(dim);
734                             foreach (ref e2; *elements2)
735                                 e2 = e;
736                             e = new ArrayLiteralExp(e.loc, elements2);
737                             e.type = tn;
738                         }
739                     }
740                 }
741             }
742 
743             /* If any elements are errors, then the whole thing is an error
744              */
745             for (size_t i = 0; i < edim; i++)
746             {
747                 Expression e = (*elements)[i];
748                 if (e.op == TOKerror)
749                     return e;
750             }
751 
752             Expression e = new ArrayLiteralExp(loc, elements);
753             e.type = type;
754             return e;
755         }
756     Lno:
757         return null;
758     }
759 
760     /********************************
761      * If possible, convert array initializer to associative array initializer.
762      */
763     Expression toAssocArrayLiteral()
764     {
765         Expression e;
766         //printf("ArrayInitializer::toAssocArrayInitializer()\n");
767         //static int i; if (++i == 2) assert(0);
768         auto keys = new Expressions();
769         keys.setDim(value.dim);
770         auto values = new Expressions();
771         values.setDim(value.dim);
772         for (size_t i = 0; i < value.dim; i++)
773         {
774             e = index[i];
775             if (!e)
776                 goto Lno;
777             (*keys)[i] = e;
778             Initializer iz = value[i];
779             if (!iz)
780                 goto Lno;
781             e = iz.toExpression();
782             if (!e)
783                 goto Lno;
784             (*values)[i] = e;
785         }
786         e = new AssocArrayLiteralExp(loc, keys, values);
787         return e;
788     Lno:
789         error(loc, "not an associative array initializer");
790         return new ErrorExp();
791     }
792 
793     override ArrayInitializer isArrayInitializer()
794     {
795         return this;
796     }
797 
798     override void accept(Visitor v)
799     {
800         v.visit(this);
801     }
802 }
803 
804 /***********************************************************
805  */
806 extern (C++) final class ExpInitializer : Initializer
807 {
808     Expression exp;
809     bool expandTuples;
810 
811     extern (D) this(Loc loc, Expression exp)
812     {
813         super(loc);
814         this.exp = exp;
815     }
816 
817     override Initializer syntaxCopy()
818     {
819         return new ExpInitializer(loc, exp.syntaxCopy());
820     }
821 
822     override Initializer inferType(Scope* sc)
823     {
824         //printf("ExpInitializer::inferType() %s\n", toChars());
825         exp = exp.semantic(sc);
826         exp = resolveProperties(sc, exp);
827         if (exp.op == TOKscope)
828         {
829             ScopeExp se = cast(ScopeExp)exp;
830             TemplateInstance ti = se.sds.isTemplateInstance();
831             if (ti && ti.semanticRun == PASSsemantic && !ti.aliasdecl)
832                 se.error("cannot infer type from %s %s, possible circular dependency", se.sds.kind(), se.toChars());
833             else
834                 se.error("cannot infer type from %s %s", se.sds.kind(), se.toChars());
835             return new ErrorInitializer();
836         }
837 
838         // Give error for overloaded function addresses
839         bool hasOverloads;
840         if (auto f = isFuncAddress(exp, &hasOverloads))
841         {
842             if (f.checkForwardRef(loc))
843                 return new ErrorInitializer();
844             if (hasOverloads && !f.isUnique())
845             {
846                 exp.error("cannot infer type from overloaded function symbol %s", exp.toChars());
847                 return new ErrorInitializer();
848             }
849         }
850         if (exp.op == TOKaddress)
851         {
852             AddrExp ae = cast(AddrExp)exp;
853             if (ae.e1.op == TOKoverloadset)
854             {
855                 exp.error("cannot infer type from overloaded function symbol %s", exp.toChars());
856                 return new ErrorInitializer();
857             }
858         }
859         if (exp.op == TOKerror)
860             return new ErrorInitializer();
861         if (!exp.type)
862             return new ErrorInitializer();
863         return this;
864     }
865 
866     override Initializer semantic(Scope* sc, Type t, NeedInterpret needInterpret)
867     {
868         //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
869         if (needInterpret)
870             sc = sc.startCTFE();
871         exp = exp.semantic(sc);
872         exp = resolveProperties(sc, exp);
873         if (needInterpret)
874             sc = sc.endCTFE();
875         if (exp.op == TOKerror)
876             return new ErrorInitializer();
877         uint olderrors = global.errors;
878         if (needInterpret)
879         {
880             // If the result will be implicitly cast, move the cast into CTFE
881             // to avoid premature truncation of polysemous types.
882             // eg real [] x = [1.1, 2.2]; should use real precision.
883             if (exp.implicitConvTo(t))
884             {
885                 exp = exp.implicitCastTo(sc, t);
886             }
887             exp = exp.ctfeInterpret();
888         }
889         else
890         {
891             exp = exp.optimize(WANTvalue);
892         }
893         if (!global.gag && olderrors != global.errors)
894             return this; // Failed, suppress duplicate error messages
895         if (exp.type.ty == Ttuple && (cast(TypeTuple)exp.type).arguments.dim == 0)
896         {
897             Type et = exp.type;
898             exp = new TupleExp(exp.loc, new Expressions());
899             exp.type = et;
900         }
901         if (exp.op == TOKtype)
902         {
903             exp.error("initializer must be an expression, not '%s'", exp.toChars());
904             return new ErrorInitializer();
905         }
906         // Make sure all pointers are constants
907         if (needInterpret && hasNonConstPointers(exp))
908         {
909             exp.error("cannot use non-constant CTFE pointer in an initializer '%s'", exp.toChars());
910             return new ErrorInitializer();
911         }
912         Type tb = t.toBasetype();
913         Type ti = exp.type.toBasetype();
914         if (exp.op == TOKtuple && expandTuples && !exp.implicitConvTo(t))
915             return new ExpInitializer(loc, exp);
916         /* Look for case of initializing a static array with a too-short
917          * string literal, such as:
918          *  char[5] foo = "abc";
919          * Allow this by doing an explicit cast, which will lengthen the string
920          * literal.
921          */
922         if (exp.op == TOKstring && tb.ty == Tsarray)
923         {
924             StringExp se = cast(StringExp)exp;
925             Type typeb = se.type.toBasetype();
926             TY tynto = tb.nextOf().ty;
927             if (!se.committed &&
928                 (typeb.ty == Tarray || typeb.ty == Tsarray) &&
929                 (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
930                 se.numberOfCodeUnits(tynto) < (cast(TypeSArray)tb).dim.toInteger())
931             {
932                 exp = se.castTo(sc, t);
933                 goto L1;
934             }
935         }
936         // Look for implicit constructor call
937         if (tb.ty == Tstruct && !(ti.ty == Tstruct && tb.toDsymbol(sc) == ti.toDsymbol(sc)) && !exp.implicitConvTo(t))
938         {
939             StructDeclaration sd = (cast(TypeStruct)tb).sym;
940             if (sd.ctor)
941             {
942                 // Rewrite as S().ctor(exp)
943                 Expression e;
944                 e = new StructLiteralExp(loc, sd, null);
945                 e = new DotIdExp(loc, e, Id.ctor);
946                 e = new CallExp(loc, e, exp);
947                 e = e.semantic(sc);
948                 if (needInterpret)
949                     exp = e.ctfeInterpret();
950                 else
951                     exp = e.optimize(WANTvalue);
952             }
953         }
954         // Look for the case of statically initializing an array
955         // with a single member.
956         if (tb.ty == Tsarray && !tb.nextOf().equals(ti.toBasetype().nextOf()) && exp.implicitConvTo(tb.nextOf()))
957         {
958             /* If the variable is not actually used in compile time, array creation is
959              * redundant. So delay it until invocation of toExpression() or toDt().
960              */
961             t = tb.nextOf();
962         }
963         if (exp.implicitConvTo(t))
964         {
965             exp = exp.implicitCastTo(sc, t);
966         }
967         else
968         {
969             // Look for mismatch of compile-time known length to emit
970             // better diagnostic message, as same as AssignExp::semantic.
971             if (tb.ty == Tsarray && exp.implicitConvTo(tb.nextOf().arrayOf()) > MATCHnomatch)
972             {
973                 uinteger_t dim1 = (cast(TypeSArray)tb).dim.toInteger();
974                 uinteger_t dim2 = dim1;
975                 if (exp.op == TOKarrayliteral)
976                 {
977                     ArrayLiteralExp ale = cast(ArrayLiteralExp)exp;
978                     dim2 = ale.elements ? ale.elements.dim : 0;
979                 }
980                 else if (exp.op == TOKslice)
981                 {
982                     Type tx = toStaticArrayType(cast(SliceExp)exp);
983                     if (tx)
984                         dim2 = (cast(TypeSArray)tx).dim.toInteger();
985                 }
986                 if (dim1 != dim2)
987                 {
988                     exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2);
989                     exp = new ErrorExp();
990                 }
991             }
992             exp = exp.implicitCastTo(sc, t);
993         }
994     L1:
995         if (exp.op == TOKerror)
996             return this;
997         if (needInterpret)
998             exp = exp.ctfeInterpret();
999         else
1000             exp = exp.optimize(WANTvalue);
1001         //printf("-ExpInitializer::semantic(): "); exp->print();
1002         return this;
1003     }
1004 
1005     override Expression toExpression(Type t = null)
1006     {
1007         if (t)
1008         {
1009             //printf("ExpInitializer::toExpression(t = %s) exp = %s\n", t->toChars(), exp->toChars());
1010             Type tb = t.toBasetype();
1011             Expression e = (exp.op == TOKconstruct || exp.op == TOKblit) ? (cast(AssignExp)exp).e2 : exp;
1012             if (tb.ty == Tsarray && e.implicitConvTo(tb.nextOf()))
1013             {
1014                 TypeSArray tsa = cast(TypeSArray)tb;
1015                 size_t d = cast(size_t)tsa.dim.toInteger();
1016                 auto elements = new Expressions();
1017                 elements.setDim(d);
1018                 for (size_t i = 0; i < d; i++)
1019                     (*elements)[i] = e;
1020                 auto ae = new ArrayLiteralExp(e.loc, elements);
1021                 ae.type = t;
1022                 return ae;
1023             }
1024         }
1025         return exp;
1026     }
1027 
1028     override ExpInitializer isExpInitializer()
1029     {
1030         return this;
1031     }
1032 
1033     override void accept(Visitor v)
1034     {
1035         v.visit(this);
1036     }
1037 }
1038 
1039 version (all)
1040 {
1041     extern (C++) bool hasNonConstPointers(Expression e)
1042     {
1043         if (e.type.ty == Terror)
1044             return false;
1045         if (e.op == TOKnull)
1046             return false;
1047         if (e.op == TOKstructliteral)
1048         {
1049             StructLiteralExp se = cast(StructLiteralExp)e;
1050             return arrayHasNonConstPointers(se.elements);
1051         }
1052         if (e.op == TOKarrayliteral)
1053         {
1054             if (!e.type.nextOf().hasPointers())
1055                 return false;
1056             ArrayLiteralExp ae = cast(ArrayLiteralExp)e;
1057             return arrayHasNonConstPointers(ae.elements);
1058         }
1059         if (e.op == TOKassocarrayliteral)
1060         {
1061             AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e;
1062             if (ae.type.nextOf().hasPointers() && arrayHasNonConstPointers(ae.values))
1063                 return true;
1064             if ((cast(TypeAArray)ae.type).index.hasPointers())
1065                 return arrayHasNonConstPointers(ae.keys);
1066             return false;
1067         }
1068         if (e.op == TOKaddress)
1069         {
1070             AddrExp ae = cast(AddrExp)e;
1071             if (ae.e1.op == TOKstructliteral)
1072             {
1073                 StructLiteralExp se = cast(StructLiteralExp)ae.e1;
1074                 if (!(se.stageflags & stageSearchPointers))
1075                 {
1076                     int old = se.stageflags;
1077                     se.stageflags |= stageSearchPointers;
1078                     bool ret = arrayHasNonConstPointers(se.elements);
1079                     se.stageflags = old;
1080                     return ret;
1081                 }
1082                 else
1083                 {
1084                     return false;
1085                 }
1086             }
1087             return true;
1088         }
1089         if (e.type.ty == Tpointer && e.type.nextOf().ty != Tfunction)
1090         {
1091             if (e.op == TOKsymoff) // address of a global is OK
1092                 return false;
1093             if (e.op == TOKint64) // cast(void *)int is OK
1094                 return false;
1095             if (e.op == TOKstring) // "abc".ptr is OK
1096                 return false;
1097             return true;
1098         }
1099         return false;
1100     }
1101 
1102     extern (C++) bool arrayHasNonConstPointers(Expressions* elems)
1103     {
1104         for (size_t i = 0; i < elems.dim; i++)
1105         {
1106             Expression e = (*elems)[i];
1107             if (e && hasNonConstPointers(e))
1108                 return true;
1109         }
1110         return false;
1111     }
1112 }