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