1 1.1 mrg /** 2 1.1 mrg * Semantic analysis of initializers. 3 1.1 mrg * 4 1.1 mrg * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved 5 1.1 mrg * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) 6 1.1 mrg * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 7 1.1 mrg * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/initsem.d, _initsem.d) 8 1.1 mrg * Documentation: https://dlang.org/phobos/dmd_initsem.html 9 1.1 mrg * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/initsem.d 10 1.1 mrg */ 11 1.1 mrg 12 1.1 mrg module dmd.initsem; 13 1.1 mrg 14 1.1 mrg import core.stdc.stdio; 15 1.1 mrg import core.checkedint; 16 1.1 mrg 17 1.1 mrg import dmd.aggregate; 18 1.1 mrg import dmd.aliasthis; 19 1.1 mrg import dmd.arraytypes; 20 1.1 mrg import dmd.astenums; 21 1.1 mrg import dmd.dcast; 22 1.1 mrg import dmd.declaration; 23 1.1 mrg import dmd.dscope; 24 1.1 mrg import dmd.dstruct; 25 1.1 mrg import dmd.dsymbol; 26 1.1 mrg import dmd.dtemplate; 27 1.1 mrg import dmd.errors; 28 1.1 mrg import dmd.expression; 29 1.1 mrg import dmd.expressionsem; 30 1.1 mrg import dmd.func; 31 1.1 mrg import dmd.globals; 32 1.1 mrg import dmd.id; 33 1.1 mrg import dmd.identifier; 34 1.1 mrg import dmd.importc; 35 1.1 mrg import dmd.init; 36 1.1 mrg import dmd.mtype; 37 1.1 mrg import dmd.opover; 38 1.1 mrg import dmd.statement; 39 1.1 mrg import dmd.target; 40 1.1 mrg import dmd.tokens; 41 1.1 mrg import dmd.typesem; 42 1.1 mrg 43 1.1 mrg /******************************** 44 1.1 mrg * If possible, convert array initializer to associative array initializer. 45 1.1 mrg * 46 1.1 mrg * Params: 47 1.1 mrg * ai = array initializer to be converted 48 1.1 mrg * 49 1.1 mrg * Returns: 50 1.1 mrg * The converted associative array initializer or ErrorExp if `ai` 51 1.1 mrg * is not an associative array initializer. 52 1.1 mrg */ 53 1.1 mrg Expression toAssocArrayLiteral(ArrayInitializer ai) 54 1.1 mrg { 55 1.1 mrg Expression e; 56 1.1 mrg //printf("ArrayInitializer::toAssocArrayInitializer()\n"); 57 1.1 mrg //static int i; if (++i == 2) assert(0); 58 1.1 mrg const dim = ai.value.dim; 59 1.1 mrg auto keys = new Expressions(dim); 60 1.1 mrg auto values = new Expressions(dim); 61 1.1 mrg for (size_t i = 0; i < dim; i++) 62 1.1 mrg { 63 1.1 mrg e = ai.index[i]; 64 1.1 mrg if (!e) 65 1.1 mrg goto Lno; 66 1.1 mrg (*keys)[i] = e; 67 1.1 mrg Initializer iz = ai.value[i]; 68 1.1 mrg if (!iz) 69 1.1 mrg goto Lno; 70 1.1 mrg e = iz.initializerToExpression(); 71 1.1 mrg if (!e) 72 1.1 mrg goto Lno; 73 1.1 mrg (*values)[i] = e; 74 1.1 mrg } 75 1.1 mrg e = new AssocArrayLiteralExp(ai.loc, keys, values); 76 1.1 mrg return e; 77 1.1 mrg Lno: 78 1.1 mrg error(ai.loc, "not an associative array initializer"); 79 1.1 mrg return ErrorExp.get(); 80 1.1 mrg } 81 1.1 mrg 82 1.1 mrg /****************************************** 83 1.1 mrg * Perform semantic analysis on init. 84 1.1 mrg * Params: 85 1.1 mrg * init = Initializer AST node 86 1.1 mrg * sc = context 87 1.1 mrg * tx = type that the initializer needs to become. If tx is an incomplete 88 1.1 mrg * type and the initializer completes it, it is updated to be the 89 1.1 mrg * complete type. ImportC has incomplete types 90 1.1 mrg * needInterpret = if CTFE needs to be run on this, 91 1.1 mrg * such as if it is the initializer for a const declaration 92 1.1 mrg * Returns: 93 1.1 mrg * `Initializer` with completed semantic analysis, `ErrorInitializer` if errors 94 1.1 mrg * were encountered 95 1.1 mrg */ 96 1.1 mrg extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedInterpret needInterpret) 97 1.1 mrg { 98 1.1 mrg Type t = tx; 99 1.1 mrg 100 1.1 mrg static Initializer err() 101 1.1 mrg { 102 1.1 mrg return new ErrorInitializer(); 103 1.1 mrg } 104 1.1 mrg 105 1.1 mrg Initializer visitVoid(VoidInitializer i) 106 1.1 mrg { 107 1.1 mrg i.type = t; 108 1.1 mrg return i; 109 1.1 mrg } 110 1.1 mrg 111 1.1 mrg Initializer visitError(ErrorInitializer i) 112 1.1 mrg { 113 1.1 mrg return i; 114 1.1 mrg } 115 1.1 mrg 116 1.1 mrg Initializer visitStruct(StructInitializer i) 117 1.1 mrg { 118 1.1 mrg //printf("StructInitializer::semantic(t = %s) %s\n", t.toChars(), i.toChars()); 119 1.1 mrg /* This works by replacing the StructInitializer with an ExpInitializer. 120 1.1 mrg */ 121 1.1 mrg t = t.toBasetype(); 122 1.1 mrg if (t.ty == Tsarray && t.nextOf().toBasetype().ty == Tstruct) 123 1.1 mrg t = t.nextOf().toBasetype(); 124 1.1 mrg if (auto ts = t.isTypeStruct()) 125 1.1 mrg { 126 1.1 mrg StructDeclaration sd = ts.sym; 127 1.1 mrg // check if the sd has a regular ctor (user defined non-copy ctor) 128 1.1 mrg // that is not disabled. 129 1.1 mrg if (sd.hasRegularCtor(true)) 130 1.1 mrg { 131 1.1 mrg error(i.loc, "%s `%s` has constructors, cannot use `{ initializers }`, use `%s( initializers )` instead", sd.kind(), sd.toChars(), sd.toChars()); 132 1.1 mrg return err(); 133 1.1 mrg } 134 1.1 mrg sd.size(i.loc); 135 1.1 mrg if (sd.sizeok != Sizeok.done) 136 1.1 mrg return err(); 137 1.1 mrg const nfields = sd.nonHiddenFields(); 138 1.1 mrg //expandTuples for non-identity arguments? 139 1.1 mrg auto elements = new Expressions(nfields); 140 1.1 mrg auto elems = (*elements)[]; 141 1.1 mrg foreach (ref elem; elems) 142 1.1 mrg elem = null; 143 1.1 mrg 144 1.1 mrg // Run semantic for explicitly given initializers 145 1.1 mrg // TODO: this part is slightly different from StructLiteralExp::semantic. 146 1.1 mrg bool errors = false; 147 1.1 mrg size_t fieldi = 0; 148 1.1 mrg foreach (j, id; i.field[]) 149 1.1 mrg { 150 1.1 mrg if (id) 151 1.1 mrg { 152 1.1 mrg /* Determine `fieldi` that `id` matches 153 1.1 mrg */ 154 1.1 mrg Dsymbol s = sd.search(i.loc, id); 155 1.1 mrg if (!s) 156 1.1 mrg { 157 1.1 mrg s = sd.search_correct(id); 158 1.1 mrg const initLoc = i.value[j].loc; 159 1.1 mrg if (s) 160 1.1 mrg error(initLoc, "`%s` is not a member of `%s`, did you mean %s `%s`?", id.toChars(), sd.toChars(), s.kind(), s.toChars()); 161 1.1 mrg else 162 1.1 mrg error(initLoc, "`%s` is not a member of `%s`", id.toChars(), sd.toChars()); 163 1.1 mrg return err(); 164 1.1 mrg } 165 1.1 mrg s.checkDeprecated(i.loc, sc); 166 1.1 mrg s = s.toAlias(); 167 1.1 mrg 168 1.1 mrg // Find out which field index `s` is 169 1.1 mrg for (fieldi = 0; 1; fieldi++) 170 1.1 mrg { 171 1.1 mrg if (fieldi >= nfields) 172 1.1 mrg { 173 1.1 mrg error(i.loc, "`%s.%s` is not a per-instance initializable field", sd.toChars(), s.toChars()); 174 1.1 mrg return err(); 175 1.1 mrg } 176 1.1 mrg if (s == sd.fields[fieldi]) 177 1.1 mrg break; 178 1.1 mrg } 179 1.1 mrg } 180 1.1 mrg if (j >= nfields) 181 1.1 mrg { 182 1.1 mrg error(i.value[j].loc, "too many initializers for `%s`", sd.toChars()); 183 1.1 mrg return err(); 184 1.1 mrg } 185 1.1 mrg 186 1.1 mrg VarDeclaration vd = sd.fields[fieldi]; 187 1.1 mrg if (elems[fieldi]) 188 1.1 mrg { 189 1.1 mrg error(i.value[j].loc, "duplicate initializer for field `%s`", vd.toChars()); 190 1.1 mrg errors = true; 191 1.1 mrg elems[fieldi] = ErrorExp.get(); // for better diagnostics on multiple errors 192 1.1 mrg ++fieldi; 193 1.1 mrg continue; 194 1.1 mrg } 195 1.1 mrg 196 1.1 mrg // Check for @safe violations 197 1.1 mrg if (vd.type.hasPointers) 198 1.1 mrg { 199 1.1 mrg if ((!t.alignment.isDefault() && t.alignment.get() < target.ptrsize || 200 1.1 mrg (vd.offset & (target.ptrsize - 1))) && 201 1.1 mrg sc.func && sc.func.setUnsafe()) 202 1.1 mrg { 203 1.1 mrg error(i.value[j].loc, "field `%s.%s` cannot assign to misaligned pointers in `@safe` code", 204 1.1 mrg sd.toChars(), vd.toChars()); 205 1.1 mrg errors = true; 206 1.1 mrg elems[fieldi] = ErrorExp.get(); // for better diagnostics on multiple errors 207 1.1 mrg ++fieldi; 208 1.1 mrg continue; 209 1.1 mrg } 210 1.1 mrg } 211 1.1 mrg 212 1.1 mrg // Check for overlapping initializations (can happen with unions) 213 1.1 mrg foreach (k, v2; sd.fields[0 .. nfields]) 214 1.1 mrg { 215 1.1 mrg if (vd.isOverlappedWith(v2) && elems[k]) 216 1.1 mrg { 217 1.1 mrg error(elems[k].loc, "overlapping initialization for field `%s` and `%s`", v2.toChars(), vd.toChars()); 218 1.1 mrg errors = true; 219 1.1 mrg continue; 220 1.1 mrg } 221 1.1 mrg } 222 1.1 mrg 223 1.1 mrg // Convert initializer to Expression `ex` 224 1.1 mrg assert(sc); 225 1.1 mrg auto tm = vd.type.addMod(t.mod); 226 1.1 mrg auto iz = i.value[j].initializerSemantic(sc, tm, needInterpret); 227 1.1 mrg auto ex = iz.initializerToExpression(); 228 1.1 mrg if (ex.op == EXP.error) 229 1.1 mrg { 230 1.1 mrg errors = true; 231 1.1 mrg elems[fieldi] = ErrorExp.get(); // for better diagnostics on multiple errors 232 1.1 mrg ++fieldi; 233 1.1 mrg continue; 234 1.1 mrg } 235 1.1 mrg 236 1.1 mrg i.value[j] = iz; 237 1.1 mrg elems[fieldi] = doCopyOrMove(sc, ex); 238 1.1 mrg ++fieldi; 239 1.1 mrg } 240 1.1 mrg if (errors) 241 1.1 mrg return err(); 242 1.1 mrg 243 1.1 mrg // Make a StructLiteralExp out of elements[] 244 1.1 mrg auto sle = new StructLiteralExp(i.loc, sd, elements, t); 245 1.1 mrg if (!sd.fill(i.loc, elements, false)) 246 1.1 mrg return err(); 247 1.1 mrg sle.type = t; 248 1.1 mrg auto ie = new ExpInitializer(i.loc, sle); 249 1.1 mrg return ie.initializerSemantic(sc, t, needInterpret); 250 1.1 mrg } 251 1.1 mrg else if ((t.ty == Tdelegate || t.isPtrToFunction()) && i.value.dim == 0) 252 1.1 mrg { 253 1.1 mrg const tok = (t.ty == Tdelegate) ? TOK.delegate_ : TOK.function_; 254 1.1 mrg /* Rewrite as empty delegate literal { } 255 1.1 mrg */ 256 1.1 mrg Type tf = new TypeFunction(ParameterList(), null, LINK.d); 257 1.1 mrg auto fd = new FuncLiteralDeclaration(i.loc, Loc.initial, tf, tok, null); 258 1.1 mrg fd.fbody = new CompoundStatement(i.loc, new Statements()); 259 1.1 mrg fd.endloc = i.loc; 260 1.1 mrg Expression e = new FuncExp(i.loc, fd); 261 1.1 mrg auto ie = new ExpInitializer(i.loc, e); 262 1.1 mrg return ie.initializerSemantic(sc, t, needInterpret); 263 1.1 mrg } 264 1.1 mrg if (t.ty != Terror) 265 1.1 mrg error(i.loc, "a struct is not a valid initializer for a `%s`", t.toChars()); 266 1.1 mrg return err(); 267 1.1 mrg } 268 1.1 mrg 269 1.1 mrg Initializer visitArray(ArrayInitializer i) 270 1.1 mrg { 271 1.1 mrg uint length; 272 1.1 mrg const(uint) amax = 0x80000000; 273 1.1 mrg bool errors = false; 274 1.1 mrg //printf("ArrayInitializer::semantic(%s)\n", t.toChars()); 275 1.1 mrg if (i.sem) // if semantic() already run 276 1.1 mrg { 277 1.1 mrg return i; 278 1.1 mrg } 279 1.1 mrg i.sem = true; 280 1.1 mrg t = t.toBasetype(); 281 1.1 mrg switch (t.ty) 282 1.1 mrg { 283 1.1 mrg case Tsarray: 284 1.1 mrg case Tarray: 285 1.1 mrg break; 286 1.1 mrg case Tvector: 287 1.1 mrg t = t.isTypeVector().basetype; 288 1.1 mrg break; 289 1.1 mrg case Taarray: 290 1.1 mrg case Tstruct: // consider implicit constructor call 291 1.1 mrg { 292 1.1 mrg Expression e; 293 1.1 mrg // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int]) 294 1.1 mrg if (t.ty == Taarray || i.isAssociativeArray()) 295 1.1 mrg e = i.toAssocArrayLiteral(); 296 1.1 mrg else 297 1.1 mrg e = i.initializerToExpression(); 298 1.1 mrg // Bugzilla 13987 299 1.1 mrg if (!e) 300 1.1 mrg { 301 1.1 mrg error(i.loc, "cannot use array to initialize `%s`", t.toChars()); 302 1.1 mrg return err(); 303 1.1 mrg } 304 1.1 mrg auto ei = new ExpInitializer(e.loc, e); 305 1.1 mrg return ei.initializerSemantic(sc, t, needInterpret); 306 1.1 mrg } 307 1.1 mrg case Tpointer: 308 1.1 mrg if (t.nextOf().ty != Tfunction) 309 1.1 mrg break; 310 1.1 mrg goto default; 311 1.1 mrg default: 312 1.1 mrg error(i.loc, "cannot use array to initialize `%s`", t.toChars()); 313 1.1 mrg return err(); 314 1.1 mrg } 315 1.1 mrg i.type = t; 316 1.1 mrg length = 0; 317 1.1 mrg for (size_t j = 0; j < i.index.dim; j++) 318 1.1 mrg { 319 1.1 mrg Expression idx = i.index[j]; 320 1.1 mrg if (idx) 321 1.1 mrg { 322 1.1 mrg sc = sc.startCTFE(); 323 1.1 mrg idx = idx.expressionSemantic(sc); 324 1.1 mrg sc = sc.endCTFE(); 325 1.1 mrg idx = idx.ctfeInterpret(); 326 1.1 mrg i.index[j] = idx; 327 1.1 mrg const uinteger_t idxvalue = idx.toInteger(); 328 1.1 mrg if (idxvalue >= amax) 329 1.1 mrg { 330 1.1 mrg error(i.loc, "array index %llu overflow", idxvalue); 331 1.1 mrg errors = true; 332 1.1 mrg } 333 1.1 mrg length = cast(uint)idxvalue; 334 1.1 mrg if (idx.op == EXP.error) 335 1.1 mrg errors = true; 336 1.1 mrg } 337 1.1 mrg Initializer val = i.value[j]; 338 1.1 mrg ExpInitializer ei = val.isExpInitializer(); 339 1.1 mrg if (ei && !idx) 340 1.1 mrg ei.expandTuples = true; 341 1.1 mrg auto tn = t.nextOf(); 342 1.1 mrg val = val.initializerSemantic(sc, tn, needInterpret); 343 1.1 mrg if (val.isErrorInitializer()) 344 1.1 mrg errors = true; 345 1.1 mrg ei = val.isExpInitializer(); 346 1.1 mrg // found a tuple, expand it 347 1.1 mrg if (ei && ei.exp.op == EXP.tuple) 348 1.1 mrg { 349 1.1 mrg TupleExp te = ei.exp.isTupleExp(); 350 1.1 mrg i.index.remove(j); 351 1.1 mrg i.value.remove(j); 352 1.1 mrg for (size_t k = 0; k < te.exps.dim; ++k) 353 1.1 mrg { 354 1.1 mrg Expression e = (*te.exps)[k]; 355 1.1 mrg i.index.insert(j + k, cast(Expression)null); 356 1.1 mrg i.value.insert(j + k, new ExpInitializer(e.loc, e)); 357 1.1 mrg } 358 1.1 mrg j--; 359 1.1 mrg continue; 360 1.1 mrg } 361 1.1 mrg else 362 1.1 mrg { 363 1.1 mrg i.value[j] = val; 364 1.1 mrg } 365 1.1 mrg length++; 366 1.1 mrg if (length == 0) 367 1.1 mrg { 368 1.1 mrg error(i.loc, "array dimension overflow"); 369 1.1 mrg return err(); 370 1.1 mrg } 371 1.1 mrg if (length > i.dim) 372 1.1 mrg i.dim = length; 373 1.1 mrg } 374 1.1 mrg if (auto tsa = t.isTypeSArray()) 375 1.1 mrg { 376 1.1 mrg uinteger_t edim = tsa.dim.toInteger(); 377 1.1 mrg if (i.dim > edim && !(tsa.isIncomplete() && (sc.flags & SCOPE.Cfile))) 378 1.1 mrg { 379 1.1 mrg error(i.loc, "array initializer has %u elements, but array length is %llu", i.dim, edim); 380 1.1 mrg return err(); 381 1.1 mrg } 382 1.1 mrg } 383 1.1 mrg if (errors) 384 1.1 mrg return err(); 385 1.1 mrg 386 1.1 mrg const sz = t.nextOf().size(); 387 1.1 mrg if (sz == SIZE_INVALID) 388 1.1 mrg return err(); 389 1.1 mrg bool overflow; 390 1.1 mrg const max = mulu(i.dim, sz, overflow); 391 1.1 mrg if (overflow || max >= amax) 392 1.1 mrg { 393 1.1 mrg error(i.loc, "array dimension %llu exceeds max of %llu", ulong(i.dim), ulong(amax / sz)); 394 1.1 mrg return err(); 395 1.1 mrg } 396 1.1 mrg return i; 397 1.1 mrg } 398 1.1 mrg 399 1.1 mrg Initializer visitExp(ExpInitializer i) 400 1.1 mrg { 401 1.1 mrg //printf("ExpInitializer::semantic(%s), type = %s\n", i.exp.toChars(), t.toChars()); 402 1.1 mrg if (needInterpret) 403 1.1 mrg sc = sc.startCTFE(); 404 1.1 mrg i.exp = i.exp.expressionSemantic(sc); 405 1.1 mrg i.exp = resolveProperties(sc, i.exp); 406 1.1 mrg if (needInterpret) 407 1.1 mrg sc = sc.endCTFE(); 408 1.1 mrg if (i.exp.op == EXP.error) 409 1.1 mrg return err(); 410 1.1 mrg uint olderrors = global.errors; 411 1.1 mrg 412 1.1 mrg /* ImportC: convert arrays to pointers, functions to pointers to functions 413 1.1 mrg */ 414 1.1 mrg Type tb = t.toBasetype(); 415 1.1 mrg if (tb.isTypePointer()) 416 1.1 mrg i.exp = i.exp.arrayFuncConv(sc); 417 1.1 mrg 418 1.1 mrg /* Save the expression before ctfe 419 1.1 mrg * Otherwise the error message would contain for example "&[0][0]" instead of "new int" 420 1.1 mrg * Regression: https://issues.dlang.org/show_bug.cgi?id=21687 421 1.1 mrg */ 422 1.1 mrg Expression currExp = i.exp; 423 1.1 mrg if (needInterpret) 424 1.1 mrg { 425 1.1 mrg // If the result will be implicitly cast, move the cast into CTFE 426 1.1 mrg // to avoid premature truncation of polysemous types. 427 1.1 mrg // eg real [] x = [1.1, 2.2]; should use real precision. 428 1.1 mrg if (i.exp.implicitConvTo(t) && !(sc.flags & SCOPE.Cfile)) 429 1.1 mrg { 430 1.1 mrg i.exp = i.exp.implicitCastTo(sc, t); 431 1.1 mrg } 432 1.1 mrg if (!global.gag && olderrors != global.errors) 433 1.1 mrg { 434 1.1 mrg return i; 435 1.1 mrg } 436 1.1 mrg if (sc.flags & SCOPE.Cfile) 437 1.1 mrg { 438 1.1 mrg /* the interpreter turns (char*)"string" into &"string"[0] which then 439 1.1 mrg * it cannot interpret. Resolve that case by doing optimize() first 440 1.1 mrg */ 441 1.1 mrg i.exp = i.exp.optimize(WANTvalue); 442 1.1 mrg if (i.exp.isSymOffExp()) 443 1.1 mrg { 444 1.1 mrg /* `static variable cannot be read at compile time` 445 1.1 mrg * https://issues.dlang.org/show_bug.cgi?id=22513 446 1.1 mrg * Maybe this would be better addressed in ctfeInterpret()? 447 1.1 mrg */ 448 1.1 mrg needInterpret = NeedInterpret.INITnointerpret; 449 1.1 mrg } 450 1.1 mrg } 451 1.1 mrg if (needInterpret) 452 1.1 mrg i.exp = i.exp.ctfeInterpret(); 453 1.1 mrg if (i.exp.op == EXP.voidExpression) 454 1.1 mrg error(i.loc, "variables cannot be initialized with an expression of type `void`. Use `void` initialization instead."); 455 1.1 mrg } 456 1.1 mrg else 457 1.1 mrg { 458 1.1 mrg i.exp = i.exp.optimize(WANTvalue); 459 1.1 mrg } 460 1.1 mrg 461 1.1 mrg if (!global.gag && olderrors != global.errors) 462 1.1 mrg { 463 1.1 mrg return i; // Failed, suppress duplicate error messages 464 1.1 mrg } 465 1.1 mrg if (i.exp.type.isTypeTuple() && i.exp.type.isTypeTuple().arguments.dim == 0) 466 1.1 mrg { 467 1.1 mrg Type et = i.exp.type; 468 1.1 mrg i.exp = new TupleExp(i.exp.loc, new Expressions()); 469 1.1 mrg i.exp.type = et; 470 1.1 mrg } 471 1.1 mrg if (i.exp.op == EXP.type) 472 1.1 mrg { 473 1.1 mrg i.exp.error("initializer must be an expression, not `%s`", i.exp.toChars()); 474 1.1 mrg return err(); 475 1.1 mrg } 476 1.1 mrg // Make sure all pointers are constants 477 1.1 mrg if (needInterpret && hasNonConstPointers(i.exp)) 478 1.1 mrg { 479 1.1 mrg i.exp.error("cannot use non-constant CTFE pointer in an initializer `%s`", currExp.toChars()); 480 1.1 mrg return err(); 481 1.1 mrg } 482 1.1 mrg Type ti = i.exp.type.toBasetype(); 483 1.1 mrg if (i.exp.op == EXP.tuple && i.expandTuples && !i.exp.implicitConvTo(t)) 484 1.1 mrg { 485 1.1 mrg return new ExpInitializer(i.loc, i.exp); 486 1.1 mrg } 487 1.1 mrg /* Look for case of initializing a static array with a too-short 488 1.1 mrg * string literal, such as: 489 1.1 mrg * char[5] foo = "abc"; 490 1.1 mrg * Allow this by doing an explicit cast, which will lengthen the string 491 1.1 mrg * literal. 492 1.1 mrg */ 493 1.1 mrg if (i.exp.op == EXP.string_ && tb.ty == Tsarray) 494 1.1 mrg { 495 1.1 mrg StringExp se = i.exp.isStringExp(); 496 1.1 mrg Type typeb = se.type.toBasetype(); 497 1.1 mrg TY tynto = tb.nextOf().ty; 498 1.1 mrg if (!se.committed && 499 1.1 mrg (typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar && 500 1.1 mrg se.numberOfCodeUnits(tynto) < tb.isTypeSArray().dim.toInteger()) 501 1.1 mrg { 502 1.1 mrg i.exp = se.castTo(sc, t); 503 1.1 mrg goto L1; 504 1.1 mrg } 505 1.1 mrg 506 1.1 mrg /* Lop off terminating 0 of initializer for: 507 1.1 mrg * static char s[5] = "hello"; 508 1.1 mrg */ 509 1.1 mrg if (sc.flags & SCOPE.Cfile && 510 1.1 mrg typeb.ty == Tsarray && 511 1.1 mrg tynto.isSomeChar && 512 1.1 mrg tb.isTypeSArray().dim.toInteger() + 1 == typeb.isTypeSArray().dim.toInteger()) 513 1.1 mrg { 514 1.1 mrg i.exp = se.castTo(sc, t); 515 1.1 mrg goto L1; 516 1.1 mrg } 517 1.1 mrg } 518 1.1 mrg /* C11 6.7.9-14..15 519 1.1 mrg * Initialize an array of unknown size with a string. 520 1.1 mrg * Change to static array of known size 521 1.1 mrg */ 522 1.1 mrg if (sc.flags & SCOPE.Cfile && i.exp.isStringExp() && 523 1.1 mrg tb.isTypeSArray() && tb.isTypeSArray().isIncomplete()) 524 1.1 mrg { 525 1.1 mrg StringExp se = i.exp.isStringExp(); 526 1.1 mrg auto ts = new TypeSArray(tb.nextOf(), new IntegerExp(Loc.initial, se.len + 1, Type.tsize_t)); 527 1.1 mrg t = typeSemantic(ts, Loc.initial, sc); 528 1.1 mrg i.exp.type = t; 529 1.1 mrg tx = t; 530 1.1 mrg } 531 1.1 mrg 532 1.1 mrg // Look for implicit constructor call 533 1.1 mrg if (tb.ty == Tstruct && !(ti.ty == Tstruct && tb.toDsymbol(sc) == ti.toDsymbol(sc)) && !i.exp.implicitConvTo(t)) 534 1.1 mrg { 535 1.1 mrg StructDeclaration sd = tb.isTypeStruct().sym; 536 1.1 mrg if (sd.ctor) 537 1.1 mrg { 538 1.1 mrg // Rewrite as S().ctor(exp) 539 1.1 mrg Expression e; 540 1.1 mrg e = new StructLiteralExp(i.loc, sd, null); 541 1.1 mrg e = new DotIdExp(i.loc, e, Id.ctor); 542 1.1 mrg e = new CallExp(i.loc, e, i.exp); 543 1.1 mrg e = e.expressionSemantic(sc); 544 1.1 mrg if (needInterpret) 545 1.1 mrg i.exp = e.ctfeInterpret(); 546 1.1 mrg else 547 1.1 mrg i.exp = e.optimize(WANTvalue); 548 1.1 mrg } 549 1.1 mrg else if (search_function(sd, Id.call)) 550 1.1 mrg { 551 1.1 mrg /* https://issues.dlang.org/show_bug.cgi?id=1547 552 1.1 mrg * 553 1.1 mrg * Look for static opCall 554 1.1 mrg * 555 1.1 mrg * Rewrite as: 556 1.1 mrg * i.exp = typeof(sd).opCall(arguments) 557 1.1 mrg */ 558 1.1 mrg 559 1.1 mrg Expression e = typeDotIdExp(i.loc, sd.type, Id.call); 560 1.1 mrg e = new CallExp(i.loc, e, i.exp); 561 1.1 mrg e = e.expressionSemantic(sc); 562 1.1 mrg e = resolveProperties(sc, e); 563 1.1 mrg if (needInterpret) 564 1.1 mrg i.exp = e.ctfeInterpret(); 565 1.1 mrg else 566 1.1 mrg i.exp = e.optimize(WANTvalue); 567 1.1 mrg } 568 1.1 mrg } 569 1.1 mrg { 570 1.1 mrg // Look for the case of statically initializing an array 571 1.1 mrg // with a single member. 572 1.1 mrg auto tba = tb.isTypeSArray(); 573 1.1 mrg if (tba && !tba.next.equals(ti.toBasetype().nextOf()) && i.exp.implicitConvTo(tba.next)) 574 1.1 mrg { 575 1.1 mrg /* If the variable is not actually used in compile time, array creation is 576 1.1 mrg * redundant. So delay it until invocation of toExpression() or toDt(). 577 1.1 mrg */ 578 1.1 mrg t = tb.nextOf(); 579 1.1 mrg } 580 1.1 mrg 581 1.1 mrg auto tta = t.isTypeSArray(); 582 1.1 mrg if (i.exp.implicitConvTo(t)) 583 1.1 mrg { 584 1.1 mrg i.exp = i.exp.implicitCastTo(sc, t); 585 1.1 mrg } 586 1.1 mrg else if (sc.flags & SCOPE.Cfile && i.exp.isStringExp() && 587 1.1 mrg tta && (tta.next.ty == Tint8 || tta.next.ty == Tuns8) && 588 1.1 mrg ti.ty == Tpointer && ti.nextOf().ty == Tchar) 589 1.1 mrg { 590 1.1 mrg /* unsigned char bbb[1] = ""; 591 1.1 mrg * signed char ccc[1] = ""; 592 1.1 mrg */ 593 1.1 mrg i.exp = i.exp.castTo(sc, t); 594 1.1 mrg } 595 1.1 mrg else 596 1.1 mrg { 597 1.1 mrg // Look for mismatch of compile-time known length to emit 598 1.1 mrg // better diagnostic message, as same as AssignExp::semantic. 599 1.1 mrg if (tba && i.exp.implicitConvTo(tba.next.arrayOf()) > MATCH.nomatch) 600 1.1 mrg { 601 1.1 mrg uinteger_t dim1 = tba.dim.toInteger(); 602 1.1 mrg uinteger_t dim2 = dim1; 603 1.1 mrg if (auto ale = i.exp.isArrayLiteralExp()) 604 1.1 mrg { 605 1.1 mrg dim2 = ale.elements ? ale.elements.dim : 0; 606 1.1 mrg } 607 1.1 mrg else if (auto se = i.exp.isSliceExp()) 608 1.1 mrg { 609 1.1 mrg if (Type tx = toStaticArrayType(se)) 610 1.1 mrg dim2 = tx.isTypeSArray().dim.toInteger(); 611 1.1 mrg } 612 1.1 mrg if (dim1 != dim2) 613 1.1 mrg { 614 1.1 mrg i.exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2); 615 1.1 mrg i.exp = ErrorExp.get(); 616 1.1 mrg } 617 1.1 mrg } 618 1.1 mrg Type et = i.exp.type; 619 1.1 mrg const errors = global.startGagging(); 620 1.1 mrg i.exp = i.exp.implicitCastTo(sc, t); 621 1.1 mrg if (global.endGagging(errors)) 622 1.1 mrg currExp.error("cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars()); 623 1.1 mrg } 624 1.1 mrg } 625 1.1 mrg L1: 626 1.1 mrg if (i.exp.op == EXP.error) 627 1.1 mrg { 628 1.1 mrg return i; 629 1.1 mrg } 630 1.1 mrg if (needInterpret) 631 1.1 mrg i.exp = i.exp.ctfeInterpret(); 632 1.1 mrg else 633 1.1 mrg i.exp = i.exp.optimize(WANTvalue); 634 1.1 mrg //printf("-ExpInitializer::semantic(): "); i.exp.print(); 635 1.1 mrg return i; 636 1.1 mrg } 637 1.1 mrg 638 1.1 mrg Initializer visitC(CInitializer ci) 639 1.1 mrg { 640 1.1 mrg if (ci.sem) // if semantic() already run 641 1.1 mrg return ci; 642 1.1 mrg //printf("CInitializer::semantic() (%s) %s\n", t.toChars(), ci.toChars()); 643 1.1 mrg ci.sem = true; 644 1.1 mrg t = t.toBasetype(); 645 1.1 mrg ci.type = t; // later passes will need this 646 1.1 mrg 647 1.1 mrg auto dil = ci.initializerList[]; 648 1.1 mrg size_t i = 0; // index into dil[] 649 1.1 mrg const uint amax = 0x8000_0000; 650 1.1 mrg bool errors; 651 1.1 mrg 652 1.1 mrg /* If `{ expression }` return the expression initializer 653 1.1 mrg */ 654 1.1 mrg ExpInitializer isBraceExpression() 655 1.1 mrg { 656 1.1 mrg return (dil.length == 1 && !dil[0].designatorList) 657 1.1 mrg ? dil[0].initializer.isExpInitializer() 658 1.1 mrg : null; 659 1.1 mrg } 660 1.1 mrg 661 1.1 mrg /* Convert struct initializer into ExpInitializer 662 1.1 mrg */ 663 1.1 mrg Initializer structs(TypeStruct ts) 664 1.1 mrg { 665 1.1 mrg //printf("structs %s\n", ts.toChars()); 666 1.1 mrg StructDeclaration sd = ts.sym; 667 1.1 mrg sd.size(ci.loc); 668 1.1 mrg if (sd.sizeok != Sizeok.done) 669 1.1 mrg { 670 1.1 mrg errors = true; 671 1.1 mrg return err(); 672 1.1 mrg } 673 1.1 mrg const nfields = sd.nonHiddenFields(); 674 1.1 mrg auto elements = new Expressions(nfields); 675 1.1 mrg auto elems = (*elements)[]; 676 1.1 mrg foreach (ref elem; elems) 677 1.1 mrg elem = null; 678 1.1 mrg 679 1.1 mrg FieldLoop: 680 1.1 mrg for (size_t fieldi = 0; fieldi < nfields; ++fieldi) 681 1.1 mrg { 682 1.1 mrg if (i == dil.length) 683 1.1 mrg break; 684 1.1 mrg 685 1.1 mrg auto di = dil[i]; 686 1.1 mrg if (di.designatorList) 687 1.1 mrg { 688 1.1 mrg error(ci.loc, "C designator-list not supported yet"); 689 1.1 mrg errors = true; 690 1.1 mrg break; 691 1.1 mrg } 692 1.1 mrg 693 1.1 mrg VarDeclaration vd = sd.fields[fieldi]; 694 1.1 mrg 695 1.1 mrg // Check for overlapping initializations (can happen with unions) 696 1.1 mrg foreach (k, v2; sd.fields[0 .. nfields]) 697 1.1 mrg { 698 1.1 mrg if (vd.isOverlappedWith(v2) && elems[k]) 699 1.1 mrg { 700 1.1 mrg continue FieldLoop; // skip it 701 1.1 mrg } 702 1.1 mrg } 703 1.1 mrg 704 1.1 mrg ++i; 705 1.1 mrg 706 1.1 mrg // Convert initializer to Expression `ex` 707 1.1 mrg assert(sc); 708 1.1 mrg auto tm = vd.type.addMod(ts.mod); 709 1.1 mrg auto iz = di.initializer.initializerSemantic(sc, tm, needInterpret); 710 1.1 mrg auto ex = iz.initializerToExpression(null, true); 711 1.1 mrg if (ex.op == EXP.error) 712 1.1 mrg { 713 1.1 mrg errors = true; 714 1.1 mrg continue; 715 1.1 mrg } 716 1.1 mrg 717 1.1 mrg elems[fieldi] = ex; 718 1.1 mrg } 719 1.1 mrg if (errors) 720 1.1 mrg return err(); 721 1.1 mrg 722 1.1 mrg // Make a StructLiteralExp out of elements[] 723 1.1 mrg Type tx = ts; 724 1.1 mrg auto sle = new StructLiteralExp(ci.loc, sd, elements, tx); 725 1.1 mrg if (!sd.fill(ci.loc, elements, false)) 726 1.1 mrg return err(); 727 1.1 mrg sle.type = tx; 728 1.1 mrg auto ie = new ExpInitializer(ci.loc, sle); 729 1.1 mrg return ie.initializerSemantic(sc, tx, needInterpret); 730 1.1 mrg } 731 1.1 mrg 732 1.1 mrg if (auto ts = t.isTypeStruct()) 733 1.1 mrg { 734 1.1 mrg auto ei = structs(ts); 735 1.1 mrg if (errors) 736 1.1 mrg return err(); 737 1.1 mrg if (i < dil.length) 738 1.1 mrg { 739 1.1 mrg error(ci.loc, "%d extra initializer(s) for `struct %s`", cast(int)(dil.length - i), ts.toChars()); 740 1.1 mrg return err(); 741 1.1 mrg } 742 1.1 mrg return ei; 743 1.1 mrg } 744 1.1 mrg 745 1.1 mrg auto tsa = t.isTypeSArray(); 746 1.1 mrg if (!tsa) 747 1.1 mrg { 748 1.1 mrg /* Not an array. See if it is `{ exp }` which can be 749 1.1 mrg * converted to an ExpInitializer 750 1.1 mrg */ 751 1.1 mrg if (ExpInitializer ei = isBraceExpression()) 752 1.1 mrg { 753 1.1 mrg return ei.initializerSemantic(sc, t, needInterpret); 754 1.1 mrg } 755 1.1 mrg 756 1.1 mrg error(ci.loc, "C non-array initializer (%s) %s not supported yet", t.toChars(), ci.toChars()); 757 1.1 mrg return err(); 758 1.1 mrg } 759 1.1 mrg 760 1.1 mrg /* If it's an array of integral being initialized by `{ string }` 761 1.1 mrg * replace with `string` 762 1.1 mrg */ 763 1.1 mrg auto tn = t.nextOf(); 764 1.1 mrg if (tn.isintegral()) 765 1.1 mrg { 766 1.1 mrg if (ExpInitializer ei = isBraceExpression()) 767 1.1 mrg { 768 1.1 mrg if (ei.exp.isStringExp()) 769 1.1 mrg return ei.initializerSemantic(sc, t, needInterpret); 770 1.1 mrg } 771 1.1 mrg } 772 1.1 mrg 773 1.1 mrg /* Support recursion to handle un-braced array initializers 774 1.1 mrg * Params: 775 1.1 mrg * t = element type 776 1.1 mrg * dim = max number of elements 777 1.1 mrg * simple = true if array of simple elements 778 1.1 mrg * Returns: 779 1.1 mrg * # of elements in array 780 1.1 mrg */ 781 1.1 mrg size_t array(Type t, size_t dim, ref bool simple) 782 1.1 mrg { 783 1.1 mrg //printf(" type %s i %d dim %d dil.length = %d\n", t.toChars(), cast(int)i, cast(int)dim, cast(int)dil.length); 784 1.1 mrg auto tn = t.nextOf().toBasetype(); 785 1.1 mrg auto tnsa = tn.isTypeSArray(); 786 1.1 mrg if (tnsa && tnsa.isIncomplete()) 787 1.1 mrg { 788 1.1 mrg // C11 6.2.5-20 "element type shall be complete whenever the array type is specified" 789 1.1 mrg error(ci.loc, "incomplete element type `%s` not allowed", tnsa.toChars()); 790 1.1 mrg errors = true; 791 1.1 mrg return 1; 792 1.1 mrg } 793 1.1 mrg if (i == dil.length) 794 1.1 mrg return 0; 795 1.1 mrg size_t n; 796 1.1 mrg const nelems = tnsa ? cast(size_t)tnsa.dim.toInteger() : 0; 797 1.1 mrg 798 1.1 mrg /* Run initializerSemantic on a single element. 799 1.1 mrg */ 800 1.1 mrg Initializer elem(Initializer ie) 801 1.1 mrg { 802 1.1 mrg ++i; 803 1.1 mrg auto tnx = tn; // in case initializerSemantic tries to change it 804 1.1 mrg ie = ie.initializerSemantic(sc, tnx, needInterpret); 805 1.1 mrg if (ie.isErrorInitializer()) 806 1.1 mrg errors = true; 807 1.1 mrg assert(tnx == tn); // sub-types should not be modified 808 1.1 mrg return ie; 809 1.1 mrg } 810 1.1 mrg 811 1.1 mrg foreach (j; 0 .. dim) 812 1.1 mrg { 813 1.1 mrg auto di = dil[i]; 814 1.1 mrg if (di.designatorList) 815 1.1 mrg { 816 1.1 mrg error(ci.loc, "C designator-list not supported yet"); 817 1.1 mrg errors = true; 818 1.1 mrg break; 819 1.1 mrg } 820 1.1 mrg if (tnsa && di.initializer.isExpInitializer()) 821 1.1 mrg { 822 1.1 mrg // no braces enclosing array initializer, so recurse 823 1.1 mrg array(tnsa, nelems, simple); 824 1.1 mrg } 825 1.1 mrg else if (auto tns = tn.isTypeStruct()) 826 1.1 mrg { 827 1.1 mrg if (auto ei = di.initializer.isExpInitializer()) 828 1.1 mrg { 829 1.1 mrg // no braces enclosing struct initializer 830 1.1 mrg 831 1.1 mrg /* Disambiguate between an exp representing the entire 832 1.1 mrg * struct, and an exp representing the first field of the struct 833 1.1 mrg */ 834 1.1 mrg if (needInterpret) 835 1.1 mrg sc = sc.startCTFE(); 836 1.1 mrg ei.exp = ei.exp.expressionSemantic(sc); 837 1.1 mrg ei.exp = resolveProperties(sc, ei.exp); 838 1.1 mrg if (needInterpret) 839 1.1 mrg sc = sc.endCTFE(); 840 1.1 mrg if (ei.exp.implicitConvTo(tn)) 841 1.1 mrg di.initializer = elem(di.initializer); // the whole struct 842 1.1 mrg else 843 1.1 mrg { 844 1.1 mrg simple = false; 845 1.1 mrg dil[n].initializer = structs(tns); // the first field 846 1.1 mrg } 847 1.1 mrg } 848 1.1 mrg else 849 1.1 mrg dil[n].initializer = elem(di.initializer); 850 1.1 mrg } 851 1.1 mrg else 852 1.1 mrg { 853 1.1 mrg di.initializer = elem(di.initializer); 854 1.1 mrg } 855 1.1 mrg ++n; 856 1.1 mrg if (i == dil.length) 857 1.1 mrg break; 858 1.1 mrg } 859 1.1 mrg //printf(" n: %d i: %d\n", cast(int)n, cast(int)i); 860 1.1 mrg return n; 861 1.1 mrg } 862 1.1 mrg 863 1.1 mrg size_t dim = tsa.isIncomplete() ? dil.length : cast(size_t)tsa.dim.toInteger(); 864 1.1 mrg bool simple = true; 865 1.1 mrg auto newdim = array(t, dim, simple); 866 1.1 mrg 867 1.1 mrg if (errors) 868 1.1 mrg return err(); 869 1.1 mrg 870 1.1 mrg if (tsa.isIncomplete()) // array of unknown length 871 1.1 mrg { 872 1.1 mrg // Change to array of known length 873 1.1 mrg tsa = new TypeSArray(tn, new IntegerExp(Loc.initial, newdim, Type.tsize_t)); 874 1.1 mrg tx = tsa; // rewrite caller's type 875 1.1 mrg ci.type = tsa; // remember for later passes 876 1.1 mrg } 877 1.1 mrg const uinteger_t edim = tsa.dim.toInteger(); 878 1.1 mrg if (i < dil.length) 879 1.1 mrg { 880 1.1 mrg error(ci.loc, "%d extra initializer(s) for static array length of %d", cast(int)(dil.length - i), cast(int)edim); 881 1.1 mrg return err(); 882 1.1 mrg } 883 1.1 mrg 884 1.1 mrg const sz = tn.size(); // element size 885 1.1 mrg if (sz == SIZE_INVALID) 886 1.1 mrg return err(); 887 1.1 mrg bool overflow; 888 1.1 mrg const max = mulu(edim, sz, overflow); 889 1.1 mrg if (overflow || max >= amax) 890 1.1 mrg { 891 1.1 mrg error(ci.loc, "array dimension %llu exceeds max of %llu", ulong(edim), ulong(amax / sz)); 892 1.1 mrg return err(); 893 1.1 mrg } 894 1.1 mrg 895 1.1 mrg /* If an array of simple elements, replace with an ArrayInitializer 896 1.1 mrg */ 897 1.1 mrg auto tnb = tn.toBasetype(); 898 1.1 mrg if (!tnb.isTypeSArray() && (!tnb.isTypeStruct() || simple)) 899 1.1 mrg { 900 1.1 mrg auto ai = new ArrayInitializer(ci.loc); 901 1.1 mrg ai.dim = cast(uint) dil.length; 902 1.1 mrg ai.index.setDim(dil.length); 903 1.1 mrg ai.value.setDim(dil.length); 904 1.1 mrg foreach (const j; 0 .. dil.length) 905 1.1 mrg { 906 1.1 mrg ai.index[j] = null; 907 1.1 mrg ai.value[j] = dil[j].initializer; 908 1.1 mrg } 909 1.1 mrg auto ty = tx; 910 1.1 mrg return ai.initializerSemantic(sc, ty, needInterpret); 911 1.1 mrg } 912 1.1 mrg 913 1.1 mrg if (newdim < ci.initializerList.length && tnb.isTypeStruct()) 914 1.1 mrg { 915 1.1 mrg // https://issues.dlang.org/show_bug.cgi?id=22375 916 1.1 mrg // initializerList can be bigger than the number of actual elements 917 1.1 mrg // to initialize for array of structs because it is not required 918 1.1 mrg // for values to have proper bracing. 919 1.1 mrg // i.e: These are all valid initializers for `struct{int a,b;}[3]`: 920 1.1 mrg // {1,2,3,4}, {{1,2},3,4}, {1,2,{3,4}}, {{1,2},{3,4}} 921 1.1 mrg // In all examples above, the new length of the initializer list 922 1.1 mrg // has been shortened from four elements to two. This is important, 923 1.1 mrg // because `dil` is written back to directly, making the lowered 924 1.1 mrg // initializer `{{1,2},{3,4}}` and not `{{1,2},{3,4},3,4}`. 925 1.1 mrg ci.initializerList.length = newdim; 926 1.1 mrg } 927 1.1 mrg 928 1.1 mrg return ci; 929 1.1 mrg } 930 1.1 mrg 931 1.1 mrg final switch (init.kind) 932 1.1 mrg { 933 1.1 mrg case InitKind.void_: return visitVoid (init.isVoidInitializer()); 934 1.1 mrg case InitKind.error: return visitError (init.isErrorInitializer()); 935 1.1 mrg case InitKind.struct_: return visitStruct(init.isStructInitializer()); 936 1.1 mrg case InitKind.array: return visitArray (init.isArrayInitializer()); 937 1.1 mrg case InitKind.exp: return visitExp (init.isExpInitializer()); 938 1.1 mrg case InitKind.C_: return visitC (init.isCInitializer()); 939 1.1 mrg } 940 1.1 mrg } 941 1.1 mrg 942 1.1 mrg /*********************** 943 1.1 mrg * Translate init to an `Expression` in order to infer the type. 944 1.1 mrg * Params: 945 1.1 mrg * init = `Initializer` AST node 946 1.1 mrg * sc = context 947 1.1 mrg * Returns: 948 1.1 mrg * an equivalent `ExpInitializer` if successful, or `ErrorInitializer` if it cannot be translated 949 1.1 mrg */ 950 1.1 mrg Initializer inferType(Initializer init, Scope* sc) 951 1.1 mrg { 952 1.1 mrg Initializer visitVoid(VoidInitializer i) 953 1.1 mrg { 954 1.1 mrg error(i.loc, "cannot infer type from void initializer"); 955 1.1 mrg return new ErrorInitializer(); 956 1.1 mrg } 957 1.1 mrg 958 1.1 mrg Initializer visitError(ErrorInitializer i) 959 1.1 mrg { 960 1.1 mrg return i; 961 1.1 mrg } 962 1.1 mrg 963 1.1 mrg Initializer visitStruct(StructInitializer i) 964 1.1 mrg { 965 1.1 mrg error(i.loc, "cannot infer type from struct initializer"); 966 1.1 mrg return new ErrorInitializer(); 967 1.1 mrg } 968 1.1 mrg 969 1.1 mrg Initializer visitArray(ArrayInitializer init) 970 1.1 mrg { 971 1.1 mrg //printf("ArrayInitializer::inferType() %s\n", toChars()); 972 1.1 mrg Expressions* keys = null; 973 1.1 mrg Expressions* values; 974 1.1 mrg if (init.isAssociativeArray()) 975 1.1 mrg { 976 1.1 mrg keys = new Expressions(init.value.dim); 977 1.1 mrg values = new Expressions(init.value.dim); 978 1.1 mrg for (size_t i = 0; i < init.value.dim; i++) 979 1.1 mrg { 980 1.1 mrg Expression e = init.index[i]; 981 1.1 mrg if (!e) 982 1.1 mrg goto Lno; 983 1.1 mrg (*keys)[i] = e; 984 1.1 mrg Initializer iz = init.value[i]; 985 1.1 mrg if (!iz) 986 1.1 mrg goto Lno; 987 1.1 mrg iz = iz.inferType(sc); 988 1.1 mrg if (iz.isErrorInitializer()) 989 1.1 mrg { 990 1.1 mrg return iz; 991 1.1 mrg } 992 1.1 mrg (*values)[i] = iz.isExpInitializer().exp; 993 1.1 mrg assert(!(*values)[i].isErrorExp()); 994 1.1 mrg } 995 1.1 mrg Expression e = new AssocArrayLiteralExp(init.loc, keys, values); 996 1.1 mrg auto ei = new ExpInitializer(init.loc, e); 997 1.1 mrg return ei.inferType(sc); 998 1.1 mrg } 999 1.1 mrg else 1000 1.1 mrg { 1001 1.1 mrg auto elements = new Expressions(init.value.dim); 1002 1.1 mrg elements.zero(); 1003 1.1 mrg for (size_t i = 0; i < init.value.dim; i++) 1004 1.1 mrg { 1005 1.1 mrg assert(!init.index[i]); // already asserted by isAssociativeArray() 1006 1.1 mrg Initializer iz = init.value[i]; 1007 1.1 mrg if (!iz) 1008 1.1 mrg goto Lno; 1009 1.1 mrg iz = iz.inferType(sc); 1010 1.1 mrg if (iz.isErrorInitializer()) 1011 1.1 mrg { 1012 1.1 mrg return iz; 1013 1.1 mrg } 1014 1.1 mrg (*elements)[i] = iz.isExpInitializer().exp; 1015 1.1 mrg assert(!(*elements)[i].isErrorExp()); 1016 1.1 mrg } 1017 1.1 mrg Expression e = new ArrayLiteralExp(init.loc, null, elements); 1018 1.1 mrg auto ei = new ExpInitializer(init.loc, e); 1019 1.1 mrg return ei.inferType(sc); 1020 1.1 mrg } 1021 1.1 mrg Lno: 1022 1.1 mrg if (keys) 1023 1.1 mrg { 1024 1.1 mrg error(init.loc, "not an associative array initializer"); 1025 1.1 mrg } 1026 1.1 mrg else 1027 1.1 mrg { 1028 1.1 mrg error(init.loc, "cannot infer type from array initializer"); 1029 1.1 mrg } 1030 1.1 mrg return new ErrorInitializer(); 1031 1.1 mrg } 1032 1.1 mrg 1033 1.1 mrg Initializer visitExp(ExpInitializer init) 1034 1.1 mrg { 1035 1.1 mrg //printf("ExpInitializer::inferType() %s\n", init.toChars()); 1036 1.1 mrg init.exp = init.exp.expressionSemantic(sc); 1037 1.1 mrg 1038 1.1 mrg // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 1039 1.1 mrg if (init.exp.op == EXP.type) 1040 1.1 mrg init.exp = resolveAliasThis(sc, init.exp); 1041 1.1 mrg 1042 1.1 mrg init.exp = resolveProperties(sc, init.exp); 1043 1.1 mrg if (auto se = init.exp.isScopeExp()) 1044 1.1 mrg { 1045 1.1 mrg TemplateInstance ti = se.sds.isTemplateInstance(); 1046 1.1 mrg if (ti && ti.semanticRun == PASS.semantic && !ti.aliasdecl) 1047 1.1 mrg se.error("cannot infer type from %s `%s`, possible circular dependency", se.sds.kind(), se.toChars()); 1048 1.1 mrg else 1049 1.1 mrg se.error("cannot infer type from %s `%s`", se.sds.kind(), se.toChars()); 1050 1.1 mrg return new ErrorInitializer(); 1051 1.1 mrg } 1052 1.1 mrg 1053 1.1 mrg // Give error for overloaded function addresses 1054 1.1 mrg bool hasOverloads; 1055 1.1 mrg if (auto f = isFuncAddress(init.exp, &hasOverloads)) 1056 1.1 mrg { 1057 1.1 mrg if (f.checkForwardRef(init.loc)) 1058 1.1 mrg { 1059 1.1 mrg return new ErrorInitializer(); 1060 1.1 mrg } 1061 1.1 mrg if (hasOverloads && !f.isUnique()) 1062 1.1 mrg { 1063 1.1 mrg init.exp.error("cannot infer type from overloaded function symbol `%s`", init.exp.toChars()); 1064 1.1 mrg return new ErrorInitializer(); 1065 1.1 mrg } 1066 1.1 mrg } 1067 1.1 mrg if (auto ae = init.exp.isAddrExp()) 1068 1.1 mrg { 1069 1.1 mrg if (ae.e1.op == EXP.overloadSet) 1070 1.1 mrg { 1071 1.1 mrg init.exp.error("cannot infer type from overloaded function symbol `%s`", init.exp.toChars()); 1072 1.1 mrg return new ErrorInitializer(); 1073 1.1 mrg } 1074 1.1 mrg } 1075 1.1 mrg if (init.exp.isErrorExp()) 1076 1.1 mrg { 1077 1.1 mrg return new ErrorInitializer(); 1078 1.1 mrg } 1079 1.1 mrg if (!init.exp.type) 1080 1.1 mrg { 1081 1.1 mrg return new ErrorInitializer(); 1082 1.1 mrg } 1083 1.1 mrg return init; 1084 1.1 mrg } 1085 1.1 mrg 1086 1.1 mrg Initializer visitC(CInitializer i) 1087 1.1 mrg { 1088 1.1 mrg //printf("CInitializer.inferType()\n"); 1089 1.1 mrg error(i.loc, "TODO C inferType initializers not supported yet"); 1090 1.1 mrg return new ErrorInitializer(); 1091 1.1 mrg } 1092 1.1 mrg 1093 1.1 mrg final switch (init.kind) 1094 1.1 mrg { 1095 1.1 mrg case InitKind.void_: return visitVoid (init.isVoidInitializer()); 1096 1.1 mrg case InitKind.error: return visitError (init.isErrorInitializer()); 1097 1.1 mrg case InitKind.struct_: return visitStruct(init.isStructInitializer()); 1098 1.1 mrg case InitKind.array: return visitArray (init.isArrayInitializer()); 1099 1.1 mrg case InitKind.exp: return visitExp (init.isExpInitializer()); 1100 1.1 mrg case InitKind.C_: return visitC (init.isCInitializer()); 1101 1.1 mrg } 1102 1.1 mrg } 1103 1.1 mrg 1104 1.1 mrg /*********************** 1105 1.1 mrg * Translate init to an `Expression`. 1106 1.1 mrg * Params: 1107 1.1 mrg * init = `Initializer` AST node 1108 1.1 mrg * itype = if not `null`, type to coerce expression to 1109 1.1 mrg * isCfile = default initializers are different with C 1110 1.1 mrg * Returns: 1111 1.1 mrg * `Expression` created, `null` if cannot, `ErrorExp` for other errors 1112 1.1 mrg */ 1113 1.1 mrg extern (C++) Expression initializerToExpression(Initializer init, Type itype = null, const bool isCfile = false) 1114 1.1 mrg { 1115 1.1 mrg //printf("initializerToExpression() isCfile: %d\n", isCfile); 1116 1.1 mrg 1117 1.1 mrg Expression visitVoid(VoidInitializer) 1118 1.1 mrg { 1119 1.1 mrg return null; 1120 1.1 mrg } 1121 1.1 mrg 1122 1.1 mrg Expression visitError(ErrorInitializer) 1123 1.1 mrg { 1124 1.1 mrg return ErrorExp.get(); 1125 1.1 mrg } 1126 1.1 mrg 1127 1.1 mrg /*************************************** 1128 1.1 mrg * This works by transforming a struct initializer into 1129 1.1 mrg * a struct literal. In the future, the two should be the 1130 1.1 mrg * same thing. 1131 1.1 mrg */ 1132 1.1 mrg Expression visitStruct(StructInitializer) 1133 1.1 mrg { 1134 1.1 mrg // cannot convert to an expression without target 'ad' 1135 1.1 mrg return null; 1136 1.1 mrg } 1137 1.1 mrg 1138 1.1 mrg /******************************** 1139 1.1 mrg * If possible, convert array initializer to array literal. 1140 1.1 mrg * Otherwise return NULL. 1141 1.1 mrg */ 1142 1.1 mrg Expression visitArray(ArrayInitializer init) 1143 1.1 mrg { 1144 1.1 mrg //printf("ArrayInitializer::toExpression(), dim = %d\n", dim); 1145 1.1 mrg //static int i; if (++i == 2) assert(0); 1146 1.1 mrg uint edim; // the length of the resulting array literal 1147 1.1 mrg const(uint) amax = 0x80000000; 1148 1.1 mrg Type t = null; // type of the array literal being initialized 1149 1.1 mrg if (init.type) 1150 1.1 mrg { 1151 1.1 mrg if (init.type == Type.terror) 1152 1.1 mrg { 1153 1.1 mrg return ErrorExp.get(); 1154 1.1 mrg } 1155 1.1 mrg t = init.type.toBasetype(); 1156 1.1 mrg switch (t.ty) 1157 1.1 mrg { 1158 1.1 mrg case Tvector: 1159 1.1 mrg t = t.isTypeVector().basetype; 1160 1.1 mrg goto case Tsarray; 1161 1.1 mrg 1162 1.1 mrg case Tsarray: 1163 1.1 mrg uinteger_t adim = t.isTypeSArray().dim.toInteger(); 1164 1.1 mrg if (adim >= amax) 1165 1.1 mrg return null; 1166 1.1 mrg edim = cast(uint)adim; 1167 1.1 mrg break; 1168 1.1 mrg 1169 1.1 mrg case Tpointer: 1170 1.1 mrg case Tarray: 1171 1.1 mrg edim = init.dim; 1172 1.1 mrg break; 1173 1.1 mrg 1174 1.1 mrg default: 1175 1.1 mrg assert(0); 1176 1.1 mrg } 1177 1.1 mrg } 1178 1.1 mrg else 1179 1.1 mrg { 1180 1.1 mrg /* Calculate the length of the array literal 1181 1.1 mrg */ 1182 1.1 mrg edim = cast(uint)init.value.dim; 1183 1.1 mrg size_t j = 0; 1184 1.1 mrg foreach (i; 0 .. init.value.dim) 1185 1.1 mrg { 1186 1.1 mrg if (auto e = init.index[i]) 1187 1.1 mrg { 1188 1.1 mrg if (e.op == EXP.int64) 1189 1.1 mrg { 1190 1.1 mrg const uinteger_t idxval = e.toInteger(); 1191 1.1 mrg if (idxval >= amax) 1192 1.1 mrg return null; 1193 1.1 mrg j = cast(size_t)idxval; 1194 1.1 mrg } 1195 1.1 mrg else 1196 1.1 mrg return null; 1197 1.1 mrg } 1198 1.1 mrg ++j; 1199 1.1 mrg if (j > edim) 1200 1.1 mrg edim = cast(uint)j; 1201 1.1 mrg } 1202 1.1 mrg } 1203 1.1 mrg 1204 1.1 mrg auto elements = new Expressions(edim); 1205 1.1 mrg elements.zero(); 1206 1.1 mrg size_t j = 0; 1207 1.1 mrg foreach (i; 0 .. init.value.dim) 1208 1.1 mrg { 1209 1.1 mrg if (auto e = init.index[i]) 1210 1.1 mrg j = cast(size_t)e.toInteger(); 1211 1.1 mrg assert(j < edim); 1212 1.1 mrg if (Initializer iz = init.value[i]) 1213 1.1 mrg { 1214 1.1 mrg if (Expression ex = iz.initializerToExpression(null, isCfile)) 1215 1.1 mrg { 1216 1.1 mrg (*elements)[j] = ex; 1217 1.1 mrg ++j; 1218 1.1 mrg } 1219 1.1 mrg else 1220 1.1 mrg return null; 1221 1.1 mrg } 1222 1.1 mrg else 1223 1.1 mrg return null; 1224 1.1 mrg } 1225 1.1 mrg 1226 1.1 mrg /* Fill in any missing elements with the default initializer 1227 1.1 mrg */ 1228 1.1 mrg Expression defaultInit = null; // lazily create it 1229 1.1 mrg foreach (ref element; (*elements)[0 .. edim]) 1230 1.1 mrg { 1231 1.1 mrg if (!element) 1232 1.1 mrg { 1233 1.1 mrg if (!init.type) // don't know what type to use 1234 1.1 mrg return null; 1235 1.1 mrg if (!defaultInit) 1236 1.1 mrg defaultInit = (cast(TypeNext)t).next.defaultInit(Loc.initial, isCfile); 1237 1.1 mrg element = defaultInit; 1238 1.1 mrg } 1239 1.1 mrg } 1240 1.1 mrg 1241 1.1 mrg /* Expand any static array initializers that are a single expression 1242 1.1 mrg * into an array of them 1243 1.1 mrg * e => [e, e, ..., e, e] 1244 1.1 mrg */ 1245 1.1 mrg if (t) 1246 1.1 mrg { 1247 1.1 mrg Type tn = t.nextOf().toBasetype(); 1248 1.1 mrg if (tn.ty == Tsarray) 1249 1.1 mrg { 1250 1.1 mrg const dim = cast(size_t)(cast(TypeSArray)tn).dim.toInteger(); 1251 1.1 mrg Type te = tn.nextOf().toBasetype(); 1252 1.1 mrg foreach (ref e; *elements) 1253 1.1 mrg { 1254 1.1 mrg if (te.equals(e.type)) 1255 1.1 mrg { 1256 1.1 mrg auto elements2 = new Expressions(dim); 1257 1.1 mrg foreach (ref e2; *elements2) 1258 1.1 mrg e2 = e; 1259 1.1 mrg e = new ArrayLiteralExp(e.loc, tn, elements2); 1260 1.1 mrg } 1261 1.1 mrg } 1262 1.1 mrg } 1263 1.1 mrg } 1264 1.1 mrg 1265 1.1 mrg /* If any elements are errors, then the whole thing is an error 1266 1.1 mrg */ 1267 1.1 mrg foreach (e; (*elements)[0 .. edim]) 1268 1.1 mrg { 1269 1.1 mrg if (e.op == EXP.error) 1270 1.1 mrg { 1271 1.1 mrg return e; 1272 1.1 mrg } 1273 1.1 mrg } 1274 1.1 mrg 1275 1.1 mrg Expression e = new ArrayLiteralExp(init.loc, init.type, elements); 1276 1.1 mrg return e; 1277 1.1 mrg } 1278 1.1 mrg 1279 1.1 mrg Expression visitExp(ExpInitializer i) 1280 1.1 mrg { 1281 1.1 mrg if (itype) 1282 1.1 mrg { 1283 1.1 mrg //printf("ExpInitializer::toExpression(t = %s) exp = %s\n", itype.toChars(), i.exp.toChars()); 1284 1.1 mrg Type tb = itype.toBasetype(); 1285 1.1 mrg Expression e = (i.exp.op == EXP.construct || i.exp.op == EXP.blit) ? (cast(AssignExp)i.exp).e2 : i.exp; 1286 1.1 mrg if (tb.ty == Tsarray && e.implicitConvTo(tb.nextOf())) 1287 1.1 mrg { 1288 1.1 mrg TypeSArray tsa = cast(TypeSArray)tb; 1289 1.1 mrg size_t d = cast(size_t)tsa.dim.toInteger(); 1290 1.1 mrg auto elements = new Expressions(d); 1291 1.1 mrg for (size_t j = 0; j < d; j++) 1292 1.1 mrg (*elements)[j] = e; 1293 1.1 mrg auto ae = new ArrayLiteralExp(e.loc, itype, elements); 1294 1.1 mrg return ae; 1295 1.1 mrg } 1296 1.1 mrg } 1297 1.1 mrg return i.exp; 1298 1.1 mrg } 1299 1.1 mrg 1300 1.1 mrg Expression visitC(CInitializer i) 1301 1.1 mrg { 1302 1.1 mrg //printf("CInitializer.initializerToExpression(null, true)\n"); 1303 1.1 mrg return null; 1304 1.1 mrg } 1305 1.1 mrg 1306 1.1 mrg final switch (init.kind) 1307 1.1 mrg { 1308 1.1 mrg case InitKind.void_: return visitVoid (init.isVoidInitializer()); 1309 1.1 mrg case InitKind.error: return visitError (init.isErrorInitializer()); 1310 1.1 mrg case InitKind.struct_: return visitStruct(init.isStructInitializer()); 1311 1.1 mrg case InitKind.array: return visitArray (init.isArrayInitializer()); 1312 1.1 mrg case InitKind.exp: return visitExp (init.isExpInitializer()); 1313 1.1 mrg case InitKind.C_: return visitC (init.isCInitializer()); 1314 1.1 mrg } 1315 1.1 mrg } 1316 1.1 mrg 1317 1.1 mrg 1318 1.1 mrg /************************************** 1319 1.1 mrg * Determine if expression has non-constant pointers, or more precisely, 1320 1.1 mrg * a pointer that CTFE cannot handle. 1321 1.1 mrg * Params: 1322 1.1 mrg * e = expression to check 1323 1.1 mrg * Returns: 1324 1.1 mrg * true if it has non-constant pointers 1325 1.1 mrg */ 1326 1.1 mrg private bool hasNonConstPointers(Expression e) 1327 1.1 mrg { 1328 1.1 mrg static bool checkArray(Expressions* elems) 1329 1.1 mrg { 1330 1.1 mrg foreach (e; *elems) 1331 1.1 mrg { 1332 1.1 mrg if (e && hasNonConstPointers(e)) 1333 1.1 mrg return true; 1334 1.1 mrg } 1335 1.1 mrg return false; 1336 1.1 mrg } 1337 1.1 mrg 1338 1.1 mrg if (e.type.ty == Terror) 1339 1.1 mrg return false; 1340 1.1 mrg if (e.op == EXP.null_) 1341 1.1 mrg return false; 1342 1.1 mrg if (auto se = e.isStructLiteralExp()) 1343 1.1 mrg { 1344 1.1 mrg return checkArray(se.elements); 1345 1.1 mrg } 1346 1.1 mrg if (auto ae = e.isArrayLiteralExp()) 1347 1.1 mrg { 1348 1.1 mrg if (!ae.type.nextOf().hasPointers()) 1349 1.1 mrg return false; 1350 1.1 mrg return checkArray(ae.elements); 1351 1.1 mrg } 1352 1.1 mrg if (auto ae = e.isAssocArrayLiteralExp()) 1353 1.1 mrg { 1354 1.1 mrg if (ae.type.nextOf().hasPointers() && checkArray(ae.values)) 1355 1.1 mrg return true; 1356 1.1 mrg if (ae.type.isTypeAArray().index.hasPointers()) 1357 1.1 mrg return checkArray(ae.keys); 1358 1.1 mrg return false; 1359 1.1 mrg } 1360 1.1 mrg if (auto ae = e.isAddrExp()) 1361 1.1 mrg { 1362 1.1 mrg if (ae.type.nextOf().isImmutable() || ae.type.nextOf().isConst()) 1363 1.1 mrg { 1364 1.1 mrg return false; 1365 1.1 mrg } 1366 1.1 mrg if (auto se = ae.e1.isStructLiteralExp()) 1367 1.1 mrg { 1368 1.1 mrg if (!(se.stageflags & stageSearchPointers)) 1369 1.1 mrg { 1370 1.1 mrg const old = se.stageflags; 1371 1.1 mrg se.stageflags |= stageSearchPointers; 1372 1.1 mrg bool ret = checkArray(se.elements); 1373 1.1 mrg se.stageflags = old; 1374 1.1 mrg return ret; 1375 1.1 mrg } 1376 1.1 mrg else 1377 1.1 mrg { 1378 1.1 mrg return false; 1379 1.1 mrg } 1380 1.1 mrg } 1381 1.1 mrg return true; 1382 1.1 mrg } 1383 1.1 mrg if (e.type.ty == Tpointer && !e.type.isPtrToFunction()) 1384 1.1 mrg { 1385 1.1 mrg if (e.op == EXP.symbolOffset) // address of a global is OK 1386 1.1 mrg return false; 1387 1.1 mrg if (e.op == EXP.int64) // cast(void *)int is OK 1388 1.1 mrg return false; 1389 1.1 mrg if (e.op == EXP.string_) // "abc".ptr is OK 1390 1.1 mrg return false; 1391 1.1 mrg return true; 1392 1.1 mrg } 1393 1.1 mrg return false; 1394 1.1 mrg } 1395