RISC-V: Add testcases for unsigned .SAT_SUB vector form 10
[official-gcc.git] / gcc / d / dmd / initsem.d
blobb07699e19fe27d9ec97e4a9c0bdde80fbc3c4c84
1 /**
2 * Semantic analysis of initializers.
4 * Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
6 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/initsem.d, _initsem.d)
8 * Documentation: https://dlang.org/phobos/dmd_initsem.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/initsem.d
12 module dmd.initsem;
14 import core.stdc.stdio;
15 import core.checkedint;
17 import dmd.aggregate;
18 import dmd.aliasthis;
19 import dmd.arraytypes;
20 import dmd.astenums;
21 import dmd.dcast;
22 import dmd.declaration;
23 import dmd.dinterpret;
24 import dmd.dscope;
25 import dmd.dstruct;
26 import dmd.dsymbol;
27 import dmd.dsymbolsem;
28 import dmd.dtemplate;
29 import dmd.errors;
30 import dmd.expression;
31 import dmd.expressionsem;
32 import dmd.func;
33 import dmd.funcsem;
34 import dmd.globals;
35 import dmd.hdrgen;
36 import dmd.id;
37 import dmd.identifier;
38 import dmd.importc;
39 import dmd.init;
40 import dmd.location;
41 import dmd.mtype;
42 import dmd.opover;
43 import dmd.optimize;
44 import dmd.statement;
45 import dmd.target;
46 import dmd.tokens;
47 import dmd.typesem;
49 /********************************
50 * If possible, convert array initializer to associative array initializer.
52 * Params:
53 * ai = array initializer to be converted
55 * Returns:
56 * The converted associative array initializer or ErrorExp if `ai`
57 * is not an associative array initializer.
59 Expression toAssocArrayLiteral(ArrayInitializer ai)
61 //printf("ArrayInitializer::toAssocArrayInitializer(%s)\n", ai.toChars());
62 //static int i; if (++i == 2) assert(0);
64 auto no(const char* format, Initializer i)
66 error(i.loc, format, toChars(i));
67 return ErrorExp.get();
70 const dim = ai.value.length;
71 if (!dim)
72 return no("invalid associative array initializer `%s`, use `null` instead", ai);
74 auto keys = new Expressions(dim);
75 auto values = new Expressions(dim);
76 foreach (i, iz; ai.value[])
78 assert(iz);
79 auto ev = iz.initializerToExpression();
80 if (!ev)
81 return no("invalid value `%s` in initializer", iz);
82 (*values)[i] = ev;
84 auto ei = ai.index[i];
85 if (!ei)
86 return no("missing key for value `%s` in initializer", iz);
87 (*keys)[i] = ei;
89 return new AssocArrayLiteralExp(ai.loc, keys, values);
92 /******************************************
93 * Perform semantic analysis on init.
94 * Params:
95 * init = Initializer AST node
96 * sc = context
97 * tx = type that the initializer needs to become. If tx is an incomplete
98 * type and the initializer completes it, it is updated to be the
99 * complete type. ImportC has incomplete types
100 * needInterpret = if CTFE needs to be run on this,
101 * such as if it is the initializer for a const declaration
102 * Returns:
103 * `Initializer` with completed semantic analysis, `ErrorInitializer` if errors
104 * were encountered
106 Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedInterpret needInterpret)
108 //printf("initializerSemantic() tx: %p %s\n", tx, tx.toChars());
109 Type t = tx;
111 static Initializer err()
113 return new ErrorInitializer();
116 Initializer visitVoid(VoidInitializer i)
118 i.type = t;
119 return i;
122 Initializer visitDefault(DefaultInitializer i)
124 i.type = t;
125 return i;
128 Initializer visitError(ErrorInitializer i)
130 return i;
133 Initializer visitStruct(StructInitializer i)
135 //printf("StructInitializer::semantic(t = %s) %s\n", t.toChars(), i.toChars());
136 /* This works by replacing the StructInitializer with an ExpInitializer.
138 t = t.toBasetype();
139 if (auto tsa = t.isTypeSArray())
141 auto ts = tsa.nextOf().toBasetype().isTypeStruct();
142 if (ts)
143 t = ts;
145 if (auto ts = t.isTypeStruct())
147 StructDeclaration sd = ts.sym;
148 // check if the sd has a regular ctor (user defined non-copy ctor)
149 // that is not disabled.
150 if (sd.hasRegularCtor(true))
152 error(i.loc, "%s `%s` has constructors, cannot use `{ initializers }`, use `%s( initializers )` instead", sd.kind(), sd.toChars(), sd.toChars());
153 return err();
155 sd.size(i.loc);
156 if (sd.sizeok != Sizeok.done)
157 return err();
159 Expression getExp(size_t j, Type fieldType)
161 // Convert initializer to Expression `ex`
162 auto tm = fieldType.addMod(t.mod);
163 auto iz = i.value[j].initializerSemantic(sc, tm, needInterpret);
164 auto ex = iz.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0);
165 if (ex.op != EXP.error)
166 i.value[j] = iz;
167 return ex;
170 auto elements = resolveStructLiteralNamedArgs(sd, t, sc, i.loc, i.field[], &getExp, (size_t j) => i.value[j].loc);
171 if (!elements)
172 return err();
174 // Make a StructLiteralExp out of elements[]
175 auto sle = new StructLiteralExp(i.loc, sd, elements, t);
176 if (!sd.fill(i.loc, *elements, false))
177 return err();
178 sle.type = t;
179 auto ie = new ExpInitializer(i.loc, sle);
180 return ie.initializerSemantic(sc, t, needInterpret);
182 else if ((t.ty == Tdelegate || t.isPtrToFunction()) && i.value.length == 0)
184 const tok = (t.ty == Tdelegate) ? TOK.delegate_ : TOK.function_;
185 /* Rewrite as empty delegate literal { }
187 Type tf = new TypeFunction(ParameterList(), null, LINK.d);
188 auto fd = new FuncLiteralDeclaration(i.loc, Loc.initial, tf, tok, null);
189 fd.fbody = new CompoundStatement(i.loc, new Statements());
190 fd.endloc = i.loc;
191 Expression e = new FuncExp(i.loc, fd);
192 auto ie = new ExpInitializer(i.loc, e);
193 return ie.initializerSemantic(sc, t, needInterpret);
195 if (t.ty != Terror)
196 error(i.loc, "a struct is not a valid initializer for a `%s`", t.toChars());
197 return err();
200 Initializer visitArray(ArrayInitializer i)
202 uint length;
203 const(uint) amax = 0x80000000;
204 bool errors = false;
205 //printf("ArrayInitializer::semantic(%s), ai: %s\n", t.toChars(), toChars(i));
206 if (i.sem) // if semantic() already run
208 return i;
210 i.sem = true;
211 t = t.toBasetype();
212 switch (t.ty)
214 case Tsarray:
215 case Tarray:
216 break;
217 case Tvector:
218 t = t.isTypeVector().basetype;
219 break;
220 case Taarray:
221 case Tstruct: // consider implicit constructor call
223 Expression e;
224 // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int])
225 if (t.ty == Taarray || i.isAssociativeArray())
226 e = i.toAssocArrayLiteral();
227 else
228 e = i.initializerToExpression();
229 // Bugzilla 13987
230 if (!e)
232 error(i.loc, "cannot use array to initialize `%s`", t.toChars());
233 return err();
235 auto ei = new ExpInitializer(e.loc, e);
236 return ei.initializerSemantic(sc, t, needInterpret);
239 case Tpointer:
240 if (t.nextOf().isTypeFunction())
241 goto default;
242 break;
244 default:
245 error(i.loc, "cannot use array to initialize `%s`", t.toChars());
246 return err();
248 i.type = t;
249 length = 0;
250 for (size_t j = 0; j < i.index.length; j++) // don't replace with foreach; j is modified
252 Expression idx = i.index[j];
253 if (idx)
255 sc = sc.startCTFE();
256 idx = idx.expressionSemantic(sc);
257 sc = sc.endCTFE();
258 idx = idx.ctfeInterpret();
259 i.index[j] = idx;
260 const uinteger_t idxvalue = idx.toInteger();
261 if (idxvalue >= amax)
263 error(i.loc, "array index %llu overflow", idxvalue);
264 errors = true;
266 length = cast(uint)idxvalue;
267 if (idx.op == EXP.error)
268 errors = true;
270 Initializer val = i.value[j];
271 ExpInitializer ei = val.isExpInitializer();
272 if (ei && !idx)
273 ei.expandTuples = true;
274 auto tn = t.nextOf();
275 val = val.initializerSemantic(sc, tn, needInterpret);
276 if (val.isErrorInitializer())
277 errors = true;
278 ei = val.isExpInitializer();
279 // found a tuple, expand it
280 if (ei && ei.exp.op == EXP.tuple)
282 TupleExp te = ei.exp.isTupleExp();
283 i.index.remove(j);
284 i.value.remove(j);
285 foreach (k, e; (*te.exps)[])
287 i.index.insert(j + k, cast(Expression)null);
288 i.value.insert(j + k, new ExpInitializer(e.loc, e));
290 j--;
291 continue;
293 else
295 i.value[j] = val;
297 ++length;
298 if (length == 0)
300 error(i.loc, "array dimension overflow");
301 return err();
303 if (length > i.dim)
304 i.dim = length;
306 if (auto tsa = t.isTypeSArray())
308 if (sc.flags & SCOPE.Cfile && tsa.isIncomplete())
310 // Change to array of known length
311 auto tn = tsa.next.toBasetype();
312 tsa = new TypeSArray(tn, new IntegerExp(Loc.initial, i.dim, Type.tsize_t));
313 tx = tsa; // rewrite caller's type
314 i.type = tsa; // remember for later passes
316 else
318 ulong edim = tsa.dim.toInteger();
319 if (i.dim > edim)
321 error(i.loc, "array initializer has %u elements, but array length is %llu", i.dim, edim);
322 return err();
326 if (errors)
327 return err();
329 const sz = t.nextOf().size();
330 if (sz == SIZE_INVALID)
331 return err();
332 bool overflow;
333 const max = mulu(i.dim, sz, overflow);
334 if (overflow || max >= amax)
336 error(i.loc, "array dimension %llu exceeds max of %llu", ulong(i.dim), ulong(amax / sz));
337 return err();
339 //printf("returns ai: %s\n", i.toChars());
340 return i;
343 Initializer visitExp(ExpInitializer i)
345 //printf("ExpInitializer::semantic(%s), type = %s\n", i.exp.toChars(), t.toChars());
346 if (needInterpret)
347 sc = sc.startCTFE();
348 i.exp = i.exp.expressionSemantic(sc);
349 i.exp = resolveProperties(sc, i.exp);
350 if (needInterpret)
351 sc = sc.endCTFE();
352 if (i.exp.op == EXP.error)
353 return err();
354 const olderrors = global.errors;
356 /* ImportC: convert arrays to pointers, functions to pointers to functions
358 Type tb = t.toBasetype();
359 if (tb.isTypePointer())
360 i.exp = i.exp.arrayFuncConv(sc);
362 /* Save the expression before ctfe
363 * Otherwise the error message would contain for example "&[0][0]" instead of "new int"
364 * Regression: https://issues.dlang.org/show_bug.cgi?id=21687
366 Expression currExp = i.exp;
367 if (needInterpret)
369 // If the result will be implicitly cast, move the cast into CTFE
370 // to avoid premature truncation of polysemous types.
371 // eg real [] x = [1.1, 2.2]; should use real precision.
372 if (i.exp.implicitConvTo(t) && !(sc.flags & SCOPE.Cfile))
374 i.exp = i.exp.implicitCastTo(sc, t);
376 if (!global.gag && olderrors != global.errors)
378 return i;
380 if (sc.flags & SCOPE.Cfile)
382 /* the interpreter turns (char*)"string" into &"string"[0] which then
383 * it cannot interpret. Resolve that case by doing optimize() first
385 i.exp = i.exp.optimize(WANTvalue);
386 if (i.exp.isSymOffExp())
388 /* `static variable cannot be read at compile time`
389 * https://issues.dlang.org/show_bug.cgi?id=22513
390 * Maybe this would be better addressed in ctfeInterpret()?
392 needInterpret = NeedInterpret.INITnointerpret;
395 if (needInterpret)
396 i.exp = i.exp.ctfeInterpret();
397 if (i.exp.op == EXP.voidExpression)
398 error(i.loc, "variables cannot be initialized with an expression of type `void`. Use `void` initialization instead.");
400 else
402 i.exp = i.exp.optimize(WANTvalue);
405 if (!global.gag && olderrors != global.errors)
407 return i; // Failed, suppress duplicate error messages
409 if (i.exp.type.isTypeTuple() && i.exp.type.isTypeTuple().arguments.length == 0)
411 Type et = i.exp.type;
412 i.exp = new TupleExp(i.exp.loc, new Expressions());
413 i.exp.type = et;
415 if (i.exp.op == EXP.type)
417 error(i.exp.loc, "initializer must be an expression, not `%s`", i.exp.toChars());
418 return err();
420 // Make sure all pointers are constants
421 if (needInterpret && hasNonConstPointers(i.exp))
423 error(i.exp.loc, "cannot use non-constant CTFE pointer in an initializer `%s`", currExp.toChars());
424 return err();
426 Type ti = i.exp.type.toBasetype();
427 if (i.exp.op == EXP.tuple && i.expandTuples && !i.exp.implicitConvTo(t))
429 return new ExpInitializer(i.loc, i.exp);
431 /* Look for case of initializing a static array with a too-short
432 * string literal, such as:
433 * char[5] foo = "abc";
434 * Allow this by doing an explicit cast, which will lengthen the string
435 * literal.
437 if (i.exp.op == EXP.string_ && tb.ty == Tsarray)
439 StringExp se = i.exp.isStringExp();
440 Type typeb = se.type.toBasetype();
441 TY tynto = tb.nextOf().ty;
442 if (!se.committed &&
443 (typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar &&
444 se.numberOfCodeUnits(tynto) < tb.isTypeSArray().dim.toInteger())
446 i.exp = se.castTo(sc, t);
447 goto L1;
450 /* Lop off terminating 0 of initializer for:
451 * static char s[5] = "hello";
453 if (sc.flags & SCOPE.Cfile &&
454 typeb.ty == Tsarray &&
455 tynto.isSomeChar &&
456 tb.isTypeSArray().dim.toInteger() + 1 == typeb.isTypeSArray().dim.toInteger())
458 i.exp = se.castTo(sc, t);
459 goto L1;
462 /* C11 6.7.9-14..15
463 * Initialize an array of unknown size with a string.
464 * Change to static array of known size
466 if (sc.flags & SCOPE.Cfile && i.exp.isStringExp() &&
467 tb.isTypeSArray() && tb.isTypeSArray().isIncomplete())
469 StringExp se = i.exp.isStringExp();
470 auto ts = new TypeSArray(tb.nextOf(), new IntegerExp(Loc.initial, se.len + 1, Type.tsize_t));
471 t = typeSemantic(ts, Loc.initial, sc);
472 i.exp.type = t;
473 tx = t;
476 // Look for implicit constructor call
477 if (tb.ty == Tstruct && !(ti.ty == Tstruct && tb.toDsymbol(sc) == ti.toDsymbol(sc)) && !i.exp.implicitConvTo(t))
479 StructDeclaration sd = tb.isTypeStruct().sym;
480 if (sd.ctor)
482 // Rewrite as S().ctor(exp)
483 Expression e;
484 e = new StructLiteralExp(i.loc, sd, null);
485 e = new DotIdExp(i.loc, e, Id.ctor);
486 e = new CallExp(i.loc, e, i.exp);
487 e = e.expressionSemantic(sc);
488 if (needInterpret)
489 i.exp = e.ctfeInterpret();
490 else
491 i.exp = e.optimize(WANTvalue);
493 else if (search_function(sd, Id.call))
495 /* https://issues.dlang.org/show_bug.cgi?id=1547
497 * Look for static opCall
499 * Rewrite as:
500 * i.exp = typeof(sd).opCall(arguments)
503 Expression e = typeDotIdExp(i.loc, sd.type, Id.call);
504 e = new CallExp(i.loc, e, i.exp);
505 e = e.expressionSemantic(sc);
506 e = resolveProperties(sc, e);
507 if (needInterpret)
508 i.exp = e.ctfeInterpret();
509 else
510 i.exp = e.optimize(WANTvalue);
514 // Look for the case of statically initializing an array with a single member.
515 // Recursively strip static array / enum layers until a compatible element is found,
516 // and return an `ArrayLiteralExp` repeating the initializer, or `null` if no match found
517 // int[2][3] = 7 => [[7, 7], [7, 7], [7, 7]]
518 // int[2] = new Object => null
519 Expression sarrayRepeat(Type tb)
521 auto tsa = tb.isTypeSArray();
522 if (!tsa)
523 return null;
525 // printf("i.exp = %s, tsa = %s\n", i.exp.toChars(), tsa.toChars());
526 Expression elem = null;
527 if (i.exp.implicitConvTo(tb.nextOf()))
528 elem = i.exp.implicitCastTo(sc, tb.nextOf());
529 else if (auto ae = sarrayRepeat(tb.nextOf().toBasetype()))
530 elem = ae;
531 else
532 return null;
534 auto arrayElements = new Expressions(cast(size_t) tsa.dim.toInteger());
535 foreach (ref e; *arrayElements)
536 e = elem;
537 return new ArrayLiteralExp(i.exp.loc, tb, elem, arrayElements);
540 if (auto sa = sarrayRepeat(tb))
542 // printf("sa = %s\n", sa.toChars());
543 i.exp = sa;
547 auto tta = t.isTypeSArray();
548 if (i.exp.implicitConvTo(t))
550 i.exp = i.exp.implicitCastTo(sc, t);
552 else if (sc.flags & SCOPE.Cfile && i.exp.isStringExp() &&
553 tta && (tta.next.ty == Tint8 || tta.next.ty == Tuns8) &&
554 ti.ty == Tsarray && ti.nextOf().ty == Tchar)
556 /* unsigned char bbb[1] = "";
557 * signed char ccc[1] = "";
559 i.exp = i.exp.castTo(sc, t);
561 else
563 auto tba = tb.isTypeSArray();
564 // Look for mismatch of compile-time known length to emit
565 // better diagnostic message, as same as AssignExp::semantic.
566 if (tba && i.exp.implicitConvTo(tba.next.arrayOf()) > MATCH.nomatch)
568 uinteger_t dim1 = tba.dim.toInteger();
569 uinteger_t dim2 = dim1;
570 if (auto ale = i.exp.isArrayLiteralExp())
572 dim2 = ale.elements ? ale.elements.length : 0;
574 else if (auto se = i.exp.isSliceExp())
576 if (Type tx = toStaticArrayType(se))
577 dim2 = tx.isTypeSArray().dim.toInteger();
579 if (dim1 != dim2)
581 error(i.exp.loc, "mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2);
582 i.exp = ErrorExp.get();
585 Type et = i.exp.type;
586 const errors = global.startGagging();
587 i.exp = i.exp.implicitCastTo(sc, t);
588 if (global.endGagging(errors))
589 error(currExp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars());
593 if (i.exp.op == EXP.error)
595 return i;
597 if (needInterpret)
598 i.exp = i.exp.ctfeInterpret();
599 else
600 i.exp = i.exp.optimize(WANTvalue);
601 //printf("-ExpInitializer::semantic(): "); i.exp.print();
602 return i;
605 Initializer visitC(CInitializer ci)
607 //printf("CInitializer::semantic() tx: %s t: %s ci: %s\n", (tx ? tx.toChars() : "".ptr), t.toChars(), toChars(ci));
608 static if (0)
609 if (auto ts = tx.isTypeStruct())
611 import dmd.common.outbuffer;
612 OutBuffer buf;
613 HdrGenState hgs;
614 toCBuffer(ts.sym, buf, hgs);
615 printf("%s\n", buf.peekChars());
618 /* Rewrite CInitializer into ExpInitializer, ArrayInitializer, or StructInitializer
620 t = t.toBasetype();
622 if (auto tv = t.isTypeVector())
623 t = tv.basetype;
625 /* If `{ expression }` return the expression initializer
627 ExpInitializer isBraceExpression()
629 auto dil = ci.initializerList[];
630 return (dil.length == 1 && !dil[0].designatorList)
631 ? dil[0].initializer.isExpInitializer()
632 : null;
635 /********************************
637 bool overlaps(VarDeclaration field, VarDeclaration[] fields, StructInitializer si)
639 foreach (fld; fields)
641 if (field.isOverlappedWith(fld))
643 // look for initializer corresponding with fld
644 foreach (i, ident; si.field[])
646 if (ident == fld.ident && si.value[i])
647 return true; // already an initializer for `field`
651 return false;
654 /* Run semantic on ExpInitializer, see if it represents entire struct ts
656 bool representsStruct(ExpInitializer ei, TypeStruct ts)
658 if (needInterpret)
659 sc = sc.startCTFE();
660 ei.exp = ei.exp.expressionSemantic(sc);
661 ei.exp = resolveProperties(sc, ei.exp);
662 if (needInterpret)
663 sc = sc.endCTFE();
664 return ei.exp.implicitConvTo(ts) != MATCH.nomatch; // initializer represents the entire struct
667 /* If { } are omitted from substructs, use recursion to reconstruct where
668 * brackets go
669 * Params:
670 * ts = substruct to initialize
671 * index = index into ci.initializer, updated
672 * Returns: struct initializer for this substruct
674 Initializer subStruct()(TypeStruct ts, ref size_t index)
676 //printf("subStruct(ts: %s, index %d)\n", ts.toChars(), cast(int)index);
678 auto si = new StructInitializer(ci.loc);
679 StructDeclaration sd = ts.sym;
680 sd.size(ci.loc);
681 if (sd.sizeok != Sizeok.done)
683 index = ci.initializerList.length;
684 return err();
686 const nfields = sd.fields.length;
688 foreach (fieldi; 0 .. nfields)
690 if (index >= ci.initializerList.length)
691 break; // ran out of initializers
692 auto di = ci.initializerList[index];
693 if (di.designatorList && fieldi != 0)
694 break; // back to top level
695 else
697 VarDeclaration field;
698 while (1) // skip field if it overlaps with previously seen fields
700 field = sd.fields[fieldi];
701 ++fieldi;
702 if (!overlaps(field, sd.fields[], si))
703 break;
704 if (fieldi == nfields)
705 break;
707 auto tn = field.type.toBasetype();
708 auto tnsa = tn.isTypeSArray();
709 auto tns = tn.isTypeStruct();
710 auto ix = di.initializer;
711 if (tnsa && ix.isExpInitializer())
713 ExpInitializer ei = ix.isExpInitializer();
714 if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
716 si.addInit(field.ident, ei);
717 ++index;
719 else
720 si.addInit(field.ident, subArray(tnsa, index)); // fwd ref of subArray is why subStruct is a template
722 else if (tns && ix.isExpInitializer())
724 /* Disambiguate between an exp representing the entire
725 * struct, and an exp representing the first field of the struct
727 if (representsStruct(ix.isExpInitializer(), tns)) // initializer represents the entire struct
729 si.addInit(field.ident, initializerSemantic(ix, sc, tn, needInterpret));
730 ++index;
732 else // field initializers for struct
733 si.addInit(field.ident, subStruct(tns, index)); // the first field
735 else
737 si.addInit(field.ident, ix);
738 ++index;
742 //printf("subStruct() returns ai: %s, index: %d\n", si.toChars(), cast(int)index);
743 return si;
746 /* If { } are omitted from subarrays, use recursion to reconstruct where
747 * brackets go
748 * Params:
749 * tsa = subarray to initialize
750 * index = index into ci.initializer, updated
751 * Returns: array initializer for this subarray
753 Initializer subArray(TypeSArray tsa, ref size_t index)
755 //printf("array(tsa: %s, index %d)\n", tsa.toChars(), cast(int)index);
756 if (tsa.isIncomplete())
758 // C11 6.2.5-20 "element type shall be complete whenever the array type is specified"
759 assert(0); // should have been detected by parser
762 auto tnsa = tsa.nextOf().toBasetype().isTypeSArray();
764 auto ai = new ArrayInitializer(ci.loc);
765 ai.isCarray = true;
767 foreach (n; 0 .. cast(size_t)tsa.dim.toInteger())
769 if (index >= ci.initializerList.length)
770 break; // ran out of initializers
771 auto di = ci.initializerList[index];
772 if (di.designatorList)
773 break; // back to top level
774 else if (tnsa && di.initializer.isExpInitializer())
776 ExpInitializer ei = di.initializer.isExpInitializer();
777 if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
779 ai.addInit(null, ei);
780 ++index;
782 else
783 ai.addInit(null, subArray(tnsa, index));
785 else
787 ai.addInit(null, di.initializer);
788 ++index;
791 //printf("array() returns ai: %s, index: %d\n", ai.toChars(), cast(int)index);
792 return ai;
795 if (auto ts = t.isTypeStruct())
797 auto si = new StructInitializer(ci.loc);
798 StructDeclaration sd = ts.sym;
799 sd.size(ci.loc); // run semantic() on sd to get fields
800 if (sd.sizeok != Sizeok.done)
802 return err();
804 const nfields = sd.fields.length;
805 size_t fieldi = 0;
807 Loop1:
808 for (size_t index = 0; index < ci.initializerList.length; )
810 DesigInit di = ci.initializerList[index];
811 Designators* dlist = di.designatorList;
812 if (dlist)
814 const length = (*dlist).length;
815 if (length == 0 || !(*dlist)[0].ident)
817 error(ci.loc, "`.identifier` expected for C struct field initializer `%s`", toChars(ci));
818 return err();
820 if (length > 1)
822 error(ci.loc, "only 1 designator currently allowed for C struct field initializer `%s`", toChars(ci));
823 return err();
825 auto id = (*dlist)[0].ident;
826 foreach (k, f; sd.fields[]) // linear search for now
828 if (f.ident == id)
830 fieldi = k;
831 si.addInit(id, di.initializer);
832 ++fieldi;
833 ++index;
834 continue Loop1;
837 error(ci.loc, "`.%s` is not a field of `%s`\n", id.toChars(), sd.toChars());
838 return err();
840 else
842 if (fieldi == nfields)
843 break;
845 auto ix = di.initializer;
847 /* If a C initializer is wrapped in a C initializer, with no designators,
848 * peel off the outer one
850 if (ix.isCInitializer())
852 CInitializer cix = ix.isCInitializer();
853 if (cix.initializerList.length == 1)
855 DesigInit dix = cix.initializerList[0];
856 if (!dix.designatorList)
858 Initializer inix = dix.initializer;
859 if (inix.isCInitializer())
860 ix = inix;
865 if (auto cix = ix.isCInitializer())
867 /* ImportC loses the structure from anonymous structs, but this is retained
868 * by the initializer syntax. if a CInitializer has a Designator, it is probably
869 * a nested anonymous struct
871 if (cix.initializerList.length)
873 DesigInit dix = cix.initializerList[0];
874 Designators* dlistx = dix.designatorList;
875 if (dlistx && (*dlistx).length == 1 && (*dlistx)[0].ident)
877 auto id = (*dlistx)[0].ident;
878 foreach (k, f; sd.fields[]) // linear search for now
880 if (f.ident == id)
882 fieldi = k;
883 si.addInit(id, dix.initializer);
884 ++fieldi;
885 ++index;
886 continue Loop1;
893 VarDeclaration field;
894 while (1) // skip field if it overlaps with previously seen fields
896 field = sd.fields[fieldi];
897 ++fieldi;
898 if (!overlaps(field, sd.fields[], si))
899 break;
900 if (fieldi == nfields)
901 break;
904 auto tn = field.type.toBasetype();
905 auto tnsa = tn.isTypeSArray();
906 auto tns = tn.isTypeStruct();
908 if (tnsa && ix.isExpInitializer())
910 ExpInitializer ei = ix.isExpInitializer();
911 if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
913 si.addInit(field.ident, ei);
914 ++index;
916 else
917 si.addInit(field.ident, subArray(tnsa, index));
919 else if (tns && ix.isExpInitializer())
921 /* Disambiguate between an exp representing the entire
922 * struct, and an exp representing the first field of the struct
924 if (representsStruct(ix.isExpInitializer(), tns)) // initializer represents the entire struct
926 si.addInit(field.ident, initializerSemantic(ix, sc, tn, needInterpret));
927 ++index;
929 else // field initializers for struct
930 si.addInit(field.ident, subStruct(tns, index)); // the first field
932 else
934 si.addInit(field.ident, di.initializer);
935 ++index;
939 return initializerSemantic(si, sc, t, needInterpret);
941 else if (auto ta = t.isTypeSArray())
943 auto tn = t.nextOf().toBasetype(); // element type of array
945 /* If it's an array of integral being initialized by `{ string }`
946 * replace with `string`
948 if (tn.isintegral())
950 if (ExpInitializer ei = isBraceExpression())
952 if (ei.exp.isStringExp())
953 return ei.initializerSemantic(sc, t, needInterpret);
957 auto tnsa = tn.isTypeSArray(); // array of array
958 auto tns = tn.isTypeStruct(); // array of struct
960 auto ai = new ArrayInitializer(ci.loc);
961 ai.isCarray = true;
962 for (size_t index = 0; index < ci.initializerList.length; )
964 auto di = ci.initializerList[index];
965 if (auto dlist = di.designatorList)
967 const length = (*dlist).length;
968 if (length == 0 || !(*dlist)[0].exp)
970 error(ci.loc, "`[ constant-expression ]` expected for C array element initializer `%s`", toChars(ci));
971 return err();
973 if (length > 1)
975 error(ci.loc, "only 1 designator currently allowed for C array element initializer `%s`", toChars(ci));
976 return err();
978 //printf("tn: %s, di.initializer: %s\n", tn.toChars(), di.initializer.toChars());
979 auto ix = di.initializer;
980 if (tnsa && ix.isExpInitializer())
982 // Wrap initializer in [ ]
983 auto ain = new ArrayInitializer(ci.loc);
984 ain.addInit(null, di.initializer);
985 ix = ain;
986 ai.addInit((*dlist)[0].exp, initializerSemantic(ix, sc, tn, needInterpret));
987 ++index;
989 else if (tns && ix.isExpInitializer())
991 /* Disambiguate between an exp representing the entire
992 * struct, and an exp representing the first field of the struct
994 if (representsStruct(ix.isExpInitializer(), tns)) // initializer represents the entire struct
996 ai.addInit((*dlist)[0].exp, initializerSemantic(ix, sc, tn, needInterpret));
997 ++index;
999 else // field initializers for struct
1000 ai.addInit((*dlist)[0].exp, subStruct(tns, index)); // the first field
1002 else
1004 ai.addInit((*dlist)[0].exp, initializerSemantic(ix, sc, tn, needInterpret));
1005 ++index;
1008 else if (tnsa && di.initializer.isExpInitializer())
1010 ExpInitializer ei = di.initializer.isExpInitializer();
1011 if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
1013 ai.addInit(null, ei);
1014 ++index;
1016 else
1017 ai.addInit(null, subArray(tnsa, index));
1019 else if (tns && di.initializer.isExpInitializer())
1021 /* Disambiguate between an exp representing the entire
1022 * struct, and an exp representing the first field of the struct
1024 if (representsStruct(di.initializer.isExpInitializer(), tns)) // initializer represents the entire struct
1026 ai.addInit(null, initializerSemantic(di.initializer, sc, tn, needInterpret));
1027 ++index;
1029 else // field initializers for struct
1030 ai.addInit(null, subStruct(tns, index)); // the first field
1032 else
1034 ai.addInit(null, initializerSemantic(di.initializer, sc, tn, needInterpret));
1035 ++index;
1038 return initializerSemantic(ai, sc, tx, needInterpret);
1040 else if (ExpInitializer ei = isBraceExpression())
1042 return visitExp(ei);
1044 else
1046 error(ci.loc, "unrecognized C initializer `%s` for type `%s`", toChars(ci), t.toChars());
1047 return err();
1051 mixin VisitInitializer!Initializer visit;
1052 auto result = visit.VisitInitializer(init);
1053 return (result !is null) ? result : new ErrorInitializer();
1056 /***********************
1057 * Translate init to an `Expression` in order to infer the type.
1058 * Params:
1059 * init = `Initializer` AST node
1060 * sc = context
1061 * Returns:
1062 * an equivalent `ExpInitializer` if successful, or `ErrorInitializer` if it cannot be translated
1064 Initializer inferType(Initializer init, Scope* sc)
1066 Initializer visitVoid(VoidInitializer i)
1068 error(i.loc, "cannot infer type from void initializer");
1069 return new ErrorInitializer();
1072 Initializer visitDefault(DefaultInitializer i)
1074 error(i.loc, "cannot infer type from default initializer");
1075 return new ErrorInitializer();
1078 Initializer visitError(ErrorInitializer i)
1080 return i;
1083 Initializer visitStruct(StructInitializer i)
1085 error(i.loc, "cannot infer type from struct initializer");
1086 return new ErrorInitializer();
1089 Initializer visitArray(ArrayInitializer init)
1091 //printf("ArrayInitializer::inferType() %s\n", toChars());
1092 Expressions* keys = null;
1093 Expressions* values;
1094 if (init.isAssociativeArray())
1096 keys = new Expressions(init.value.length);
1097 values = new Expressions(init.value.length);
1098 for (size_t i = 0; i < init.value.length; i++)
1100 Expression e = init.index[i];
1101 if (!e)
1102 goto Lno;
1103 (*keys)[i] = e;
1104 Initializer iz = init.value[i];
1105 if (!iz)
1106 goto Lno;
1107 iz = iz.inferType(sc);
1108 if (iz.isErrorInitializer())
1110 return iz;
1112 (*values)[i] = iz.isExpInitializer().exp;
1113 assert(!(*values)[i].isErrorExp());
1115 Expression e = new AssocArrayLiteralExp(init.loc, keys, values);
1116 auto ei = new ExpInitializer(init.loc, e);
1117 return ei.inferType(sc);
1119 else
1121 auto elements = new Expressions(init.value.length);
1122 elements.zero();
1123 for (size_t i = 0; i < init.value.length; i++)
1125 assert(!init.index[i]); // already asserted by isAssociativeArray()
1126 Initializer iz = init.value[i];
1127 if (!iz)
1128 goto Lno;
1129 iz = iz.inferType(sc);
1130 if (iz.isErrorInitializer())
1132 return iz;
1134 (*elements)[i] = iz.isExpInitializer().exp;
1135 assert(!(*elements)[i].isErrorExp());
1137 Expression e = new ArrayLiteralExp(init.loc, null, elements);
1138 auto ei = new ExpInitializer(init.loc, e);
1139 return ei.inferType(sc);
1141 Lno:
1142 if (keys)
1144 error(init.loc, "not an associative array initializer");
1146 else
1148 error(init.loc, "cannot infer type from array initializer");
1150 return new ErrorInitializer();
1153 Initializer visitExp(ExpInitializer init)
1155 //printf("ExpInitializer::inferType() %s\n", init.toChars());
1156 init.exp = init.exp.expressionSemantic(sc);
1158 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
1159 if (init.exp.op == EXP.type)
1160 init.exp = resolveAliasThis(sc, init.exp);
1162 init.exp = resolveProperties(sc, init.exp);
1163 if (auto se = init.exp.isScopeExp())
1165 TemplateInstance ti = se.sds.isTemplateInstance();
1166 if (ti && ti.semanticRun == PASS.semantic && !ti.aliasdecl)
1167 error(se.loc, "cannot infer type from %s `%s`, possible circular dependency", se.sds.kind(), se.toChars());
1168 else
1169 error(se.loc, "cannot infer type from %s `%s`", se.sds.kind(), se.toChars());
1170 return new ErrorInitializer();
1173 // Give error for overloaded function addresses
1174 bool hasOverloads;
1175 if (auto f = isFuncAddress(init.exp, &hasOverloads))
1177 if (checkForwardRef(f, init.loc))
1179 return new ErrorInitializer();
1181 if (hasOverloads && !f.isUnique())
1183 error(init.exp.loc, "cannot infer type from overloaded function symbol `%s`", init.exp.toChars());
1184 return new ErrorInitializer();
1187 if (auto ae = init.exp.isAddrExp())
1189 if (ae.e1.op == EXP.overloadSet)
1191 error(init.exp.loc, "cannot infer type from overloaded function symbol `%s`", init.exp.toChars());
1192 return new ErrorInitializer();
1195 if (init.exp.isErrorExp())
1197 return new ErrorInitializer();
1199 if (!init.exp.type)
1201 return new ErrorInitializer();
1203 return init;
1206 Initializer visitC(CInitializer i)
1208 //printf("CInitializer.inferType()\n");
1209 error(i.loc, "TODO C inferType initializers not supported yet");
1210 return new ErrorInitializer();
1213 mixin VisitInitializer!Initializer visit;
1214 auto result = visit.VisitInitializer(init);
1215 return (result !is null) ? result : new ErrorInitializer();
1218 /***********************
1219 * Translate init to an `Expression`.
1220 * Params:
1221 * init = `Initializer` AST node
1222 * itype = if not `null`, type to coerce expression to
1223 * isCfile = default initializers are different with C
1224 * Returns:
1225 * `Expression` created, `null` if cannot, `ErrorExp` for other errors
1227 Expression initializerToExpression(Initializer init, Type itype = null, const bool isCfile = false)
1229 //printf("initializerToExpression() isCfile: %d\n", isCfile);
1231 Expression visitVoid(VoidInitializer)
1233 return null;
1236 Expression visitDefault(DefaultInitializer di)
1238 return di.type ? di.type.defaultInit(Loc.initial, isCfile) : null;
1241 Expression visitError(ErrorInitializer)
1243 return ErrorExp.get();
1246 /***************************************
1247 * This works by transforming a struct initializer into
1248 * a struct literal. In the future, the two should be the
1249 * same thing.
1251 Expression visitStruct(StructInitializer)
1253 // cannot convert to an expression without target 'ad'
1254 return null;
1257 /********************************
1258 * If possible, convert array initializer to array literal.
1259 * Otherwise return NULL.
1261 Expression visitArray(ArrayInitializer init)
1263 //printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
1264 //static int i; if (++i == 2) assert(0);
1265 uint edim; // the length of the resulting array literal
1266 const(uint) amax = 0x80000000;
1267 Type t = null; // type of the array literal being initialized
1268 if (init.type)
1270 if (init.type == Type.terror)
1272 return ErrorExp.get();
1274 t = init.type.toBasetype();
1275 switch (t.ty)
1277 case Tvector:
1278 t = t.isTypeVector().basetype;
1279 goto case Tsarray;
1281 case Tsarray:
1282 uinteger_t adim = t.isTypeSArray().dim.toInteger();
1283 if (adim >= amax)
1284 return null;
1285 edim = cast(uint)adim;
1286 break;
1288 case Tpointer:
1289 case Tarray:
1290 edim = init.dim;
1291 break;
1293 default:
1294 assert(0);
1297 else
1299 /* Calculate the length of the array literal
1301 edim = cast(uint)init.value.length;
1302 size_t j = 0;
1303 foreach (i; 0 .. init.value.length)
1305 if (auto e = init.index[i])
1307 if (e.op == EXP.int64)
1309 const uinteger_t idxval = e.toInteger();
1310 if (idxval >= amax)
1311 return null;
1312 j = cast(size_t)idxval;
1314 else
1315 return null;
1317 ++j;
1318 if (j > edim)
1319 edim = cast(uint)j;
1323 auto elements = new Expressions(edim);
1324 elements.zero();
1325 size_t j = 0;
1326 foreach (i; 0 .. init.value.length)
1328 if (auto e = init.index[i])
1329 j = cast(size_t)e.toInteger();
1330 assert(j < edim);
1331 if (Initializer iz = init.value[i])
1333 if (Expression ex = iz.initializerToExpression(null, isCfile))
1335 (*elements)[j] = ex;
1336 ++j;
1338 else
1339 return null;
1341 else
1342 return null;
1345 /* Fill in any missing elements with the default initializer
1347 Expression defaultInit = null; // lazily create it
1348 foreach (ref element; (*elements)[0 .. edim])
1350 if (!element)
1352 if (!init.type) // don't know what type to use
1353 return null;
1354 if (!defaultInit)
1355 defaultInit = (cast(TypeNext)t).next.defaultInit(Loc.initial, isCfile);
1356 element = defaultInit;
1360 /* Expand any static array initializers that are a single expression
1361 * into an array of them
1362 * e => [e, e, ..., e, e]
1364 if (t)
1366 Type tn = t.nextOf().toBasetype();
1367 if (tn.ty == Tsarray)
1369 const dim = cast(size_t)(cast(TypeSArray)tn).dim.toInteger();
1370 Type te = tn.nextOf().toBasetype();
1371 foreach (ref e; *elements)
1373 if (te.equals(e.type))
1375 auto elements2 = new Expressions(dim);
1376 foreach (ref e2; *elements2)
1377 e2 = e;
1378 e = new ArrayLiteralExp(e.loc, tn, elements2);
1384 /* If any elements are errors, then the whole thing is an error
1386 foreach (e; (*elements)[0 .. edim])
1388 if (e.op == EXP.error)
1390 return e;
1394 Expression e = new ArrayLiteralExp(init.loc, init.type, elements);
1395 return e;
1398 Expression visitExp(ExpInitializer i)
1400 if (itype)
1402 //printf("ExpInitializer::toExpression(t = %s) exp = %s\n", itype.toChars(), i.exp.toChars());
1403 Type tb = itype.toBasetype();
1404 Expression e = (i.exp.op == EXP.construct || i.exp.op == EXP.blit) ? (cast(AssignExp)i.exp).e2 : i.exp;
1405 if (tb.ty == Tsarray && e.implicitConvTo(tb.nextOf()))
1407 TypeSArray tsa = cast(TypeSArray)tb;
1408 size_t d = cast(size_t)tsa.dim.toInteger();
1409 auto elements = new Expressions(d);
1410 for (size_t j = 0; j < d; j++)
1411 (*elements)[j] = e;
1412 auto ae = new ArrayLiteralExp(e.loc, itype, elements);
1413 return ae;
1416 return i.exp;
1419 Expression visitC(CInitializer i)
1421 //printf("CInitializer.initializerToExpression(null, true)\n");
1422 return null;
1425 mixin VisitInitializer!Expression visit;
1426 return visit.VisitInitializer(init);
1430 /**************************************
1431 * Determine if expression has non-constant pointers, or more precisely,
1432 * a pointer that CTFE cannot handle.
1433 * Params:
1434 * e = expression to check
1435 * Returns:
1436 * true if it has non-constant pointers
1438 private bool hasNonConstPointers(Expression e)
1440 static bool checkArray(Expressions* elems)
1442 foreach (e; *elems)
1444 if (e && hasNonConstPointers(e))
1445 return true;
1447 return false;
1450 if (e.type.ty == Terror)
1451 return false;
1452 if (e.op == EXP.null_)
1453 return false;
1454 if (auto se = e.isStructLiteralExp())
1456 return checkArray(se.elements);
1458 if (auto ae = e.isArrayLiteralExp())
1460 if (!ae.type.nextOf().hasPointers())
1461 return false;
1462 return checkArray(ae.elements);
1464 if (auto ae = e.isAssocArrayLiteralExp())
1466 if (ae.type.nextOf().hasPointers() && checkArray(ae.values))
1467 return true;
1468 if (ae.type.isTypeAArray().index.hasPointers())
1469 return checkArray(ae.keys);
1470 return false;
1472 if (auto ae = e.isAddrExp())
1474 if (ae.type.nextOf().isImmutable() || ae.type.nextOf().isConst())
1476 return false;
1478 if (auto se = ae.e1.isStructLiteralExp())
1480 if (!(se.stageflags & stageSearchPointers))
1482 const old = se.stageflags;
1483 se.stageflags |= stageSearchPointers;
1484 bool ret = checkArray(se.elements);
1485 se.stageflags = old;
1486 return ret;
1488 else
1490 return false;
1493 return true;
1495 if (e.type.ty == Tpointer && !e.type.isPtrToFunction())
1497 if (e.op == EXP.symbolOffset) // address of a global is OK
1498 return false;
1499 if (e.op == EXP.int64) // cast(void *)int is OK
1500 return false;
1501 if (e.op == EXP.string_) // "abc".ptr is OK
1502 return false;
1503 return true;
1505 return false;
1509 Given the names and values of a `StructInitializer` or `CallExp`,
1510 resolve it to a list of expressions to construct a `StructLiteralExp`.
1512 Params:
1513 sd = struct
1514 t = type of struct (potentially including qualifiers such as `const` or `immutable`)
1515 sc = scope of the expression initializing the struct
1516 iloc = location of expression initializing the struct
1517 names = identifiers passed in argument list, `null` entries for positional arguments
1518 getExp = function that, given an index into `names` and destination type, returns the initializing expression
1519 getLoc = function that, given an index into `names`, returns a location for error messages
1521 Returns: list of expressions ordered to the struct's fields, or `null` on error
1523 Expressions* resolveStructLiteralNamedArgs(StructDeclaration sd, Type t, Scope* sc,
1524 Loc iloc, Identifier[] names, scope Expression delegate(size_t i, Type fieldType) getExp,
1525 scope Loc delegate(size_t i) getLoc
1528 //expandTuples for non-identity arguments?
1529 const nfields = sd.nonHiddenFields();
1530 auto elements = new Expressions(nfields);
1531 auto elems = (*elements)[];
1532 foreach (ref elem; elems)
1533 elem = null;
1535 // Run semantic for explicitly given initializers
1536 // TODO: this part is slightly different from StructLiteralExp::semantic.
1537 bool errors = false;
1538 size_t fieldi = 0;
1539 foreach (j, id; names)
1541 const argLoc = getLoc(j);
1542 if (id)
1544 // Determine `fieldi` that `id` matches
1545 Dsymbol s = sd.search(iloc, id);
1546 if (!s)
1548 s = sd.search_correct(id);
1549 if (s)
1550 error(argLoc, "`%s` is not a member of `%s`, did you mean %s `%s`?", id.toChars(), sd.toChars(), s.kind(), s.toChars());
1551 else
1552 error(argLoc, "`%s` is not a member of `%s`", id.toChars(), sd.toChars());
1553 return null;
1555 s.checkDeprecated(iloc, sc);
1556 s = s.toAlias();
1558 // Find out which field index `s` is
1559 for (fieldi = 0; 1; fieldi++)
1561 if (fieldi >= nfields)
1563 error(iloc, "`%s.%s` is not a per-instance initializable field", sd.toChars(), s.toChars());
1564 return null;
1566 if (s == sd.fields[fieldi])
1567 break;
1570 if (nfields == 0)
1572 error(argLoc, "initializer provided for struct `%s` with no fields", sd.toChars());
1573 return null;
1575 if (j >= nfields)
1577 error(argLoc, "too many initializers for `%s` with %d field%s", sd.toChars(),
1578 cast(int) nfields, nfields != 1 ? "s".ptr : "".ptr);
1579 return null;
1581 if (fieldi >= nfields)
1583 error(argLoc, "trying to initialize past the last field `%s` of `%s`", sd.fields[nfields - 1].toChars(), sd.toChars());
1584 return null;
1587 VarDeclaration vd = sd.fields[fieldi];
1588 if (elems[fieldi])
1590 error(argLoc, "duplicate initializer for field `%s`", vd.toChars());
1591 errors = true;
1592 elems[fieldi] = ErrorExp.get(); // for better diagnostics on multiple errors
1593 ++fieldi;
1594 continue;
1597 // Check for @safe violations
1598 if (vd.type.hasPointers)
1600 if ((!t.alignment.isDefault() && t.alignment.get() < target.ptrsize ||
1601 (vd.offset & (target.ptrsize - 1))))
1603 if (sc.setUnsafe(false, argLoc,
1604 "field `%s.%s` cannot assign to misaligned pointers in `@safe` code", sd, vd))
1606 errors = true;
1607 elems[fieldi] = ErrorExp.get(); // for better diagnostics on multiple errors
1608 ++fieldi;
1609 continue;
1614 // Check for overlapping initializations (can happen with unions)
1615 foreach (k, v2; sd.fields[0 .. nfields])
1617 if (vd.isOverlappedWith(v2) && elems[k])
1619 error(elems[k].loc, "overlapping initialization for field `%s` and `%s`", v2.toChars(), vd.toChars());
1620 enum errorMsg = "`struct` initializers that contain anonymous unions" ~
1621 " must initialize only the first member of a `union`. All subsequent" ~
1622 " non-overlapping fields are default initialized";
1623 if (!sd.isUnionDeclaration())
1624 .errorSupplemental(elems[k].loc, errorMsg);
1625 errors = true;
1626 continue;
1630 assert(sc);
1632 auto ex = getExp(j, vd.type);
1634 if (ex.op == EXP.error)
1636 errors = true;
1637 elems[fieldi] = ErrorExp.get(); // for better diagnostics on multiple errors
1638 ++fieldi;
1639 continue;
1642 elems[fieldi] = doCopyOrMove(sc, ex);
1643 ++fieldi;
1645 if (errors)
1646 return null;
1648 return elements;