1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 */
9
10 #include "root/dsystem.h"
11 #include "root/rmem.h"
12 #include "root/root.h"
13
14 #include "mars.h"
15 #include "mangle.h"
16 #include "mtype.h"
17 #include "init.h"
18 #include "expression.h"
19 #include "template.h"
20 #include "utf.h"
21 #include "enum.h"
22 #include "scope.h"
23 #include "statement.h"
24 #include "declaration.h"
25 #include "aggregate.h"
26 #include "import.h"
27 #include "id.h"
28 #include "dsymbol.h"
29 #include "module.h"
30 #include "attrib.h"
31 #include "hdrgen.h"
32 #include "parse.h"
33 #include "nspace.h"
34 #include "ctfe.h"
35 #include "target.h"
36
37 bool typeMerge(Scope *sc, TOK op, Type **pt, Expression **pe1, Expression **pe2);
38 bool isArrayOpValid(Expression *e);
39 Expression *expandVar(int result, VarDeclaration *v);
40 TypeTuple *toArgTypes(Type *t);
41 bool checkAssignEscape(Scope *sc, Expression *e, bool gag);
42 bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag);
43 bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember);
44 bool checkNestedRef(Dsymbol *s, Dsymbol *p);
45 bool checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad, size_t istart = 0);
46 bool symbolIsVisible(Module *mod, Dsymbol *s);
47 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e);
48 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
49 Type *getTypeInfoType(Loc loc, Type *t, Scope *sc);
50 bool MODimplicitConv(MOD modfrom, MOD modto);
51 MATCH MODmethodConv(MOD modfrom, MOD modto);
52 void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod);
53
54 void unSpeculative(Scope *sc, RootObject *o);
55 bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt);
56 bool checkDefCtor(Loc loc, Type *t);
57 bool isDotOpDispatch(Expression *e);
58 bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Type *tthis, Expressions *arguments, FuncDeclaration *fd, Type **prettype, Expression **peprefix);
59 Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad, Expression *e1, Declaration *var, int flag = 0);
60 bool isNeedThisScope(Scope *sc, Declaration *d);
61 Expression *resolveUFCS(Scope *sc, CallExp *ce);
62 bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg);
63 bool isSafeCast(Expression *e, Type *tfrom, Type *tto);
64 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
65 Expression *callCpCtor(Scope *sc, Expression *e);
66
67 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
68 Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NULL);
69 Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL);
70 Expression *trySemantic(Expression *e, Scope *sc);
71 Expression *unaSemantic(UnaExp *e, Scope *sc);
72 Expression *binSemantic(BinExp *e, Scope *sc);
73 Expression *binSemanticProp(BinExp *e, Scope *sc);
74 Expression *semantic(Expression *e, Scope *sc);
75 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
76 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
77 StringExp *semanticString(Scope *sc, Expression *exp, const char *s);
78
79 /****************************************
80 * Preprocess arguments to function.
81 * Output:
82 * exps[] tuples expanded, properties resolved, rewritten in place
83 * Returns:
84 * true a semantic error occurred
85 */
86
preFunctionParameters(Scope * sc,Expressions * exps)87 static bool preFunctionParameters(Scope *sc, Expressions *exps)
88 {
89 bool err = false;
90 if (exps)
91 {
92 expandTuples(exps);
93
94 for (size_t i = 0; i < exps->dim; i++)
95 {
96 Expression *arg = (*exps)[i];
97
98 arg = resolveProperties(sc, arg);
99 if (arg->op == TOKtype)
100 {
101 arg->error("cannot pass type %s as a function argument", arg->toChars());
102 arg = new ErrorExp();
103 err = true;
104 }
105 else if (arg->type->toBasetype()->ty == Tfunction)
106 {
107 arg->error("cannot pass type %s as a function argument", arg->toChars());
108 arg = new ErrorExp();
109 err = true;
110 }
111 else if (checkNonAssignmentArrayOp(arg))
112 {
113 arg = new ErrorExp();
114 err = true;
115 }
116 (*exps)[i] = arg;
117 }
118 }
119 return err;
120 }
121
122 class ExpressionSemanticVisitor : public Visitor
123 {
124 public:
125 Expression *result;
126 Scope *sc;
127
ExpressionSemanticVisitor(Scope * sc)128 ExpressionSemanticVisitor(Scope *sc)
129 {
130 this->result = NULL;
131 this->sc = sc;
132 }
133
134 private:
setError()135 void setError()
136 {
137 result = new ErrorExp();
138 }
139
140 /*********************
141 * Mark the operand as will never be dereferenced,
142 * which is useful info for @safe checks.
143 * Do before semantic() on operands rewrites them.
144 */
setNoderefOperand(UnaExp * e)145 static void setNoderefOperand(UnaExp *e)
146 {
147 if (e->e1->op == TOKdotid)
148 ((DotIdExp *)e->e1)->noderef = true;
149 }
150
151 /*********************
152 * Mark the operands as will never be dereferenced,
153 * which is useful info for @safe checks.
154 * Do before semantic() on operands rewrites them.
155 */
setNoderefOperands(BinExp * e)156 static void setNoderefOperands(BinExp *e)
157 {
158 if (e->e1->op == TOKdotid)
159 ((DotIdExp *)e->e1)->noderef = true;
160 if (e->e2->op == TOKdotid)
161 ((DotIdExp *)e->e2)->noderef = true;
162 }
163
resolveOverloadSet(Loc loc,Scope * sc,OverloadSet * os,Objects * tiargs,Type * tthis,Expressions * arguments)164 static FuncDeclaration *resolveOverloadSet(Loc loc, Scope *sc,
165 OverloadSet *os, Objects* tiargs, Type *tthis, Expressions *arguments)
166 {
167 FuncDeclaration *f = NULL;
168 for (size_t i = 0; i < os->a.dim; i++)
169 {
170 Dsymbol *s = os->a[i];
171 if (tiargs && s->isFuncDeclaration())
172 continue;
173 if (FuncDeclaration *f2 = resolveFuncCall(loc, sc, s, tiargs, tthis, arguments, 1))
174 {
175 if (f2->errors)
176 return NULL;
177 if (f)
178 {
179 /* Error if match in more than one overload set,
180 * even if one is a 'better' match than the other.
181 */
182 ScopeDsymbol::multiplyDefined(loc, f, f2);
183 }
184 else
185 f = f2;
186 }
187 }
188 if (!f)
189 ::error(loc, "no overload matches for %s", os->toChars());
190 else if (f->errors)
191 f = NULL;
192 return f;
193 }
194
195 /****************************************************
196 * Determine if `exp`, which takes the address of `v`, can do so safely.
197 * Params:
198 * sc = context
199 * exp = expression that takes the address of `v`
200 * v = the variable getting its address taken
201 * Returns:
202 * `true` if ok, `false` for error
203 */
checkAddressVar(Scope * sc,UnaExp * e,VarDeclaration * v)204 static bool checkAddressVar(Scope *sc, UnaExp *e, VarDeclaration *v)
205 {
206 if (v)
207 {
208 if (!v->canTakeAddressOf())
209 {
210 e->error("cannot take address of %s", e->e1->toChars());
211 return false;
212 }
213 if (sc->func && !sc->intypeof && !v->isDataseg())
214 {
215 const char *p = v->isParameter() ? "parameter" : "local";
216 if (global.params.vsafe)
217 {
218 // Taking the address of v means it cannot be set to 'scope' later
219 v->storage_class &= ~STCmaybescope;
220 v->doNotInferScope = true;
221 if (v->storage_class & STCscope && sc->func->setUnsafe())
222 {
223 e->error("cannot take address of scope %s %s in @safe function %s", p, v->toChars(), sc->func->toChars());
224 return false;
225 }
226 }
227 else if (sc->func->setUnsafe())
228 {
229 e->error("cannot take address of %s %s in @safe function %s", p, v->toChars(), sc->func->toChars());
230 return false;
231 }
232 }
233 }
234 return true;
235 }
236
checkVectorElem(Expression * e,Expression * elem)237 static bool checkVectorElem(Expression *e, Expression *elem)
238 {
239 if (elem->isConst() == 1)
240 return false;
241
242 e->error("constant expression expected, not %s", elem->toChars());
243 return true;
244 }
245
246 public:
visit(Expression * e)247 void visit(Expression *e)
248 {
249 if (e->type)
250 e->type = e->type->semantic(e->loc, sc);
251 else
252 e->type = Type::tvoid;
253 result = e;
254 }
255
visit(IntegerExp * e)256 void visit(IntegerExp *e)
257 {
258 assert(e->type);
259 if (e->type->ty == Terror)
260 return setError();
261 assert(e->type->deco);
262 e->normalize();
263 result = e;
264 }
265
visit(RealExp * e)266 void visit(RealExp *e)
267 {
268 if (!e->type)
269 e->type = Type::tfloat64;
270 else
271 e->type = e->type->semantic(e->loc, sc);
272 result = e;
273 }
274
visit(ComplexExp * e)275 void visit(ComplexExp *e)
276 {
277 if (!e->type)
278 e->type = Type::tcomplex80;
279 else
280 e->type = e->type->semantic(e->loc, sc);
281 result = e;
282 }
283
visit(IdentifierExp * exp)284 void visit(IdentifierExp *exp)
285 {
286 if (exp->type) // This is used as the dummy expression
287 {
288 result = exp;
289 return;
290 }
291
292 Dsymbol *scopesym;
293 Dsymbol *s = sc->search(exp->loc, exp->ident, &scopesym);
294 if (s)
295 {
296 if (s->errors)
297 return setError();
298
299 Expression *e;
300
301 /* See if the symbol was a member of an enclosing 'with'
302 */
303 WithScopeSymbol *withsym = scopesym->isWithScopeSymbol();
304 if (withsym && withsym->withstate->wthis)
305 {
306 /* Disallow shadowing
307 */
308 // First find the scope of the with
309 Scope *scwith = sc;
310 while (scwith->scopesym != scopesym)
311 {
312 scwith = scwith->enclosing;
313 assert(scwith);
314 }
315 // Look at enclosing scopes for symbols with the same name,
316 // in the same function
317 for (Scope *scx = scwith; scx && scx->func == scwith->func; scx = scx->enclosing)
318 {
319 Dsymbol *s2;
320 if (scx->scopesym && scx->scopesym->symtab &&
321 (s2 = scx->scopesym->symtab->lookup(s->ident)) != NULL &&
322 s != s2)
323 {
324 exp->error("with symbol %s is shadowing local symbol %s", s->toPrettyChars(), s2->toPrettyChars());
325 return setError();
326 }
327 }
328 s = s->toAlias();
329
330 // Same as wthis.ident
331 // TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.
332 // The redudancy should be removed.
333 e = new VarExp(exp->loc, withsym->withstate->wthis);
334 e = new DotIdExp(exp->loc, e, exp->ident);
335 e = semantic(e, sc);
336 }
337 else
338 {
339 if (withsym)
340 {
341 Declaration *d = s->isDeclaration();
342 if (d)
343 checkAccess(exp->loc, sc, NULL, d);
344 }
345
346 /* If f is really a function template,
347 * then replace f with the function template declaration.
348 */
349 FuncDeclaration *f = s->isFuncDeclaration();
350 if (f)
351 {
352 TemplateDeclaration *td = getFuncTemplateDecl(f);
353 if (td)
354 {
355 if (td->overroot) // if not start of overloaded list of TemplateDeclaration's
356 td = td->overroot; // then get the start
357 e = new TemplateExp(exp->loc, td, f);
358 e = semantic(e, sc);
359 result = e;
360 return;
361 }
362 }
363 // Haven't done overload resolution yet, so pass 1
364 e = resolve(exp->loc, sc, s, true);
365 }
366 result = e;
367 return;
368 }
369
370 if (hasThis(sc))
371 {
372 AggregateDeclaration *ad = sc->getStructClassScope();
373 if (ad && ad->aliasthis)
374 {
375 Expression *e;
376 e = new IdentifierExp(exp->loc, Id::This);
377 e = new DotIdExp(exp->loc, e, ad->aliasthis->ident);
378 e = new DotIdExp(exp->loc, e, exp->ident);
379 e = trySemantic(e, sc);
380 if (e)
381 {
382 result = e;
383 return;
384 }
385 }
386 }
387
388 if (exp->ident == Id::ctfe)
389 {
390 if (sc->flags & SCOPEctfe)
391 {
392 exp->error("variable __ctfe cannot be read at compile time");
393 return setError();
394 }
395
396 // Create the magic __ctfe bool variable
397 VarDeclaration *vd = new VarDeclaration(exp->loc, Type::tbool, Id::ctfe, NULL);
398 vd->storage_class |= STCtemp;
399 Expression *e = new VarExp(exp->loc, vd);
400 e = semantic(e, sc);
401 result = e;
402 return;
403 }
404
405 // If we've reached this point and are inside a with() scope then we may
406 // try one last attempt by checking whether the 'wthis' object supports
407 // dynamic dispatching via opDispatch.
408 // This is done by rewriting this expression as wthis.ident.
409 for (Scope *sc2 = sc; sc2; sc2 = sc2->enclosing)
410 {
411 if (!sc2->scopesym)
412 continue;
413
414 if (WithScopeSymbol *ss = sc2->scopesym->isWithScopeSymbol())
415 {
416 if (ss->withstate->wthis)
417 {
418 Expression *e;
419 e = new VarExp(exp->loc, ss->withstate->wthis);
420 e = new DotIdExp(exp->loc, e, exp->ident);
421 e = trySemantic(e, sc);
422 if (e)
423 {
424 result = e;
425 return;
426 }
427 }
428 break;
429 }
430 }
431
432 /* Look for what user might have meant
433 */
434 if (const char *n = importHint(exp->ident->toChars()))
435 exp->error("`%s` is not defined, perhaps `import %s;` is needed?", exp->ident->toChars(), n);
436 else if (Dsymbol *s2 = sc->search_correct(exp->ident))
437 exp->error("undefined identifier `%s`, did you mean %s `%s`?", exp->ident->toChars(), s2->kind(), s2->toChars());
438 else if (const char *p = Scope::search_correct_C(exp->ident))
439 exp->error("undefined identifier `%s`, did you mean `%s`?", exp->ident->toChars(), p);
440 else
441 exp->error("undefined identifier `%s`", exp->ident->toChars());
442 return setError();
443 }
444
visit(DsymbolExp * e)445 void visit(DsymbolExp *e)
446 {
447 result = resolve(e->loc, sc, e->s, e->hasOverloads);
448 }
449
visit(ThisExp * e)450 void visit(ThisExp *e)
451 {
452 if (e->type)
453 {
454 result = e;
455 return;
456 }
457
458 FuncDeclaration *fd = hasThis(sc); // fd is the uplevel function with the 'this' variable
459
460 /* Special case for typeof(this) and typeof(super) since both
461 * should work even if they are not inside a non-static member function
462 */
463 if (!fd && sc->intypeof == 1)
464 {
465 // Find enclosing struct or class
466 for (Dsymbol *s = sc->getStructClassScope(); 1; s = s->parent)
467 {
468 if (!s)
469 {
470 e->error("%s is not in a class or struct scope", e->toChars());
471 goto Lerr;
472 }
473 ClassDeclaration *cd = s->isClassDeclaration();
474 if (cd)
475 {
476 e->type = cd->type;
477 result = e;
478 return;
479 }
480 StructDeclaration *sd = s->isStructDeclaration();
481 if (sd)
482 {
483 e->type = sd->type;
484 result = e;
485 return;
486 }
487 }
488 }
489 if (!fd)
490 goto Lerr;
491
492 assert(fd->vthis);
493 e->var = fd->vthis;
494 assert(e->var->parent);
495 e->type = e->var->type;
496 if (e->var->checkNestedReference(sc, e->loc))
497 return setError();
498 if (!sc->intypeof)
499 sc->callSuper |= CSXthis;
500 result = e;
501 return;
502
503 Lerr:
504 e->error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars());
505 return setError();
506 }
507
visit(SuperExp * e)508 void visit(SuperExp *e)
509 {
510 if (e->type)
511 {
512 result = e;
513 return;
514 }
515
516 FuncDeclaration *fd = hasThis(sc);
517 ClassDeclaration *cd;
518 Dsymbol *s;
519
520 /* Special case for typeof(this) and typeof(super) since both
521 * should work even if they are not inside a non-static member function
522 */
523 if (!fd && sc->intypeof == 1)
524 {
525 // Find enclosing class
526 for (s = sc->getStructClassScope(); 1; s = s->parent)
527 {
528 if (!s)
529 {
530 e->error("%s is not in a class scope", e->toChars());
531 goto Lerr;
532 }
533 cd = s->isClassDeclaration();
534 if (cd)
535 {
536 cd = cd->baseClass;
537 if (!cd)
538 {
539 e->error("class %s has no 'super'", s->toChars());
540 goto Lerr;
541 }
542 e->type = cd->type;
543 result = e;
544 return;
545 }
546 }
547 }
548 if (!fd)
549 goto Lerr;
550
551 e->var = fd->vthis;
552 assert(e->var && e->var->parent);
553
554 s = fd->toParent();
555 while (s && s->isTemplateInstance())
556 s = s->toParent();
557 if (s->isTemplateDeclaration()) // allow inside template constraint
558 s = s->toParent();
559 assert(s);
560 cd = s->isClassDeclaration();
561 //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars());
562 if (!cd)
563 goto Lerr;
564 if (!cd->baseClass)
565 {
566 e->error("no base class for %s", cd->toChars());
567 e->type = e->var->type;
568 }
569 else
570 {
571 e->type = cd->baseClass->type;
572 e->type = e->type->castMod(e->var->type->mod);
573 }
574
575 if (e->var->checkNestedReference(sc, e->loc))
576 return setError();
577
578 if (!sc->intypeof)
579 sc->callSuper |= CSXsuper;
580 result = e;
581 return;
582
583 Lerr:
584 e->error("'super' is only allowed in non-static class member functions");
585 return setError();
586 }
587
visit(NullExp * e)588 void visit(NullExp *e)
589 {
590 // NULL is the same as (void *)0
591 if (e->type)
592 {
593 result = e;
594 return;
595 }
596 e->type = Type::tnull;
597 result = e;
598 }
599
visit(StringExp * e)600 void visit(StringExp *e)
601 {
602 if (e->type)
603 {
604 result = e;
605 return;
606 }
607
608 OutBuffer buffer;
609 size_t newlen = 0;
610 const char *p;
611 size_t u;
612 unsigned c;
613
614 switch (e->postfix)
615 {
616 case 'd':
617 for (u = 0; u < e->len;)
618 {
619 p = utf_decodeChar((utf8_t *)e->string, e->len, &u, &c);
620 if (p)
621 {
622 e->error("%s", p);
623 return setError();
624 }
625 else
626 {
627 buffer.write4(c);
628 newlen++;
629 }
630 }
631 buffer.write4(0);
632 e->string = buffer.extractData();
633 e->len = newlen;
634 e->sz = 4;
635 e->type = new TypeDArray(Type::tdchar->immutableOf());
636 e->committed = 1;
637 break;
638
639 case 'w':
640 for (u = 0; u < e->len;)
641 {
642 p = utf_decodeChar((utf8_t *)e->string, e->len, &u, &c);
643 if (p)
644 {
645 e->error("%s", p);
646 return setError();
647 }
648 else
649 {
650 buffer.writeUTF16(c);
651 newlen++;
652 if (c >= 0x10000)
653 newlen++;
654 }
655 }
656 buffer.writeUTF16(0);
657 e->string = buffer.extractData();
658 e->len = newlen;
659 e->sz = 2;
660 e->type = new TypeDArray(Type::twchar->immutableOf());
661 e->committed = 1;
662 break;
663
664 case 'c':
665 e->committed = 1;
666 /* fall through */
667
668 default:
669 e->type = new TypeDArray(Type::tchar->immutableOf());
670 break;
671 }
672 e->type = e->type->semantic(e->loc, sc);
673 //e->type = e->type->immutableOf();
674 //printf("type = %s\n", e->type->toChars());
675
676 result = e;
677 }
678
visit(ArrayLiteralExp * e)679 void visit(ArrayLiteralExp *e)
680 {
681 if (e->type)
682 {
683 result = e;
684 return;
685 }
686
687 /* Perhaps an empty array literal [ ] should be rewritten as null?
688 */
689
690 if (e->basis)
691 e->basis = semantic(e->basis, sc);
692 if (arrayExpressionSemantic(e->elements, sc) || (e->basis && e->basis->op == TOKerror))
693 return setError();
694 expandTuples(e->elements);
695
696 Type *t0;
697 if (e->basis)
698 e->elements->push(e->basis);
699 bool err = arrayExpressionToCommonType(sc, e->elements, &t0);
700 if (e->basis)
701 e->elements->pop();
702 if (err)
703 return setError();
704
705 e->type = t0->arrayOf();
706 e->type = e->type->semantic(e->loc, sc);
707
708 /* Disallow array literals of type void being used.
709 */
710 if (e->elements->dim > 0 && t0->ty == Tvoid)
711 {
712 e->error("%s of type %s has no value", e->toChars(), e->type->toChars());
713 return setError();
714 }
715
716 if (global.params.useTypeInfo && Type::dtypeinfo)
717 semanticTypeInfo(sc, e->type);
718
719 result = e;
720 }
721
visit(AssocArrayLiteralExp * e)722 void visit(AssocArrayLiteralExp *e)
723 {
724 if (e->type)
725 {
726 result = e;
727 return;
728 }
729
730 // Run semantic() on each element
731 bool err_keys = arrayExpressionSemantic(e->keys, sc);
732 bool err_vals = arrayExpressionSemantic(e->values, sc);
733 if (err_keys || err_vals)
734 return setError();
735 expandTuples(e->keys);
736 expandTuples(e->values);
737 if (e->keys->dim != e->values->dim)
738 {
739 e->error("number of keys is %u, must match number of values %u", e->keys->dim, e->values->dim);
740 return setError();
741 }
742
743 Type *tkey = NULL;
744 Type *tvalue = NULL;
745 err_keys = arrayExpressionToCommonType(sc, e->keys, &tkey);
746 err_vals = arrayExpressionToCommonType(sc, e->values, &tvalue);
747 if (err_keys || err_vals)
748 return setError();
749
750 if (tkey == Type::terror || tvalue == Type::terror)
751 return setError();
752
753 e->type = new TypeAArray(tvalue, tkey);
754 e->type = e->type->semantic(e->loc, sc);
755
756 semanticTypeInfo(sc, e->type);
757
758 result = e;
759 }
760
visit(StructLiteralExp * e)761 void visit(StructLiteralExp *e)
762 {
763 if (e->type)
764 {
765 result = e;
766 return;
767 }
768
769 e->sd->size(e->loc);
770 if (e->sd->sizeok != SIZEOKdone)
771 return setError();
772
773 if (arrayExpressionSemantic(e->elements, sc)) // run semantic() on each element
774 return setError();
775 expandTuples(e->elements);
776
777 /* Fit elements[] to the corresponding type of field[].
778 */
779 if (!e->sd->fit(e->loc, sc, e->elements, e->stype))
780 return setError();
781
782 /* Fill out remainder of elements[] with default initializers for fields[]
783 */
784 if (!e->sd->fill(e->loc, e->elements, false))
785 {
786 /* An error in the initializer needs to be recorded as an error
787 * in the enclosing function or template, since the initializer
788 * will be part of the stuct declaration.
789 */
790 global.increaseErrorCount();
791 return setError();
792 }
793
794 if (checkFrameAccess(e->loc, sc, e->sd, e->elements->dim))
795 return setError();
796
797 e->type = e->stype ? e->stype : e->sd->type;
798 result = e;
799 }
800
visit(TypeExp * exp)801 void visit(TypeExp *exp)
802 {
803 if (exp->type->ty == Terror)
804 return setError();
805
806 //printf("TypeExp::semantic(%s)\n", exp->type->toChars());
807 Expression *e;
808 Type *t;
809 Dsymbol *s;
810
811 exp->type->resolve(exp->loc, sc, &e, &t, &s, true);
812 if (e)
813 {
814 //printf("e = %s %s\n", Token::toChars(e->op), e->toChars());
815 e = semantic(e, sc);
816 }
817 else if (t)
818 {
819 //printf("t = %d %s\n", t->ty, t->toChars());
820 exp->type = t->semantic(exp->loc, sc);
821 e = exp;
822 }
823 else if (s)
824 {
825 //printf("s = %s %s\n", s->kind(), s->toChars());
826 e = resolve(exp->loc, sc, s, true);
827 }
828 else
829 assert(0);
830
831 if (global.params.vcomplex)
832 exp->type->checkComplexTransition(exp->loc);
833
834 result = e;
835 }
836
visit(ScopeExp * exp)837 void visit(ScopeExp *exp)
838 {
839 if (exp->type)
840 {
841 result = exp;
842 return;
843 }
844
845 ScopeDsymbol *sds2 = exp->sds;
846 TemplateInstance *ti = sds2->isTemplateInstance();
847 while (ti)
848 {
849 WithScopeSymbol *withsym;
850 if (!ti->findTempDecl(sc, &withsym) ||
851 !ti->semanticTiargs(sc))
852 return setError();
853 if (withsym && withsym->withstate->wthis)
854 {
855 Expression *e = new VarExp(exp->loc, withsym->withstate->wthis);
856 e = new DotTemplateInstanceExp(exp->loc, e, ti);
857 result = semantic(e, sc);
858 return;
859 }
860 if (ti->needsTypeInference(sc))
861 {
862 if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration())
863 {
864 Dsymbol *p = td->toParent2();
865 FuncDeclaration *fdthis = hasThis(sc);
866 AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL;
867 if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad &&
868 (td->_scope->stc & STCstatic) == 0)
869 {
870 Expression *e = new DotTemplateInstanceExp(exp->loc, new ThisExp(exp->loc), ti->name, ti->tiargs);
871 result = semantic(e, sc);
872 return;
873 }
874 }
875 else if (OverloadSet *os = ti->tempdecl->isOverloadSet())
876 {
877 FuncDeclaration *fdthis = hasThis(sc);
878 AggregateDeclaration *ad = os->parent->isAggregateDeclaration();
879 if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad)
880 {
881 Expression *e = new DotTemplateInstanceExp(exp->loc, new ThisExp(exp->loc), ti->name, ti->tiargs);
882 result = semantic(e, sc);
883 return;
884 }
885 }
886 // ti is an instance which requires IFTI.
887 exp->sds = ti;
888 exp->type = Type::tvoid;
889 result = exp;
890 return;
891 }
892 ti->semantic(sc);
893 if (!ti->inst || ti->errors)
894 return setError();
895
896 Dsymbol *s = ti->toAlias();
897 if (s == ti)
898 {
899 exp->sds = ti;
900 exp->type = Type::tvoid;
901 result = exp;
902 return;
903 }
904 sds2 = s->isScopeDsymbol();
905 if (sds2)
906 {
907 ti = sds2->isTemplateInstance();
908 //printf("+ sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
909 continue;
910 }
911
912 if (VarDeclaration *v = s->isVarDeclaration())
913 {
914 if (!v->type)
915 {
916 exp->error("forward reference of %s %s", v->kind(), v->toChars());
917 return setError();
918 }
919 if ((v->storage_class & STCmanifest) && v->_init)
920 {
921 /* When an instance that will be converted to a constant exists,
922 * the instance representation "foo!tiargs" is treated like a
923 * variable name, and its recursive appearance check (note that
924 * it's equivalent with a recursive instantiation of foo) is done
925 * separately from the circular initialization check for the
926 * eponymous enum variable declaration.
927 *
928 * template foo(T) {
929 * enum bool foo = foo; // recursive definition check (v.inuse)
930 * }
931 * template bar(T) {
932 * enum bool bar = bar!T; // recursive instantiation check (ti.inuse)
933 * }
934 */
935 if (ti->inuse)
936 {
937 exp->error("recursive expansion of %s '%s'", ti->kind(), ti->toPrettyChars());
938 return setError();
939 }
940
941 Expression *e = v->expandInitializer(exp->loc);
942 ti->inuse++;
943 e = semantic(e, sc);
944 ti->inuse--;
945 result = e;
946 return;
947 }
948 }
949
950 //printf("s = %s, '%s'\n", s->kind(), s->toChars());
951 Expression *e = resolve(exp->loc, sc, s, true);
952 //printf("-1ScopeExp::semantic()\n");
953 result = e;
954 return;
955 }
956
957 //printf("sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
958 //printf("\tparent = '%s'\n", sds2->parent->toChars());
959 sds2->semantic(sc);
960
961 if (Type *t = sds2->getType()) // (Aggregate|Enum)Declaration
962 {
963 Expression *ex = new TypeExp(exp->loc, t);
964 result = semantic(ex, sc);
965 return;
966 }
967
968 if (TemplateDeclaration *td = sds2->isTemplateDeclaration())
969 {
970 result = semantic(new TemplateExp(exp->loc, td), sc);
971 return;
972 }
973
974 exp->sds = sds2;
975 exp->type = Type::tvoid;
976 //printf("-2ScopeExp::semantic() %s\n", exp->toChars());
977 result = exp;
978 }
979
visit(NewExp * exp)980 void visit(NewExp *exp)
981 {
982 if (exp->type) // if semantic() already run
983 {
984 result = exp;
985 return;
986 }
987
988 // Bugzilla 11581: With the syntax `new T[edim]` or `thisexp.new T[edim]`,
989 // T should be analyzed first and edim should go into arguments iff it's
990 // not a tuple.
991 Expression *edim = NULL;
992 if (!exp->arguments && exp->newtype->ty == Tsarray)
993 {
994 edim = ((TypeSArray *)exp->newtype)->dim;
995 exp->newtype = ((TypeNext *)exp->newtype)->next;
996 }
997
998 ClassDeclaration *cdthis = NULL;
999 if (exp->thisexp)
1000 {
1001 exp->thisexp = semantic(exp->thisexp, sc);
1002 if (exp->thisexp->op == TOKerror)
1003 return setError();
1004 cdthis = exp->thisexp->type->isClassHandle();
1005 if (!cdthis)
1006 {
1007 exp->error("'this' for nested class must be a class type, not %s", exp->thisexp->type->toChars());
1008 return setError();
1009 }
1010
1011 sc = sc->push(cdthis);
1012 exp->type = exp->newtype->semantic(exp->loc, sc);
1013 sc = sc->pop();
1014 }
1015 else
1016 {
1017 exp->type = exp->newtype->semantic(exp->loc, sc);
1018 }
1019 if (exp->type->ty == Terror)
1020 return setError();
1021
1022 if (edim)
1023 {
1024 if (exp->type->toBasetype()->ty == Ttuple)
1025 {
1026 // --> new T[edim]
1027 exp->type = new TypeSArray(exp->type, edim);
1028 exp->type = exp->type->semantic(exp->loc, sc);
1029 if (exp->type->ty == Terror)
1030 return setError();
1031 }
1032 else
1033 {
1034 // --> new T[](edim)
1035 exp->arguments = new Expressions();
1036 exp->arguments->push(edim);
1037 exp->type = exp->type->arrayOf();
1038 }
1039 }
1040
1041 exp->newtype = exp->type; // in case type gets cast to something else
1042 Type *tb = exp->type->toBasetype();
1043 //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco);
1044
1045 if (arrayExpressionSemantic(exp->newargs, sc) ||
1046 preFunctionParameters(sc, exp->newargs))
1047 {
1048 return setError();
1049 }
1050 if (arrayExpressionSemantic(exp->arguments, sc) ||
1051 preFunctionParameters(sc, exp->arguments))
1052 {
1053 return setError();
1054 }
1055
1056 if (exp->thisexp && tb->ty != Tclass)
1057 {
1058 exp->error("e.new is only for allocating nested classes, not %s", tb->toChars());
1059 return setError();
1060 }
1061
1062 size_t nargs = exp->arguments ? exp->arguments->dim : 0;
1063 Expression *newprefix = NULL;
1064
1065 if (tb->ty == Tclass)
1066 {
1067 ClassDeclaration *cd = ((TypeClass *)tb)->sym;
1068 cd->size(exp->loc);
1069 if (cd->sizeok != SIZEOKdone)
1070 return setError();
1071 if (!cd->ctor)
1072 cd->ctor = cd->searchCtor();
1073 if (cd->noDefaultCtor && !nargs && !cd->defaultCtor)
1074 {
1075 exp->error("default construction is disabled for type %s", cd->type->toChars());
1076 return setError();
1077 }
1078
1079 if (cd->isInterfaceDeclaration())
1080 {
1081 exp->error("cannot create instance of interface %s", cd->toChars());
1082 return setError();
1083 }
1084 if (cd->isAbstract())
1085 {
1086 exp->error("cannot create instance of abstract class %s", cd->toChars());
1087 for (size_t i = 0; i < cd->vtbl.dim; i++)
1088 {
1089 FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
1090 if (fd && fd->isAbstract())
1091 errorSupplemental(exp->loc, "function '%s' is not implemented", fd->toFullSignature());
1092 }
1093 return setError();
1094 }
1095 // checkDeprecated() is already done in newtype->semantic().
1096
1097 if (cd->isNested())
1098 {
1099 /* We need a 'this' pointer for the nested class.
1100 * Ensure we have the right one.
1101 */
1102 Dsymbol *s = cd->toParent2();
1103 //printf("cd isNested, parent = %s '%s'\n", s->kind(), s->toPrettyChars());
1104 if (ClassDeclaration *cdn = s->isClassDeclaration())
1105 {
1106 if (!cdthis)
1107 {
1108 // Supply an implicit 'this' and try again
1109 exp->thisexp = new ThisExp(exp->loc);
1110 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent)
1111 {
1112 if (!sp)
1113 {
1114 exp->error("outer class %s 'this' needed to 'new' nested class %s", cdn->toChars(), cd->toChars());
1115 return setError();
1116 }
1117 ClassDeclaration *cdp = sp->isClassDeclaration();
1118 if (!cdp)
1119 continue;
1120 if (cdp == cdn || cdn->isBaseOf(cdp, NULL))
1121 break;
1122 // Add a '.outer' and try again
1123 exp->thisexp = new DotIdExp(exp->loc, exp->thisexp, Id::outer);
1124 }
1125 exp->thisexp = semantic(exp->thisexp, sc);
1126 if (exp->thisexp->op == TOKerror)
1127 return setError();
1128 cdthis = exp->thisexp->type->isClassHandle();
1129 }
1130 if (cdthis != cdn && !cdn->isBaseOf(cdthis, NULL))
1131 {
1132 //printf("cdthis = %s\n", cdthis->toChars());
1133 exp->error("'this' for nested class must be of type %s, not %s",
1134 cdn->toChars(), exp->thisexp->type->toChars());
1135 return setError();
1136 }
1137 if (!MODimplicitConv(exp->thisexp->type->mod, exp->newtype->mod))
1138 {
1139 exp->error("nested type %s should have the same or weaker constancy as enclosing type %s",
1140 exp->newtype->toChars(), exp->thisexp->type->toChars());
1141 return setError();
1142 }
1143 }
1144 else if (exp->thisexp)
1145 {
1146 exp->error("e.new is only for allocating nested classes");
1147 return setError();
1148 }
1149 else if (FuncDeclaration *fdn = s->isFuncDeclaration())
1150 {
1151 // make sure the parent context fdn of cd is reachable from sc
1152 if (checkNestedRef(sc->parent, fdn))
1153 {
1154 exp->error("outer function context of %s is needed to 'new' nested class %s",
1155 fdn->toPrettyChars(), cd->toPrettyChars());
1156 return setError();
1157 }
1158 }
1159 else
1160 assert(0);
1161 }
1162 else if (exp->thisexp)
1163 {
1164 exp->error("e.new is only for allocating nested classes");
1165 return setError();
1166 }
1167
1168 if (cd->aggNew)
1169 {
1170 // Prepend the size argument to newargs[]
1171 Expression *e = new IntegerExp(exp->loc, cd->size(exp->loc), Type::tsize_t);
1172 if (!exp->newargs)
1173 exp->newargs = new Expressions();
1174 exp->newargs->shift(e);
1175
1176 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, cd->aggNew, NULL, tb, exp->newargs);
1177 if (!f || f->errors)
1178 return setError();
1179 exp->checkDeprecated(sc, f);
1180 exp->checkPurity(sc, f);
1181 exp->checkSafety(sc, f);
1182 exp->checkNogc(sc, f);
1183 checkAccess(cd, exp->loc, sc, f);
1184
1185 TypeFunction *tf = (TypeFunction *)f->type;
1186 Type *rettype;
1187 if (functionParameters(exp->loc, sc, tf, NULL, exp->newargs, f, &rettype, &newprefix))
1188 return setError();
1189
1190 exp->allocator = f->isNewDeclaration();
1191 assert(exp->allocator);
1192 }
1193 else
1194 {
1195 if (exp->newargs && exp->newargs->dim)
1196 {
1197 exp->error("no allocator for %s", cd->toChars());
1198 return setError();
1199 }
1200 }
1201
1202 if (cd->ctor)
1203 {
1204 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, cd->ctor, NULL, tb, exp->arguments, 0);
1205 if (!f || f->errors)
1206 return setError();
1207 exp->checkDeprecated(sc, f);
1208 exp->checkPurity(sc, f);
1209 exp->checkSafety(sc, f);
1210 exp->checkNogc(sc, f);
1211 checkAccess(cd, exp->loc, sc, f);
1212
1213 TypeFunction *tf = (TypeFunction *)f->type;
1214 if (!exp->arguments)
1215 exp->arguments = new Expressions();
1216 if (functionParameters(exp->loc, sc, tf, exp->type, exp->arguments, f, &exp->type, &exp->argprefix))
1217 return setError();
1218
1219 exp->member = f->isCtorDeclaration();
1220 assert(exp->member);
1221 }
1222 else
1223 {
1224 if (nargs)
1225 {
1226 exp->error("no constructor for %s", cd->toChars());
1227 return setError();
1228 }
1229 }
1230 }
1231 else if (tb->ty == Tstruct)
1232 {
1233 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
1234 sd->size(exp->loc);
1235 if (sd->sizeok != SIZEOKdone)
1236 return setError();
1237 if (!sd->ctor)
1238 sd->ctor = sd->searchCtor();
1239 if (sd->noDefaultCtor && !nargs)
1240 {
1241 exp->error("default construction is disabled for type %s", sd->type->toChars());
1242 return setError();
1243 }
1244 // checkDeprecated() is already done in newtype->semantic().
1245
1246 if (sd->aggNew)
1247 {
1248 // Prepend the uint size argument to newargs[]
1249 Expression *e = new IntegerExp(exp->loc, sd->size(exp->loc), Type::tsize_t);
1250 if (!exp->newargs)
1251 exp->newargs = new Expressions();
1252 exp->newargs->shift(e);
1253
1254 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, sd->aggNew, NULL, tb, exp->newargs);
1255 if (!f || f->errors)
1256 return setError();
1257 exp->checkDeprecated(sc, f);
1258 exp->checkPurity(sc, f);
1259 exp->checkSafety(sc, f);
1260 exp->checkNogc(sc, f);
1261 checkAccess(sd, exp->loc, sc, f);
1262
1263 TypeFunction *tf = (TypeFunction *)f->type;
1264 Type *rettype;
1265 if (functionParameters(exp->loc, sc, tf, NULL, exp->newargs, f, &rettype, &newprefix))
1266 return setError();
1267
1268 exp->allocator = f->isNewDeclaration();
1269 assert(exp->allocator);
1270 }
1271 else
1272 {
1273 if (exp->newargs && exp->newargs->dim)
1274 {
1275 exp->error("no allocator for %s", sd->toChars());
1276 return setError();
1277 }
1278 }
1279
1280 if (sd->ctor && nargs)
1281 {
1282 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, sd->ctor, NULL, tb, exp->arguments, 0);
1283 if (!f || f->errors)
1284 return setError();
1285 exp->checkDeprecated(sc, f);
1286 exp->checkPurity(sc, f);
1287 exp->checkSafety(sc, f);
1288 exp->checkNogc(sc, f);
1289 checkAccess(sd, exp->loc, sc, f);
1290
1291 TypeFunction *tf = (TypeFunction *)f->type;
1292 if (!exp->arguments)
1293 exp->arguments = new Expressions();
1294 if (functionParameters(exp->loc, sc, tf, exp->type, exp->arguments, f, &exp->type, &exp->argprefix))
1295 return setError();
1296
1297 exp->member = f->isCtorDeclaration();
1298 assert(exp->member);
1299
1300 if (checkFrameAccess(exp->loc, sc, sd, sd->fields.dim))
1301 return setError();
1302 }
1303 else
1304 {
1305 if (!exp->arguments)
1306 exp->arguments = new Expressions();
1307
1308 if (!sd->fit(exp->loc, sc, exp->arguments, tb))
1309 return setError();
1310 if (!sd->fill(exp->loc, exp->arguments, false))
1311 return setError();
1312 if (checkFrameAccess(exp->loc, sc, sd, exp->arguments ? exp->arguments->dim : 0))
1313 return setError();
1314 }
1315
1316 exp->type = exp->type->pointerTo();
1317 }
1318 else if (tb->ty == Tarray && nargs)
1319 {
1320 Type *tn = tb->nextOf()->baseElemOf();
1321 Dsymbol *s = tn->toDsymbol(sc);
1322 AggregateDeclaration *ad = s ? s->isAggregateDeclaration() : NULL;
1323 if (ad && ad->noDefaultCtor)
1324 {
1325 exp->error("default construction is disabled for type %s", tb->nextOf()->toChars());
1326 return setError();
1327 }
1328 for (size_t i = 0; i < nargs; i++)
1329 {
1330 if (tb->ty != Tarray)
1331 {
1332 exp->error("too many arguments for array");
1333 return setError();
1334 }
1335
1336 Expression *arg = (*exp->arguments)[i];
1337 arg = resolveProperties(sc, arg);
1338 arg = arg->implicitCastTo(sc, Type::tsize_t);
1339 arg = arg->optimize(WANTvalue);
1340 if (arg->op == TOKint64 && (sinteger_t)arg->toInteger() < 0)
1341 {
1342 exp->error("negative array index %s", arg->toChars());
1343 return setError();
1344 }
1345 (*exp->arguments)[i] = arg;
1346 tb = ((TypeDArray *)tb)->next->toBasetype();
1347 }
1348 }
1349 else if (tb->isscalar())
1350 {
1351 if (!nargs)
1352 {
1353 }
1354 else if (nargs == 1)
1355 {
1356 Expression *e = (*exp->arguments)[0];
1357 e = e->implicitCastTo(sc, tb);
1358 (*exp->arguments)[0] = e;
1359 }
1360 else
1361 {
1362 exp->error("more than one argument for construction of %s", exp->type->toChars());
1363 return setError();
1364 }
1365
1366 exp->type = exp->type->pointerTo();
1367 }
1368 else
1369 {
1370 exp->error("new can only create structs, dynamic arrays or class objects, not %s's", exp->type->toChars());
1371 return setError();
1372 }
1373
1374 //printf("NewExp: '%s'\n", toChars());
1375 //printf("NewExp:type '%s'\n", exp->type->toChars());
1376 semanticTypeInfo(sc, exp->type);
1377
1378 if (newprefix)
1379 {
1380 result = Expression::combine(newprefix, exp);
1381 return;
1382 }
1383 result = exp;
1384 }
1385
visit(NewAnonClassExp * e)1386 void visit(NewAnonClassExp *e)
1387 {
1388 Expression *d = new DeclarationExp(e->loc, e->cd);
1389 sc = sc->push(); // just create new scope
1390 sc->flags &= ~SCOPEctfe; // temporary stop CTFE
1391 d = semantic(d, sc);
1392 sc = sc->pop();
1393
1394 if (!e->cd->errors && sc->intypeof && !sc->parent->inNonRoot())
1395 {
1396 ScopeDsymbol *sds = sc->tinst ? (ScopeDsymbol *)sc->tinst : sc->_module;
1397 sds->members->push(e->cd);
1398 }
1399
1400 Expression *n = new NewExp(e->loc, e->thisexp, e->newargs, e->cd->type, e->arguments);
1401
1402 Expression *c = new CommaExp(e->loc, d, n);
1403 result = semantic(c, sc);
1404 }
1405
visit(SymOffExp * e)1406 void visit(SymOffExp *e)
1407 {
1408 //var->semantic(sc);
1409 if (!e->type)
1410 e->type = e->var->type->pointerTo();
1411 if (VarDeclaration *v = e->var->isVarDeclaration())
1412 {
1413 if (v->checkNestedReference(sc, e->loc))
1414 return setError();
1415 }
1416 else if (FuncDeclaration *f = e->var->isFuncDeclaration())
1417 {
1418 if (f->checkNestedReference(sc, e->loc))
1419 return setError();
1420 }
1421 result = e;
1422 }
1423
visit(VarExp * e)1424 void visit(VarExp *e)
1425 {
1426 if (FuncDeclaration *fd = e->var->isFuncDeclaration())
1427 {
1428 //printf("L%d fd = %s\n", __LINE__, f->toChars());
1429 if (!fd->functionSemantic())
1430 return setError();
1431 }
1432
1433 if (!e->type)
1434 e->type = e->var->type;
1435
1436 if (e->type && !e->type->deco)
1437 e->type = e->type->semantic(e->loc, sc);
1438
1439 /* Fix for 1161 doesn't work because it causes protection
1440 * problems when instantiating imported templates passing private
1441 * variables as alias template parameters.
1442 */
1443 //checkAccess(e->loc, sc, NULL, e->var);
1444
1445 if (VarDeclaration *vd = e->var->isVarDeclaration())
1446 {
1447 if (vd->checkNestedReference(sc, e->loc))
1448 return setError();
1449 // Bugzilla 12025: If the variable is not actually used in runtime code,
1450 // the purity violation error is redundant.
1451 //checkPurity(sc, vd);
1452 }
1453 else if (FuncDeclaration *fd = e->var->isFuncDeclaration())
1454 {
1455 // TODO: If fd isn't yet resolved its overload, the checkNestedReference
1456 // call would cause incorrect validation.
1457 // Maybe here should be moved in CallExp, or AddrExp for functions.
1458 if (fd->checkNestedReference(sc, e->loc))
1459 return setError();
1460 }
1461 else if (e->var->isOverDeclaration())
1462 {
1463 e->type = Type::tvoid; // ambiguous type?
1464 }
1465
1466 result = e;
1467 }
1468
visit(TupleExp * exp)1469 void visit(TupleExp *exp)
1470 {
1471 if (exp->type)
1472 {
1473 result = exp;
1474 return;
1475 }
1476
1477 if (exp->e0)
1478 exp->e0 = semantic(exp->e0, sc);
1479
1480 // Run semantic() on each argument
1481 bool err = false;
1482 for (size_t i = 0; i < exp->exps->dim; i++)
1483 {
1484 Expression *e = (*exp->exps)[i];
1485 e = semantic(e, sc);
1486 if (!e->type)
1487 {
1488 exp->error("%s has no value", e->toChars());
1489 err = true;
1490 }
1491 else if (e->op == TOKerror)
1492 err = true;
1493 else
1494 (*exp->exps)[i] = e;
1495 }
1496 if (err)
1497 return setError();
1498
1499 expandTuples(exp->exps);
1500 exp->type = new TypeTuple(exp->exps);
1501 exp->type = exp->type->semantic(exp->loc, sc);
1502 //printf("-TupleExp::semantic(%s)\n", exp->toChars());
1503 result = exp;
1504 }
1505
visit(FuncExp * exp)1506 void visit(FuncExp *exp)
1507 {
1508 Expression *e = exp;
1509
1510 sc = sc->push(); // just create new scope
1511 sc->flags &= ~SCOPEctfe; // temporary stop CTFE
1512 sc->protection = Prot(PROTpublic); // Bugzilla 12506
1513
1514 if (!exp->type || exp->type == Type::tvoid)
1515 {
1516 /* fd->treq might be incomplete type,
1517 * so should not semantic it.
1518 * void foo(T)(T delegate(int) dg){}
1519 * foo(a=>a); // in IFTI, treq == T delegate(int)
1520 */
1521 //if (exp->fd->treq)
1522 // exp->fd->treq = exp->fd->treq->semantic(exp->loc, sc);
1523
1524 exp->genIdent(sc);
1525
1526 // Set target of return type inference
1527 if (exp->fd->treq && !exp->fd->type->nextOf())
1528 {
1529 TypeFunction *tfv = NULL;
1530 if (exp->fd->treq->ty == Tdelegate ||
1531 (exp->fd->treq->ty == Tpointer && exp->fd->treq->nextOf()->ty == Tfunction))
1532 tfv = (TypeFunction *)exp->fd->treq->nextOf();
1533 if (tfv)
1534 {
1535 TypeFunction *tfl = (TypeFunction *)exp->fd->type;
1536 tfl->next = tfv->nextOf();
1537 }
1538 }
1539
1540 //printf("td = %p, treq = %p\n", exp->td, exp->fd->treq);
1541 if (exp->td)
1542 {
1543 assert(exp->td->parameters && exp->td->parameters->dim);
1544 exp->td->semantic(sc);
1545 exp->type = Type::tvoid; // temporary type
1546
1547 if (exp->fd->treq) // defer type determination
1548 {
1549 FuncExp *fe;
1550 if (exp->matchType(exp->fd->treq, sc, &fe) > MATCHnomatch)
1551 e = fe;
1552 else
1553 e = new ErrorExp();
1554 }
1555 goto Ldone;
1556 }
1557
1558 unsigned olderrors = global.errors;
1559 exp->fd->semantic(sc);
1560 if (olderrors == global.errors)
1561 {
1562 exp->fd->semantic2(sc);
1563 if (olderrors == global.errors)
1564 exp->fd->semantic3(sc);
1565 }
1566 if (olderrors != global.errors)
1567 {
1568 if (exp->fd->type && exp->fd->type->ty == Tfunction && !exp->fd->type->nextOf())
1569 ((TypeFunction *)exp->fd->type)->next = Type::terror;
1570 e = new ErrorExp();
1571 goto Ldone;
1572 }
1573
1574 // Type is a "delegate to" or "pointer to" the function literal
1575 if ((exp->fd->isNested() && exp->fd->tok == TOKdelegate) ||
1576 (exp->tok == TOKreserved && exp->fd->treq && exp->fd->treq->ty == Tdelegate))
1577 {
1578 exp->type = new TypeDelegate(exp->fd->type);
1579 exp->type = exp->type->semantic(exp->loc, sc);
1580
1581 exp->fd->tok = TOKdelegate;
1582 }
1583 else
1584 {
1585 exp->type = new TypePointer(exp->fd->type);
1586 exp->type = exp->type->semantic(exp->loc, sc);
1587 //exp->type = exp->fd->type->pointerTo();
1588
1589 /* A lambda expression deduced to function pointer might become
1590 * to a delegate literal implicitly.
1591 *
1592 * auto foo(void function() fp) { return 1; }
1593 * assert(foo({}) == 1);
1594 *
1595 * So, should keep fd->tok == TOKreserve if fd->treq == NULL.
1596 */
1597 if (exp->fd->treq && exp->fd->treq->ty == Tpointer)
1598 {
1599 // change to non-nested
1600 exp->fd->tok = TOKfunction;
1601 exp->fd->vthis = NULL;
1602 }
1603 }
1604 exp->fd->tookAddressOf++;
1605 }
1606 Ldone:
1607 sc = sc->pop();
1608 result = e;
1609 }
1610
1611 // used from CallExp::semantic()
callExpSemantic(FuncExp * exp,Scope * sc,Expressions * arguments)1612 Expression *callExpSemantic(FuncExp *exp, Scope *sc, Expressions *arguments)
1613 {
1614 if ((!exp->type || exp->type == Type::tvoid) && exp->td && arguments && arguments->dim)
1615 {
1616 for (size_t k = 0; k < arguments->dim; k++)
1617 { Expression *checkarg = (*arguments)[k];
1618 if (checkarg->op == TOKerror)
1619 return checkarg;
1620 }
1621
1622 exp->genIdent(sc);
1623
1624 assert(exp->td->parameters && exp->td->parameters->dim);
1625 exp->td->semantic(sc);
1626
1627 TypeFunction *tfl = (TypeFunction *)exp->fd->type;
1628 size_t dim = Parameter::dim(tfl->parameters);
1629 if (arguments->dim < dim)
1630 { // Default arguments are always typed, so they don't need inference.
1631 Parameter *p = Parameter::getNth(tfl->parameters, arguments->dim);
1632 if (p->defaultArg)
1633 dim = arguments->dim;
1634 }
1635
1636 if ((!tfl->varargs && arguments->dim == dim) ||
1637 ( tfl->varargs && arguments->dim >= dim))
1638 {
1639 Objects *tiargs = new Objects();
1640 tiargs->reserve(exp->td->parameters->dim);
1641
1642 for (size_t i = 0; i < exp->td->parameters->dim; i++)
1643 {
1644 TemplateParameter *tp = (*exp->td->parameters)[i];
1645 for (size_t u = 0; u < dim; u++)
1646 { Parameter *p = Parameter::getNth(tfl->parameters, u);
1647 if (p->type->ty == Tident &&
1648 ((TypeIdentifier *)p->type)->ident == tp->ident)
1649 { Expression *e = (*arguments)[u];
1650 tiargs->push(e->type);
1651 u = dim; // break inner loop
1652 }
1653 }
1654 }
1655
1656 TemplateInstance *ti = new TemplateInstance(exp->loc, exp->td, tiargs);
1657 Expression *se = new ScopeExp(exp->loc, ti);
1658 return semantic(se, sc);
1659 }
1660 exp->error("cannot infer function literal type");
1661 return new ErrorExp();
1662 }
1663 return semantic(exp, sc);
1664 }
1665
visit(DeclarationExp * e)1666 void visit(DeclarationExp *e)
1667 {
1668 if (e->type)
1669 {
1670 result = e;
1671 return;
1672 }
1673
1674 unsigned olderrors = global.errors;
1675
1676 /* This is here to support extern(linkage) declaration,
1677 * where the extern(linkage) winds up being an AttribDeclaration
1678 * wrapper.
1679 */
1680 Dsymbol *s = e->declaration;
1681
1682 while (1)
1683 {
1684 AttribDeclaration *ad = s->isAttribDeclaration();
1685 if (ad)
1686 {
1687 if (ad->decl && ad->decl->dim == 1)
1688 {
1689 s = (*ad->decl)[0];
1690 continue;
1691 }
1692 }
1693 break;
1694 }
1695
1696 VarDeclaration *v = s->isVarDeclaration();
1697 if (v)
1698 {
1699 // Do semantic() on initializer first, so:
1700 // int a = a;
1701 // will be illegal.
1702 e->declaration->semantic(sc);
1703 s->parent = sc->parent;
1704 }
1705
1706 //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc);
1707 // Insert into both local scope and function scope.
1708 // Must be unique in both.
1709 if (s->ident)
1710 {
1711 if (!sc->insert(s))
1712 {
1713 e->error("declaration %s is already defined", s->toPrettyChars());
1714 return setError();
1715 }
1716 else if (sc->func)
1717 {
1718 // Bugzilla 11720 - include Dataseg variables
1719 if ((s->isFuncDeclaration() ||
1720 s->isAggregateDeclaration() ||
1721 s->isEnumDeclaration() ||
1722 (v && v->isDataseg())) &&
1723 !sc->func->localsymtab->insert(s))
1724 {
1725 e->error("declaration %s is already defined in another scope in %s",
1726 s->toPrettyChars(), sc->func->toChars());
1727 return setError();
1728 }
1729 else
1730 {
1731 // Disallow shadowing
1732 for (Scope *scx = sc->enclosing; scx && scx->func == sc->func; scx = scx->enclosing)
1733 {
1734 Dsymbol *s2;
1735 if (scx->scopesym && scx->scopesym->symtab &&
1736 (s2 = scx->scopesym->symtab->lookup(s->ident)) != NULL &&
1737 s != s2)
1738 {
1739 e->error("%s %s is shadowing %s %s", s->kind(), s->ident->toChars(), s2->kind(), s2->toPrettyChars());
1740 return setError();
1741 }
1742 }
1743 }
1744 }
1745 }
1746 if (!s->isVarDeclaration())
1747 {
1748 Scope *sc2 = sc;
1749 if (sc2->stc & (STCpure | STCnothrow | STCnogc))
1750 sc2 = sc->push();
1751 sc2->stc &= ~(STCpure | STCnothrow | STCnogc);
1752 e->declaration->semantic(sc2);
1753 if (sc2 != sc)
1754 sc2->pop();
1755 s->parent = sc->parent;
1756 }
1757 if (global.errors == olderrors)
1758 {
1759 e->declaration->semantic2(sc);
1760 if (global.errors == olderrors)
1761 {
1762 e->declaration->semantic3(sc);
1763 }
1764 }
1765 // todo: error in declaration should be propagated.
1766
1767 e->type = Type::tvoid;
1768 result = e;
1769 }
1770
visit(TypeidExp * exp)1771 void visit(TypeidExp *exp)
1772 {
1773 Type *ta = isType(exp->obj);
1774 Expression *ea = isExpression(exp->obj);
1775 Dsymbol *sa = isDsymbol(exp->obj);
1776
1777 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1778
1779 if (ta)
1780 {
1781 ta->resolve(exp->loc, sc, &ea, &ta, &sa, true);
1782 }
1783
1784 if (ea)
1785 {
1786 if (Dsymbol *sym = getDsymbol(ea))
1787 ea = resolve(exp->loc, sc, sym, false);
1788 else
1789 ea = semantic(ea, sc);
1790 ea = resolveProperties(sc, ea);
1791 ta = ea->type;
1792 if (ea->op == TOKtype)
1793 ea = NULL;
1794 }
1795
1796 if (!ta)
1797 {
1798 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1799 exp->error("no type for typeid(%s)", ea ? ea->toChars() : (sa ? sa->toChars() : ""));
1800 return setError();
1801 }
1802
1803 if (global.params.vcomplex)
1804 ta->checkComplexTransition(exp->loc);
1805
1806 Expression *e;
1807 if (ea && ta->toBasetype()->ty == Tclass)
1808 {
1809 /* Get the dynamic type, which is .classinfo
1810 */
1811 ea = semantic(ea, sc);
1812 e = new TypeidExp(ea->loc, ea);
1813 e->type = Type::typeinfoclass->type;
1814 }
1815 else if (ta->ty == Terror)
1816 {
1817 e = new ErrorExp();
1818 }
1819 else
1820 {
1821 // Handle this in the glue layer
1822 e = new TypeidExp(exp->loc, ta);
1823 e->type = getTypeInfoType(exp->loc, ta, sc);
1824
1825 semanticTypeInfo(sc, ta);
1826
1827 if (ea)
1828 {
1829 e = new CommaExp(exp->loc, ea, e); // execute ea
1830 e = semantic(e, sc);
1831 }
1832 }
1833 result = e;
1834 }
1835
visit(TraitsExp * e)1836 void visit(TraitsExp *e)
1837 {
1838 result = semanticTraits(e, sc);
1839 }
1840
visit(HaltExp * e)1841 void visit(HaltExp *e)
1842 {
1843 e->type = Type::tvoid;
1844 result = e;
1845 }
1846
visit(IsExp * e)1847 void visit(IsExp *e)
1848 {
1849 /* is(targ id tok tspec)
1850 * is(targ id : tok2)
1851 * is(targ id == tok2)
1852 */
1853
1854 //printf("IsExp::semantic(%s)\n", toChars());
1855 if (e->id && !(sc->flags & SCOPEcondition))
1856 {
1857 e->error("can only declare type aliases within static if conditionals or static asserts");
1858 return setError();
1859 }
1860
1861 Type *tded = NULL;
1862 Scope *sc2 = sc->copy(); // keep sc->flags
1863 sc2->tinst = NULL;
1864 sc2->minst = NULL;
1865 sc2->flags |= SCOPEfullinst;
1866 Type *t = e->targ->trySemantic(e->loc, sc2);
1867 sc2->pop();
1868 if (!t)
1869 goto Lno; // errors, so condition is false
1870 e->targ = t;
1871 if (e->tok2 != TOKreserved)
1872 {
1873 switch (e->tok2)
1874 {
1875 case TOKstruct:
1876 if (e->targ->ty != Tstruct)
1877 goto Lno;
1878 if (((TypeStruct *)e->targ)->sym->isUnionDeclaration())
1879 goto Lno;
1880 tded = e->targ;
1881 break;
1882
1883 case TOKunion:
1884 if (e->targ->ty != Tstruct)
1885 goto Lno;
1886 if (!((TypeStruct *)e->targ)->sym->isUnionDeclaration())
1887 goto Lno;
1888 tded = e->targ;
1889 break;
1890
1891 case TOKclass:
1892 if (e->targ->ty != Tclass)
1893 goto Lno;
1894 if (((TypeClass *)e->targ)->sym->isInterfaceDeclaration())
1895 goto Lno;
1896 tded = e->targ;
1897 break;
1898
1899 case TOKinterface:
1900 if (e->targ->ty != Tclass)
1901 goto Lno;
1902 if (!((TypeClass *)e->targ)->sym->isInterfaceDeclaration())
1903 goto Lno;
1904 tded = e->targ;
1905 break;
1906 case TOKconst:
1907 if (!e->targ->isConst())
1908 goto Lno;
1909 tded = e->targ;
1910 break;
1911
1912 case TOKimmutable:
1913 if (!e->targ->isImmutable())
1914 goto Lno;
1915 tded = e->targ;
1916 break;
1917
1918 case TOKshared:
1919 if (!e->targ->isShared())
1920 goto Lno;
1921 tded = e->targ;
1922 break;
1923
1924 case TOKwild:
1925 if (!e->targ->isWild())
1926 goto Lno;
1927 tded = e->targ;
1928 break;
1929
1930 case TOKsuper:
1931 // If class or interface, get the base class and interfaces
1932 if (e->targ->ty != Tclass)
1933 goto Lno;
1934 else
1935 {
1936 ClassDeclaration *cd = ((TypeClass *)e->targ)->sym;
1937 Parameters *args = new Parameters;
1938 args->reserve(cd->baseclasses->dim);
1939 if (cd->_scope && !cd->symtab)
1940 cd->semantic(cd->_scope);
1941 for (size_t i = 0; i < cd->baseclasses->dim; i++)
1942 {
1943 BaseClass *b = (*cd->baseclasses)[i];
1944 args->push(new Parameter(STCin, b->type, NULL, NULL));
1945 }
1946 tded = new TypeTuple(args);
1947 }
1948 break;
1949
1950 case TOKenum:
1951 if (e->targ->ty != Tenum)
1952 goto Lno;
1953 if (e->id)
1954 tded = ((TypeEnum *)e->targ)->sym->getMemtype(e->loc);
1955 else
1956 tded = e->targ;
1957 if (tded->ty == Terror)
1958 return setError();
1959 break;
1960
1961 case TOKdelegate:
1962 if (e->targ->ty != Tdelegate)
1963 goto Lno;
1964 tded = ((TypeDelegate *)e->targ)->next; // the underlying function type
1965 break;
1966
1967 case TOKfunction:
1968 case TOKparameters:
1969 {
1970 if (e->targ->ty != Tfunction)
1971 goto Lno;
1972 tded = e->targ;
1973
1974 /* Generate tuple from function parameter types.
1975 */
1976 assert(tded->ty == Tfunction);
1977 Parameters *params = ((TypeFunction *)tded)->parameters;
1978 size_t dim = Parameter::dim(params);
1979 Parameters *args = new Parameters;
1980 args->reserve(dim);
1981 for (size_t i = 0; i < dim; i++)
1982 {
1983 Parameter *arg = Parameter::getNth(params, i);
1984 assert(arg && arg->type);
1985 /* If one of the default arguments was an error,
1986 don't return an invalid tuple
1987 */
1988 if (e->tok2 == TOKparameters && arg->defaultArg &&
1989 arg->defaultArg->op == TOKerror)
1990 return setError();
1991 args->push(new Parameter(arg->storageClass, arg->type,
1992 (e->tok2 == TOKparameters) ? arg->ident : NULL,
1993 (e->tok2 == TOKparameters) ? arg->defaultArg : NULL));
1994 }
1995 tded = new TypeTuple(args);
1996 break;
1997 }
1998 case TOKreturn:
1999 /* Get the 'return type' for the function,
2000 * delegate, or pointer to function.
2001 */
2002 if (e->targ->ty == Tfunction)
2003 tded = ((TypeFunction *)e->targ)->next;
2004 else if (e->targ->ty == Tdelegate)
2005 {
2006 tded = ((TypeDelegate *)e->targ)->next;
2007 tded = ((TypeFunction *)tded)->next;
2008 }
2009 else if (e->targ->ty == Tpointer &&
2010 ((TypePointer *)e->targ)->next->ty == Tfunction)
2011 {
2012 tded = ((TypePointer *)e->targ)->next;
2013 tded = ((TypeFunction *)tded)->next;
2014 }
2015 else
2016 goto Lno;
2017 break;
2018
2019 case TOKargTypes:
2020 /* Generate a type tuple of the equivalent types used to determine if a
2021 * function argument of this type can be passed in registers.
2022 * The results of this are highly platform dependent, and intended
2023 * primarly for use in implementing va_arg().
2024 */
2025 tded = toArgTypes(e->targ);
2026 if (!tded)
2027 goto Lno; // not valid for a parameter
2028 break;
2029
2030 case TOKvector:
2031 if (e->targ->ty != Tvector)
2032 goto Lno;
2033 tded = ((TypeVector *)e->targ)->basetype;
2034 break;
2035
2036 default:
2037 assert(0);
2038 }
2039 goto Lyes;
2040 }
2041 else if (e->tspec && !e->id && !(e->parameters && e->parameters->dim))
2042 {
2043 /* Evaluate to true if targ matches tspec
2044 * is(targ == tspec)
2045 * is(targ : tspec)
2046 */
2047 e->tspec = e->tspec->semantic(e->loc, sc);
2048 //printf("targ = %s, %s\n", e->targ->toChars(), e->targ->deco);
2049 //printf("tspec = %s, %s\n", e->tspec->toChars(), e->tspec->deco);
2050 if (e->tok == TOKcolon)
2051 {
2052 if (e->targ->implicitConvTo(e->tspec))
2053 goto Lyes;
2054 else
2055 goto Lno;
2056 }
2057 else /* == */
2058 {
2059 if (e->targ->equals(e->tspec))
2060 goto Lyes;
2061 else
2062 goto Lno;
2063 }
2064 }
2065 else if (e->tspec)
2066 {
2067 /* Evaluate to true if targ matches tspec.
2068 * If true, declare id as an alias for the specialized type.
2069 * is(targ == tspec, tpl)
2070 * is(targ : tspec, tpl)
2071 * is(targ id == tspec)
2072 * is(targ id : tspec)
2073 * is(targ id == tspec, tpl)
2074 * is(targ id : tspec, tpl)
2075 */
2076
2077 Identifier *tid = e->id ? e->id : Identifier::generateId("__isexp_id");
2078 e->parameters->insert(0, new TemplateTypeParameter(e->loc, tid, NULL, NULL));
2079
2080 Objects dedtypes;
2081 dedtypes.setDim(e->parameters->dim);
2082 dedtypes.zero();
2083
2084 MATCH m = deduceType(e->targ, sc, e->tspec, e->parameters, &dedtypes);
2085 //printf("targ: %s\n", e->targ->toChars());
2086 //printf("tspec: %s\n", e->tspec->toChars());
2087 if (m <= MATCHnomatch ||
2088 (m != MATCHexact && e->tok == TOKequal))
2089 {
2090 goto Lno;
2091 }
2092 else
2093 {
2094 tded = (Type *)dedtypes[0];
2095 if (!tded)
2096 tded = e->targ;
2097 Objects tiargs;
2098 tiargs.setDim(1);
2099 tiargs[0] = e->targ;
2100
2101 /* Declare trailing parameters
2102 */
2103 for (size_t i = 1; i < e->parameters->dim; i++)
2104 {
2105 TemplateParameter *tp = (*e->parameters)[i];
2106 Declaration *s = NULL;
2107
2108 m = tp->matchArg(e->loc, sc, &tiargs, i, e->parameters, &dedtypes, &s);
2109 if (m <= MATCHnomatch)
2110 goto Lno;
2111 s->semantic(sc);
2112 if (sc->sds)
2113 s->addMember(sc, sc->sds);
2114 else if (!sc->insert(s))
2115 e->error("declaration %s is already defined", s->toChars());
2116
2117 unSpeculative(sc, s);
2118 }
2119 goto Lyes;
2120 }
2121 }
2122 else if (e->id)
2123 {
2124 /* Declare id as an alias for type targ. Evaluate to true
2125 * is(targ id)
2126 */
2127 tded = e->targ;
2128 goto Lyes;
2129 }
2130
2131 Lyes:
2132 if (e->id)
2133 {
2134 Dsymbol *s;
2135 Tuple *tup = isTuple(tded);
2136 if (tup)
2137 s = new TupleDeclaration(e->loc, e->id, &(tup->objects));
2138 else
2139 s = new AliasDeclaration(e->loc, e->id, tded);
2140 s->semantic(sc);
2141 /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there.
2142 * More investigation is needed.
2143 */
2144 if (!tup && !sc->insert(s))
2145 e->error("declaration %s is already defined", s->toChars());
2146 if (sc->sds)
2147 s->addMember(sc, sc->sds);
2148
2149 unSpeculative(sc, s);
2150 }
2151 //printf("Lyes\n");
2152 result = new IntegerExp(e->loc, 1, Type::tbool);
2153 return;
2154
2155 Lno:
2156 //printf("Lno\n");
2157 result = new IntegerExp(e->loc, 0, Type::tbool);
2158 }
2159
visit(BinAssignExp * exp)2160 void visit(BinAssignExp *exp)
2161 {
2162 if (exp->type)
2163 {
2164 result = exp;
2165 return;
2166 }
2167
2168 Expression *e = exp->op_overload(sc);
2169 if (e)
2170 {
2171 result = e;
2172 return;
2173 }
2174
2175 if (exp->e1->checkReadModifyWrite(exp->op, exp->e2))
2176 return setError();
2177
2178 if (exp->e1->op == TOKarraylength)
2179 {
2180 // arr.length op= e2;
2181 e = ArrayLengthExp::rewriteOpAssign(exp);
2182 e = semantic(e, sc);
2183 result = e;
2184 return;
2185 }
2186 if (exp->e1->op == TOKslice || exp->e1->type->ty == Tarray || exp->e1->type->ty == Tsarray)
2187 {
2188 if (exp->e1->op == TOKslice)
2189 ((SliceExp *)exp->e1)->arrayop = true;
2190
2191 // T[] op= ...
2192 if (exp->e2->implicitConvTo(exp->e1->type->nextOf()))
2193 {
2194 // T[] op= T
2195 exp->e2 = exp->e2->castTo(sc, exp->e1->type->nextOf());
2196 }
2197 else if (Expression *ex = typeCombine(exp, sc))
2198 {
2199 result = ex;
2200 return;
2201 }
2202 exp->type = exp->e1->type;
2203 result = arrayOp(exp, sc);
2204 return;
2205 }
2206
2207 exp->e1 = semantic(exp->e1, sc);
2208 exp->e1 = exp->e1->optimize(WANTvalue);
2209 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1);
2210 exp->type = exp->e1->type;
2211 if (exp->checkScalar())
2212 return setError();
2213
2214 int arith = (exp->op == TOKaddass || exp->op == TOKminass || exp->op == TOKmulass ||
2215 exp->op == TOKdivass || exp->op == TOKmodass || exp->op == TOKpowass);
2216 int bitwise = (exp->op == TOKandass || exp->op == TOKorass || exp->op == TOKxorass);
2217 int shift = (exp->op == TOKshlass || exp->op == TOKshrass || exp->op == TOKushrass);
2218
2219 if (bitwise && exp->type->toBasetype()->ty == Tbool)
2220 exp->e2 = exp->e2->implicitCastTo(sc, exp->type);
2221 else if (exp->checkNoBool())
2222 return setError();
2223
2224 if ((exp->op == TOKaddass || exp->op == TOKminass) &&
2225 exp->e1->type->toBasetype()->ty == Tpointer &&
2226 exp->e2->type->toBasetype()->isintegral())
2227 {
2228 result = scaleFactor(exp, sc);
2229 return;
2230 }
2231
2232 if (Expression *ex = typeCombine(exp, sc))
2233 {
2234 result = ex;
2235 return;
2236 }
2237
2238 if (arith && exp->checkArithmeticBin())
2239 return setError();
2240 if ((bitwise || shift) && exp->checkIntegralBin())
2241 return setError();
2242 if (shift)
2243 {
2244 if (exp->e2->type->toBasetype()->ty != Tvector)
2245 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt);
2246 }
2247
2248 if (!Target::isVectorOpSupported(exp->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
2249 {
2250 result = exp->incompatibleTypes();
2251 return;
2252 }
2253
2254 if (exp->e1->op == TOKerror || exp->e2->op == TOKerror)
2255 return setError();
2256
2257 e = exp->checkOpAssignTypes(sc);
2258 if (e->op == TOKerror)
2259 {
2260 result = e;
2261 return;
2262 }
2263
2264 assert(e->op == TOKassign || e == exp);
2265 result = ((BinExp *)e)->reorderSettingAAElem(sc);
2266 }
2267
visit(CompileExp * exp)2268 void visit(CompileExp *exp)
2269 {
2270 StringExp *se = semanticString(sc, exp->e1, "argument to mixin");
2271 if (!se)
2272 return setError();
2273 se = se->toUTF8(sc);
2274 unsigned errors = global.errors;
2275 Parser p(exp->loc, sc->_module, (utf8_t *)se->string, se->len, 0);
2276 p.nextToken();
2277 //printf("p.loc.linnum = %d\n", p.loc.linnum);
2278 Expression *e = p.parseExpression();
2279 if (p.errors)
2280 {
2281 assert(global.errors != errors); // should have caught all these cases
2282 return setError();
2283 }
2284 if (p.token.value != TOKeof)
2285 {
2286 exp->error("incomplete mixin expression (%s)", se->toChars());
2287 return setError();
2288 }
2289 result = semantic(e, sc);
2290 }
2291
visit(ImportExp * e)2292 void visit(ImportExp *e)
2293 {
2294 StringExp *se = semanticString(sc, e->e1, "file name argument");
2295 if (!se)
2296 return setError();
2297 se = se->toUTF8(sc);
2298
2299 const char *name = (char *)se->string;
2300 if (!global.params.fileImppath)
2301 {
2302 e->error("need -Jpath switch to import text file %s", name);
2303 return setError();
2304 }
2305
2306 /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory
2307 * ('Path Traversal') attacks.
2308 * http://cwe.mitre.org/data/definitions/22.html
2309 */
2310
2311 name = FileName::safeSearchPath(global.filePath, name);
2312 if (!name)
2313 {
2314 e->error("file %s cannot be found or not in a path specified with -J", se->toChars());
2315 return setError();
2316 }
2317
2318 if (global.params.verbose)
2319 message("file %.*s\t(%s)", (int)se->len, (char *)se->string, name);
2320 if (global.params.moduleDeps != NULL)
2321 {
2322 OutBuffer *ob = global.params.moduleDeps;
2323 Module* imod = sc->instantiatingModule();
2324
2325 if (!global.params.moduleDepsFile)
2326 ob->writestring("depsFile ");
2327 ob->writestring(imod->toPrettyChars());
2328 ob->writestring(" (");
2329 escapePath(ob, imod->srcfile->toChars());
2330 ob->writestring(") : ");
2331 if (global.params.moduleDepsFile)
2332 ob->writestring("string : ");
2333 ob->writestring((char *) se->string);
2334 ob->writestring(" (");
2335 escapePath(ob, name);
2336 ob->writestring(")");
2337 ob->writenl();
2338 }
2339
2340 {
2341 File f(name);
2342 if (f.read())
2343 {
2344 e->error("cannot read file %s", f.toChars());
2345 return setError();
2346 }
2347 else
2348 {
2349 f.ref = 1;
2350 se = new StringExp(e->loc, f.buffer, f.len);
2351 }
2352 }
2353 result = semantic(se, sc);
2354 }
2355
visit(AssertExp * exp)2356 void visit(AssertExp *exp)
2357 {
2358 if (Expression *ex = unaSemantic(exp, sc))
2359 {
2360 result = ex;
2361 return;
2362 }
2363 exp->e1 = resolveProperties(sc, exp->e1);
2364 // BUG: see if we can do compile time elimination of the Assert
2365 exp->e1 = exp->e1->optimize(WANTvalue);
2366 exp->e1 = exp->e1->toBoolean(sc);
2367 if (exp->msg)
2368 {
2369 exp->msg = semantic(exp->msg, sc);
2370 exp->msg = resolveProperties(sc, exp->msg);
2371 exp->msg = exp->msg->implicitCastTo(sc, Type::tchar->constOf()->arrayOf());
2372 exp->msg = exp->msg->optimize(WANTvalue);
2373 }
2374
2375 if (exp->e1->op == TOKerror)
2376 {
2377 result = exp->e1;
2378 return;
2379 }
2380 if (exp->msg && exp->msg->op == TOKerror)
2381 {
2382 result = exp->msg;
2383 return;
2384 }
2385
2386 bool f1 = checkNonAssignmentArrayOp(exp->e1);
2387 bool f2 = exp->msg && checkNonAssignmentArrayOp(exp->msg);
2388 if (f1 || f2)
2389 return setError();
2390
2391 if (exp->e1->isBool(false))
2392 {
2393 FuncDeclaration *fd = sc->parent->isFuncDeclaration();
2394 if (fd)
2395 fd->hasReturnExp |= 4;
2396 sc->callSuper |= CSXhalt;
2397 if (sc->fieldinit)
2398 {
2399 for (size_t i = 0; i < sc->fieldinit_dim; i++)
2400 sc->fieldinit[i] |= CSXhalt;
2401 }
2402
2403 if (!global.params.useAssert)
2404 {
2405 Expression *e = new HaltExp(exp->loc);
2406 e = semantic(e, sc);
2407 result = e;
2408 return;
2409 }
2410 }
2411 exp->type = Type::tvoid;
2412 result = exp;
2413 }
2414
visit(DotIdExp * exp)2415 void visit(DotIdExp *exp)
2416 {
2417 Expression *e = semanticY(exp, sc, 1);
2418 if (e && isDotOpDispatch(e))
2419 {
2420 unsigned errors = global.startGagging();
2421 e = resolvePropertiesX(sc, e);
2422 if (global.endGagging(errors))
2423 e = NULL; /* fall down to UFCS */
2424 else
2425 {
2426 result = e;
2427 return;
2428 }
2429 }
2430 if (!e) // if failed to find the property
2431 {
2432 /* If ident is not a valid property, rewrite:
2433 * e1.ident
2434 * as:
2435 * .ident(e1)
2436 */
2437 e = resolveUFCSProperties(sc, exp);
2438 }
2439 result = e;
2440 }
2441
visit(DotTemplateExp * e)2442 void visit(DotTemplateExp *e)
2443 {
2444 if (Expression *ex = unaSemantic(e, sc))
2445 {
2446 result = ex;
2447 return;
2448 }
2449 result = e;
2450 }
2451
visit(DotVarExp * exp)2452 void visit(DotVarExp *exp)
2453 {
2454 if (exp->type)
2455 {
2456 result = exp;
2457 return;
2458 }
2459
2460 exp->var = exp->var->toAlias()->isDeclaration();
2461
2462 exp->e1 = semantic(exp->e1, sc);
2463
2464 if (TupleDeclaration *tup = exp->var->isTupleDeclaration())
2465 {
2466 /* Replace:
2467 * e1.tuple(a, b, c)
2468 * with:
2469 * tuple(e1.a, e1.b, e1.c)
2470 */
2471 Expression *e0 = NULL;
2472 Expression *ev = sc->func ? extractSideEffect(sc, "__tup", &e0, exp->e1) : exp->e1;
2473
2474 Expressions *exps = new Expressions;
2475 exps->reserve(tup->objects->dim);
2476 for (size_t i = 0; i < tup->objects->dim; i++)
2477 {
2478 RootObject *o = (*tup->objects)[i];
2479 Expression *e;
2480 if (o->dyncast() == DYNCAST_EXPRESSION)
2481 {
2482 e = (Expression *)o;
2483 if (e->op == TOKdsymbol)
2484 {
2485 Dsymbol *s = ((DsymbolExp *)e)->s;
2486 e = new DotVarExp(exp->loc, ev, s->isDeclaration());
2487 }
2488 }
2489 else if (o->dyncast() == DYNCAST_DSYMBOL)
2490 {
2491 e = new DsymbolExp(exp->loc, (Dsymbol *)o);
2492 }
2493 else if (o->dyncast() == DYNCAST_TYPE)
2494 {
2495 e = new TypeExp(exp->loc, (Type *)o);
2496 }
2497 else
2498 {
2499 exp->error("%s is not an expression", o->toChars());
2500 return setError();
2501 }
2502 exps->push(e);
2503 }
2504
2505 Expression *e = new TupleExp(exp->loc, e0, exps);
2506 e = semantic(e, sc);
2507 result = e;
2508 return;
2509 }
2510
2511 exp->e1 = exp->e1->addDtorHook(sc);
2512
2513 Type *t1 = exp->e1->type;
2514
2515 if (FuncDeclaration *fd = exp->var->isFuncDeclaration())
2516 {
2517 // for functions, do checks after overload resolution
2518 if (!fd->functionSemantic())
2519 return setError();
2520
2521 /* Bugzilla 13843: If fd obviously has no overloads, we should
2522 * normalize AST, and it will give a chance to wrap fd with FuncExp.
2523 */
2524 if (fd->isNested() || fd->isFuncLiteralDeclaration())
2525 {
2526 // (e1, fd)
2527 Expression *e = resolve(exp->loc, sc, fd, false);
2528 result = Expression::combine(exp->e1, e);
2529 return;
2530 }
2531
2532 exp->type = fd->type;
2533 assert(exp->type);
2534 }
2535 else if (exp->var->isOverDeclaration())
2536 {
2537 exp->type = Type::tvoid; // ambiguous type?
2538 }
2539 else
2540 {
2541 exp->type = exp->var->type;
2542 if (!exp->type && global.errors)
2543 {
2544 // var is goofed up, just return 0
2545 return setError();
2546 }
2547 assert(exp->type);
2548
2549 if (t1->ty == Tpointer)
2550 t1 = t1->nextOf();
2551
2552 exp->type = exp->type->addMod(t1->mod);
2553
2554 Dsymbol *vparent = exp->var->toParent();
2555 AggregateDeclaration *ad = vparent ? vparent->isAggregateDeclaration() : NULL;
2556
2557 if (Expression *e1x = getRightThis(exp->loc, sc, ad, exp->e1, exp->var, 1))
2558 exp->e1 = e1x;
2559 else
2560 {
2561 /* Later checkRightThis will report correct error for invalid field variable access.
2562 */
2563 Expression *e = new VarExp(exp->loc, exp->var);
2564 e = semantic(e, sc);
2565 result = e;
2566 return;
2567 }
2568 checkAccess(exp->loc, sc, exp->e1, exp->var);
2569
2570 VarDeclaration *v = exp->var->isVarDeclaration();
2571 if (v && (v->isDataseg() || (v->storage_class & STCmanifest)))
2572 {
2573 Expression *e = expandVar(WANTvalue, v);
2574 if (e)
2575 {
2576 result = e;
2577 return;
2578 }
2579 }
2580
2581 if (v && v->isDataseg()) // fix bugzilla 8238
2582 {
2583 // (e1, v)
2584 checkAccess(exp->loc, sc, exp->e1, v);
2585 Expression *e = new VarExp(exp->loc, v);
2586 e = new CommaExp(exp->loc, exp->e1, e);
2587 e = semantic(e, sc);
2588 result = e;
2589 return;
2590 }
2591 }
2592
2593 //printf("-DotVarExp::semantic('%s')\n", exp->toChars());
2594 result = exp;
2595 }
2596
visit(DotTemplateInstanceExp * exp)2597 void visit(DotTemplateInstanceExp *exp)
2598 {
2599 // Indicate we need to resolve by UFCS.
2600 Expression *e = semanticY(exp, sc, 1);
2601 if (!e)
2602 e = resolveUFCSProperties(sc, exp);
2603 result = e;
2604 }
2605
visit(DelegateExp * e)2606 void visit(DelegateExp *e)
2607 {
2608 if (e->type)
2609 {
2610 result = e;
2611 return;
2612 }
2613
2614 e->e1 = semantic(e->e1, sc);
2615 e->type = new TypeDelegate(e->func->type);
2616 e->type = e->type->semantic(e->loc, sc);
2617 FuncDeclaration *f = e->func->toAliasFunc();
2618 AggregateDeclaration *ad = f->toParent()->isAggregateDeclaration();
2619 if (f->needThis())
2620 e->e1 = getRightThis(e->loc, sc, ad, e->e1, f);
2621 if (f->type->ty == Tfunction)
2622 {
2623 TypeFunction *tf = (TypeFunction *)f->type;
2624 if (!MODmethodConv(e->e1->type->mod, f->type->mod))
2625 {
2626 OutBuffer thisBuf, funcBuf;
2627 MODMatchToBuffer(&thisBuf, e->e1->type->mod, tf->mod);
2628 MODMatchToBuffer(&funcBuf, tf->mod, e->e1->type->mod);
2629 e->error("%smethod %s is not callable using a %s%s",
2630 funcBuf.peekString(), f->toPrettyChars(), thisBuf.peekString(), e->e1->toChars());
2631 return setError();
2632 }
2633 }
2634 if (ad && ad->isClassDeclaration() && ad->type != e->e1->type)
2635 {
2636 // A downcast is required for interfaces, see Bugzilla 3706
2637 e->e1 = new CastExp(e->loc, e->e1, ad->type);
2638 e->e1 = semantic(e->e1, sc);
2639 }
2640 result = e;
2641 }
2642
visit(DotTypeExp * exp)2643 void visit(DotTypeExp *exp)
2644 {
2645 if (exp->type)
2646 {
2647 result = exp;
2648 return;
2649 }
2650
2651 if (Expression *e = unaSemantic(exp, sc))
2652 {
2653 result = e;
2654 return;
2655 }
2656
2657 exp->type = exp->sym->getType()->addMod(exp->e1->type->mod);
2658 result = exp;
2659 }
2660
visit(CallExp * exp)2661 void visit(CallExp *exp)
2662 {
2663 if (exp->type)
2664 {
2665 result = exp; // semantic() already run
2666 return;
2667 }
2668
2669 Type *t1;
2670 Objects *tiargs = NULL; // initial list of template arguments
2671 Expression *ethis = NULL;
2672 Type *tthis = NULL;
2673 Expression *e1org = exp->e1;
2674
2675 if (exp->e1->op == TOKcomma)
2676 {
2677 /* Rewrite (a,b)(args) as (a,(b(args)))
2678 */
2679 CommaExp *ce = (CommaExp *)exp->e1;
2680 exp->e1 = ce->e2;
2681 ce->e2 = exp;
2682 result = semantic(ce, sc);
2683 return;
2684 }
2685
2686 if (exp->e1->op == TOKdelegate)
2687 {
2688 DelegateExp *de = (DelegateExp *)exp->e1;
2689 exp->e1 = new DotVarExp(de->loc, de->e1, de->func, de->hasOverloads);
2690 result = semantic(exp, sc);
2691 return;
2692 }
2693
2694 if (exp->e1->op == TOKfunction)
2695 {
2696 if (arrayExpressionSemantic(exp->arguments, sc) ||
2697 preFunctionParameters(sc, exp->arguments))
2698 {
2699 return setError();
2700 }
2701
2702 // Run e1 semantic even if arguments have any errors
2703 FuncExp *fe = (FuncExp *)exp->e1;
2704 exp->e1 = callExpSemantic(fe, sc, exp->arguments);
2705 if (exp->e1->op == TOKerror)
2706 {
2707 result = exp->e1;
2708 return;
2709 }
2710 }
2711
2712 if (Expression *ex = resolveUFCS(sc, exp))
2713 {
2714 result = ex;
2715 return;
2716 }
2717
2718 /* This recognizes:
2719 * foo!(tiargs)(funcargs)
2720 */
2721 if (exp->e1->op == TOKscope)
2722 {
2723 ScopeExp *se = (ScopeExp *)exp->e1;
2724 TemplateInstance *ti = se->sds->isTemplateInstance();
2725 if (ti)
2726 {
2727 /* Attempt to instantiate ti. If that works, go with it.
2728 * If not, go with partial explicit specialization.
2729 */
2730 WithScopeSymbol *withsym;
2731 if (!ti->findTempDecl(sc, &withsym) ||
2732 !ti->semanticTiargs(sc))
2733 {
2734 return setError();
2735 }
2736 if (withsym && withsym->withstate->wthis)
2737 {
2738 exp->e1 = new VarExp(exp->e1->loc, withsym->withstate->wthis);
2739 exp->e1 = new DotTemplateInstanceExp(exp->e1->loc, exp->e1, ti);
2740 goto Ldotti;
2741 }
2742 if (ti->needsTypeInference(sc, 1))
2743 {
2744 /* Go with partial explicit specialization
2745 */
2746 tiargs = ti->tiargs;
2747 assert(ti->tempdecl);
2748 if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration())
2749 exp->e1 = new TemplateExp(exp->loc, td);
2750 else if (OverDeclaration *od = ti->tempdecl->isOverDeclaration())
2751 exp->e1 = new VarExp(exp->loc, od);
2752 else
2753 exp->e1 = new OverExp(exp->loc, ti->tempdecl->isOverloadSet());
2754 }
2755 else
2756 {
2757 Expression *e1x = semantic(exp->e1, sc);
2758 if (e1x->op == TOKerror)
2759 {
2760 result = e1x;
2761 return;
2762 }
2763 exp->e1 = e1x;
2764 }
2765 }
2766 }
2767
2768 /* This recognizes:
2769 * expr.foo!(tiargs)(funcargs)
2770 */
2771 Ldotti:
2772 if (exp->e1->op == TOKdotti && !exp->e1->type)
2773 {
2774 DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)exp->e1;
2775 TemplateInstance *ti = se->ti;
2776 {
2777 /* Attempt to instantiate ti. If that works, go with it.
2778 * If not, go with partial explicit specialization.
2779 */
2780 if (!se->findTempDecl(sc) ||
2781 !ti->semanticTiargs(sc))
2782 {
2783 return setError();
2784 }
2785 if (ti->needsTypeInference(sc, 1))
2786 {
2787 /* Go with partial explicit specialization
2788 */
2789 tiargs = ti->tiargs;
2790 assert(ti->tempdecl);
2791 if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration())
2792 exp->e1 = new DotTemplateExp(exp->loc, se->e1, td);
2793 else if (OverDeclaration *od = ti->tempdecl->isOverDeclaration())
2794 {
2795 exp->e1 = new DotVarExp(exp->loc, se->e1, od, true);
2796 }
2797 else
2798 exp->e1 = new DotExp(exp->loc, se->e1, new OverExp(exp->loc, ti->tempdecl->isOverloadSet()));
2799 }
2800 else
2801 {
2802 Expression *e1x = semantic(exp->e1, sc);
2803 if (e1x->op == TOKerror)
2804 {
2805 result =e1x;
2806 return;
2807 }
2808 exp->e1 = e1x;
2809 }
2810 }
2811 }
2812
2813 Lagain:
2814 //printf("Lagain: %s\n", exp->toChars());
2815 exp->f = NULL;
2816 if (exp->e1->op == TOKthis || exp->e1->op == TOKsuper)
2817 {
2818 // semantic() run later for these
2819 }
2820 else
2821 {
2822 if (exp->e1->op == TOKdotid)
2823 {
2824 DotIdExp *die = (DotIdExp *)exp->e1;
2825 exp->e1 = semantic(die, sc);
2826 /* Look for e1 having been rewritten to expr.opDispatch!(string)
2827 * We handle such earlier, so go back.
2828 * Note that in the rewrite, we carefully did not run semantic() on e1
2829 */
2830 if (exp->e1->op == TOKdotti && !exp->e1->type)
2831 {
2832 goto Ldotti;
2833 }
2834 }
2835 else
2836 {
2837 static int nest;
2838 if (++nest > 500)
2839 {
2840 exp->error("recursive evaluation of %s", exp->toChars());
2841 --nest;
2842 return setError();
2843 }
2844 Expression *ex = unaSemantic(exp, sc);
2845 --nest;
2846 if (ex)
2847 {
2848 result = ex;
2849 return;
2850 }
2851 }
2852
2853 /* Look for e1 being a lazy parameter
2854 */
2855 if (exp->e1->op == TOKvar)
2856 {
2857 VarExp *ve = (VarExp *)exp->e1;
2858 if (ve->var->storage_class & STClazy)
2859 {
2860 // lazy paramaters can be called without violating purity and safety
2861 Type *tw = ve->var->type;
2862 Type *tc = ve->var->type->substWildTo(MODconst);
2863 TypeFunction *tf = new TypeFunction(NULL, tc, 0, LINKd, STCsafe | STCpure);
2864 (tf = (TypeFunction *)tf->semantic(exp->loc, sc))->next = tw; // hack for bug7757
2865 TypeDelegate *t = new TypeDelegate(tf);
2866 ve->type = t->semantic(exp->loc, sc);
2867 }
2868 VarDeclaration *v = ve->var->isVarDeclaration();
2869 if (v && ve->checkPurity(sc, v))
2870 return setError();
2871 }
2872
2873 if (exp->e1->op == TOKsymoff && ((SymOffExp *)exp->e1)->hasOverloads)
2874 {
2875 SymOffExp *se = (SymOffExp *)exp->e1;
2876 exp->e1 = new VarExp(se->loc, se->var, true);
2877 exp->e1 = semantic(exp->e1, sc);
2878 }
2879 else if (exp->e1->op == TOKdot)
2880 {
2881 DotExp *de = (DotExp *) exp->e1;
2882
2883 if (de->e2->op == TOKoverloadset)
2884 {
2885 ethis = de->e1;
2886 tthis = de->e1->type;
2887 exp->e1 = de->e2;
2888 }
2889 }
2890 else if (exp->e1->op == TOKstar && exp->e1->type->ty == Tfunction)
2891 {
2892 // Rewrite (*fp)(arguments) to fp(arguments)
2893 exp->e1 = ((PtrExp *)exp->e1)->e1;
2894 }
2895 }
2896
2897 t1 = exp->e1->type ? exp->e1->type->toBasetype() : NULL;
2898
2899 if (exp->e1->op == TOKerror)
2900 {
2901 result = exp->e1;
2902 return;
2903 }
2904 if (arrayExpressionSemantic(exp->arguments, sc) ||
2905 preFunctionParameters(sc, exp->arguments))
2906 {
2907 return setError();
2908 }
2909
2910 // Check for call operator overload
2911 if (t1)
2912 {
2913 if (t1->ty == Tstruct)
2914 {
2915 StructDeclaration *sd = ((TypeStruct *)t1)->sym;
2916 sd->size(exp->loc); // Resolve forward references to construct object
2917 if (sd->sizeok != SIZEOKdone)
2918 return setError();
2919 if (!sd->ctor)
2920 sd->ctor = sd->searchCtor();
2921
2922 // First look for constructor
2923 if (exp->e1->op == TOKtype && sd->ctor)
2924 {
2925 if (!sd->noDefaultCtor && !(exp->arguments && exp->arguments->dim))
2926 goto Lx;
2927
2928 StructLiteralExp *sle = new StructLiteralExp(exp->loc, sd, NULL, exp->e1->type);
2929 if (!sd->fill(exp->loc, sle->elements, true))
2930 return setError();
2931 if (checkFrameAccess(exp->loc, sc, sd, sle->elements->dim))
2932 return setError();
2933 // Bugzilla 14556: Set concrete type to avoid further redundant semantic().
2934 sle->type = exp->e1->type;
2935
2936 /* Constructor takes a mutable object, so don't use
2937 * the immutable initializer symbol.
2938 */
2939 sle->useStaticInit = false;
2940
2941 Expression *e = sle;
2942 if (CtorDeclaration *cf = sd->ctor->isCtorDeclaration())
2943 {
2944 e = new DotVarExp(exp->loc, e, cf, true);
2945 }
2946 else if (TemplateDeclaration *td = sd->ctor->isTemplateDeclaration())
2947 {
2948 e = new DotTemplateExp(exp->loc, e, td);
2949 }
2950 else if (OverloadSet *os = sd->ctor->isOverloadSet())
2951 {
2952 e = new DotExp(exp->loc, e, new OverExp(exp->loc, os));
2953 }
2954 else
2955 assert(0);
2956 e = new CallExp(exp->loc, e, exp->arguments);
2957 result = semantic(e, sc);
2958 return;
2959 }
2960 // No constructor, look for overload of opCall
2961 if (search_function(sd, Id::call))
2962 goto L1; // overload of opCall, therefore it's a call
2963
2964 if (exp->e1->op != TOKtype)
2965 {
2966 if (sd->aliasthis && exp->e1->type != exp->att1)
2967 {
2968 if (!exp->att1 && exp->e1->type->checkAliasThisRec())
2969 exp->att1 = exp->e1->type;
2970 exp->e1 = resolveAliasThis(sc, exp->e1);
2971 goto Lagain;
2972 }
2973 exp->error("%s %s does not overload ()", sd->kind(), sd->toChars());
2974 return setError();
2975 }
2976
2977 /* It's a struct literal
2978 */
2979 Lx:
2980 Expression *e = new StructLiteralExp(exp->loc, sd, exp->arguments, exp->e1->type);
2981 result = semantic(e, sc);
2982 return;
2983 }
2984 else if (t1->ty == Tclass)
2985 {
2986 L1:
2987 // Rewrite as e1.call(arguments)
2988 Expression *e = new DotIdExp(exp->loc, exp->e1, Id::call);
2989 e = new CallExp(exp->loc, e, exp->arguments);
2990 result = semantic(e, sc);
2991 return;
2992 }
2993 else if (exp->e1->op == TOKtype && t1->isscalar())
2994 {
2995 Expression *e;
2996
2997 // Make sure to use the the enum type itself rather than its
2998 // base type (see bugzilla 16346)
2999 if (exp->e1->type->ty == Tenum)
3000 {
3001 t1 = exp->e1->type;
3002 }
3003
3004 if (!exp->arguments || exp->arguments->dim == 0)
3005 {
3006 e = t1->defaultInitLiteral(exp->loc);
3007 }
3008 else if (exp->arguments->dim == 1)
3009 {
3010 e = (*exp->arguments)[0];
3011 e = e->implicitCastTo(sc, t1);
3012 e = new CastExp(exp->loc, e, t1);
3013 }
3014 else
3015 {
3016 exp->error("more than one argument for construction of %s", t1->toChars());
3017 e = new ErrorExp();
3018 }
3019 result = semantic(e, sc);
3020 return;
3021 }
3022 }
3023
3024 if ((exp->e1->op == TOKdotvar && t1->ty == Tfunction) ||
3025 exp->e1->op == TOKdottd)
3026 {
3027 UnaExp *ue = (UnaExp *)(exp->e1);
3028
3029 Expression *ue1 = ue->e1;
3030 Expression *ue1old = ue1; // need for 'right this' check
3031 VarDeclaration *v;
3032 if (ue1->op == TOKvar &&
3033 (v = ((VarExp *)ue1)->var->isVarDeclaration()) != NULL &&
3034 v->needThis())
3035 {
3036 ue->e1 = new TypeExp(ue1->loc, ue1->type);
3037 ue1 = NULL;
3038 }
3039
3040 DotVarExp *dve;
3041 DotTemplateExp *dte;
3042 Dsymbol *s;
3043 if (exp->e1->op == TOKdotvar)
3044 {
3045 dve = (DotVarExp *)(exp->e1);
3046 dte = NULL;
3047 s = dve->var;
3048 tiargs = NULL;
3049 }
3050 else
3051 {
3052 dve = NULL;
3053 dte = (DotTemplateExp *)(exp->e1);
3054 s = dte->td;
3055 }
3056
3057 // Do overload resolution
3058 exp->f = resolveFuncCall(exp->loc, sc, s, tiargs, ue1 ? ue1->type : NULL, exp->arguments);
3059 if (!exp->f || exp->f->errors || exp->f->type->ty == Terror)
3060 return setError();
3061 if (exp->f->interfaceVirtual)
3062 {
3063 /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent
3064 */
3065 BaseClass *b = exp->f->interfaceVirtual;
3066 ClassDeclaration *ad2 = b->sym;
3067 ue->e1 = ue->e1->castTo(sc, ad2->type->addMod(ue->e1->type->mod));
3068 ue->e1 = semantic(ue->e1, sc);
3069 ue1 = ue->e1;
3070 int vi = exp->f->findVtblIndex((Dsymbols*)&ad2->vtbl, (int)ad2->vtbl.dim);
3071 assert(vi >= 0);
3072 exp->f = ad2->vtbl[vi]->isFuncDeclaration();
3073 assert(exp->f);
3074 }
3075 if (exp->f->needThis())
3076 {
3077 AggregateDeclaration *ad = exp->f->toParent2()->isAggregateDeclaration();
3078 ue->e1 = getRightThis(exp->loc, sc, ad, ue->e1, exp->f);
3079 if (ue->e1->op == TOKerror)
3080 {
3081 result = ue->e1;
3082 return;
3083 }
3084 ethis = ue->e1;
3085 tthis = ue->e1->type;
3086 if (!(exp->f->type->ty == Tfunction && ((TypeFunction *)exp->f->type)->isscope))
3087 {
3088 if (global.params.vsafe && checkParamArgumentEscape(sc, exp->f, Id::This, ethis, false))
3089 return setError();
3090 }
3091 }
3092
3093 /* Cannot call public functions from inside invariant
3094 * (because then the invariant would have infinite recursion)
3095 */
3096 if (sc->func && sc->func->isInvariantDeclaration() &&
3097 ue->e1->op == TOKthis &&
3098 exp->f->addPostInvariant()
3099 )
3100 {
3101 exp->error("cannot call public/export function %s from invariant", exp->f->toChars());
3102 return setError();
3103 }
3104
3105 exp->checkDeprecated(sc, exp->f);
3106 exp->checkPurity(sc, exp->f);
3107 exp->checkSafety(sc, exp->f);
3108 exp->checkNogc(sc, exp->f);
3109 checkAccess(exp->loc, sc, ue->e1, exp->f);
3110 if (!exp->f->needThis())
3111 {
3112 exp->e1 = Expression::combine(ue->e1, new VarExp(exp->loc, exp->f, false));
3113 }
3114 else
3115 {
3116 if (ue1old->checkRightThis(sc))
3117 return setError();
3118 if (exp->e1->op == TOKdotvar)
3119 {
3120 dve->var = exp->f;
3121 exp->e1->type = exp->f->type;
3122 }
3123 else
3124 {
3125 exp->e1 = new DotVarExp(exp->loc, dte->e1, exp->f, false);
3126 exp->e1 = semantic(exp->e1, sc);
3127 if (exp->e1->op == TOKerror)
3128 return setError();
3129 ue = (UnaExp *)exp->e1;
3130 }
3131
3132 // See if we need to adjust the 'this' pointer
3133 AggregateDeclaration *ad = exp->f->isThis();
3134 ClassDeclaration *cd = ue->e1->type->isClassHandle();
3135 if (ad && cd && ad->isClassDeclaration())
3136 {
3137 if (ue->e1->op == TOKdottype)
3138 {
3139 ue->e1 = ((DotTypeExp *)ue->e1)->e1;
3140 exp->directcall = true;
3141 }
3142 else if (ue->e1->op == TOKsuper)
3143 exp->directcall = true;
3144 else if ((cd->storage_class & STCfinal) != 0) // Bugzilla 14211
3145 exp->directcall = true;
3146
3147 if (ad != cd)
3148 {
3149 ue->e1 = ue->e1->castTo(sc, ad->type->addMod(ue->e1->type->mod));
3150 ue->e1 = semantic(ue->e1, sc);
3151 }
3152 }
3153 }
3154 // If we've got a pointer to a function then deference it
3155 // https://issues.dlang.org/show_bug.cgi?id=16483
3156 if (exp->e1->type->ty == Tpointer && exp->e1->type->nextOf()->ty == Tfunction)
3157 {
3158 Expression *e = new PtrExp(exp->loc, exp->e1);
3159 e->type = exp->e1->type->nextOf();
3160 exp->e1 = e;
3161 }
3162 t1 = exp->e1->type;
3163 }
3164 else if (exp->e1->op == TOKsuper)
3165 {
3166 // Base class constructor call
3167 AggregateDeclaration *ad = sc->func ? sc->func->isThis() : NULL;
3168 ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
3169 if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration())
3170 {
3171 exp->error("super class constructor call must be in a constructor");
3172 return setError();
3173 }
3174 if (!cd->baseClass->ctor)
3175 {
3176 exp->error("no super class constructor for %s", cd->baseClass->toChars());
3177 return setError();
3178 }
3179
3180 if (!sc->intypeof && !(sc->callSuper & CSXhalt))
3181 {
3182 if (sc->noctor || sc->callSuper & CSXlabel)
3183 exp->error("constructor calls not allowed in loops or after labels");
3184 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
3185 exp->error("multiple constructor calls");
3186 if ((sc->callSuper & CSXreturn) && !(sc->callSuper & CSXany_ctor))
3187 exp->error("an earlier return statement skips constructor");
3188 sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
3189 }
3190
3191 tthis = cd->type->addMod(sc->func->type->mod);
3192 if (OverloadSet *os = cd->baseClass->ctor->isOverloadSet())
3193 exp->f = resolveOverloadSet(exp->loc, sc, os, NULL, tthis, exp->arguments);
3194 else
3195 exp->f = resolveFuncCall(exp->loc, sc, cd->baseClass->ctor, NULL, tthis, exp->arguments, 0);
3196 if (!exp->f || exp->f->errors)
3197 return setError();
3198 exp->checkDeprecated(sc, exp->f);
3199 exp->checkPurity(sc, exp->f);
3200 exp->checkSafety(sc, exp->f);
3201 exp->checkNogc(sc, exp->f);
3202 checkAccess(exp->loc, sc, NULL, exp->f);
3203
3204 exp->e1 = new DotVarExp(exp->e1->loc, exp->e1, exp->f, false);
3205 exp->e1 = semantic(exp->e1, sc);
3206 t1 = exp->e1->type;
3207 }
3208 else if (exp->e1->op == TOKthis)
3209 {
3210 // same class constructor call
3211 AggregateDeclaration *ad = sc->func ? sc->func->isThis() : NULL;
3212 if (!ad || !sc->func->isCtorDeclaration())
3213 {
3214 exp->error("constructor call must be in a constructor");
3215 return setError();
3216 }
3217
3218 if (!sc->intypeof && !(sc->callSuper & CSXhalt))
3219 {
3220 if (sc->noctor || sc->callSuper & CSXlabel)
3221 exp->error("constructor calls not allowed in loops or after labels");
3222 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
3223 exp->error("multiple constructor calls");
3224 if ((sc->callSuper & CSXreturn) && !(sc->callSuper & CSXany_ctor))
3225 exp->error("an earlier return statement skips constructor");
3226 sc->callSuper |= CSXany_ctor | CSXthis_ctor;
3227 }
3228
3229 tthis = ad->type->addMod(sc->func->type->mod);
3230 if (OverloadSet *os = ad->ctor->isOverloadSet())
3231 exp->f = resolveOverloadSet(exp->loc, sc, os, NULL, tthis, exp->arguments);
3232 else
3233 exp->f = resolveFuncCall(exp->loc, sc, ad->ctor, NULL, tthis, exp->arguments, 0);
3234 if (!exp->f || exp->f->errors)
3235 return setError();
3236 exp->checkDeprecated(sc, exp->f);
3237 exp->checkPurity(sc, exp->f);
3238 exp->checkSafety(sc, exp->f);
3239 exp->checkNogc(sc, exp->f);
3240 //checkAccess(exp->loc, sc, NULL, exp->f); // necessary?
3241
3242 exp->e1 = new DotVarExp(exp->e1->loc, exp->e1, exp->f, false);
3243 exp->e1 = semantic(exp->e1, sc);
3244 t1 = exp->e1->type;
3245
3246 // BUG: this should really be done by checking the static
3247 // call graph
3248 if (exp->f == sc->func)
3249 {
3250 exp->error("cyclic constructor call");
3251 return setError();
3252 }
3253 }
3254 else if (exp->e1->op == TOKoverloadset)
3255 {
3256 OverloadSet *os = ((OverExp *)exp->e1)->vars;
3257 exp->f = resolveOverloadSet(exp->loc, sc, os, tiargs, tthis, exp->arguments);
3258 if (!exp->f)
3259 return setError();
3260 if (ethis)
3261 exp->e1 = new DotVarExp(exp->loc, ethis, exp->f, false);
3262 else
3263 exp->e1 = new VarExp(exp->loc, exp->f, false);
3264 goto Lagain;
3265 }
3266 else if (!t1)
3267 {
3268 exp->error("function expected before (), not '%s'", exp->e1->toChars());
3269 return setError();
3270 }
3271 else if (t1->ty == Terror)
3272 {
3273 return setError();
3274 }
3275 else if (t1->ty != Tfunction)
3276 {
3277 TypeFunction *tf;
3278 const char *p;
3279 Dsymbol *s;
3280 exp->f = NULL;
3281 if (exp->e1->op == TOKfunction)
3282 {
3283 // function literal that direct called is always inferred.
3284 assert(((FuncExp *)exp->e1)->fd);
3285 exp->f = ((FuncExp *)exp->e1)->fd;
3286 tf = (TypeFunction *)exp->f->type;
3287 p = "function literal";
3288 }
3289 else if (t1->ty == Tdelegate)
3290 {
3291 TypeDelegate *td = (TypeDelegate *)t1;
3292 assert(td->next->ty == Tfunction);
3293 tf = (TypeFunction *)(td->next);
3294 p = "delegate";
3295 }
3296 else if (t1->ty == Tpointer && ((TypePointer *)t1)->next->ty == Tfunction)
3297 {
3298 tf = (TypeFunction *)(((TypePointer *)t1)->next);
3299 p = "function pointer";
3300 }
3301 else if (exp->e1->op == TOKdotvar &&
3302 ((DotVarExp *)exp->e1)->var->isOverDeclaration())
3303 {
3304 DotVarExp *dve = (DotVarExp *)exp->e1;
3305 exp->f = resolveFuncCall(exp->loc, sc, dve->var, tiargs, dve->e1->type, exp->arguments, 2);
3306 if (!exp->f)
3307 return setError();
3308 if (exp->f->needThis())
3309 {
3310 dve->var = exp->f;
3311 dve->type = exp->f->type;
3312 dve->hasOverloads = false;
3313 goto Lagain;
3314 }
3315 exp->e1 = new VarExp(dve->loc, exp->f, false);
3316 Expression *e = new CommaExp(exp->loc, dve->e1, exp);
3317 result = semantic(e, sc);
3318 return;
3319 }
3320 else if (exp->e1->op == TOKvar &&
3321 ((VarExp *)exp->e1)->var->isOverDeclaration())
3322 {
3323 s = ((VarExp *)exp->e1)->var;
3324 goto L2;
3325 }
3326 else if (exp->e1->op == TOKtemplate)
3327 {
3328 s = ((TemplateExp *)exp->e1)->td;
3329 L2:
3330 exp->f = resolveFuncCall(exp->loc, sc, s, tiargs, NULL, exp->arguments);
3331 if (!exp->f || exp->f->errors)
3332 return setError();
3333 if (exp->f->needThis())
3334 {
3335 if (hasThis(sc))
3336 {
3337 // Supply an implicit 'this', as in
3338 // this.ident
3339 Expression *ex = new ThisExp(exp->loc);
3340 ex = semantic(ex, sc);
3341 exp->e1 = new DotVarExp(exp->loc, ex, exp->f, false);
3342 goto Lagain;
3343 }
3344 else if (isNeedThisScope(sc, exp->f))
3345 {
3346 exp->error("need 'this' for '%s' of type '%s'", exp->f->toChars(), exp->f->type->toChars());
3347 return setError();
3348 }
3349 }
3350 exp->e1 = new VarExp(exp->e1->loc, exp->f, false);
3351 goto Lagain;
3352 }
3353 else
3354 {
3355 exp->error("function expected before (), not %s of type %s", exp->e1->toChars(), exp->e1->type->toChars());
3356 return setError();
3357 }
3358
3359 if (!tf->callMatch(NULL, exp->arguments))
3360 {
3361 OutBuffer buf;
3362
3363 buf.writeByte('(');
3364 argExpTypesToCBuffer(&buf, exp->arguments);
3365 buf.writeByte(')');
3366 if (tthis)
3367 tthis->modToBuffer(&buf);
3368
3369 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3370 ::error(exp->loc, "%s %s %s is not callable using argument types %s",
3371 p, exp->e1->toChars(), parametersTypeToChars(tf->parameters, tf->varargs),
3372 buf.peekString());
3373
3374 return setError();
3375 }
3376
3377 // Purity and safety check should run after testing arguments matching
3378 if (exp->f)
3379 {
3380 exp->checkPurity(sc, exp->f);
3381 exp->checkSafety(sc, exp->f);
3382 exp->checkNogc(sc, exp->f);
3383 if (exp->f->checkNestedReference(sc, exp->loc))
3384 return setError();
3385 }
3386 else if (sc->func && sc->intypeof != 1 && !(sc->flags & SCOPEctfe))
3387 {
3388 bool err = false;
3389 if (!tf->purity && !(sc->flags & SCOPEdebug) && sc->func->setImpure())
3390 {
3391 exp->error("pure %s '%s' cannot call impure %s '%s'",
3392 sc->func->kind(), sc->func->toPrettyChars(), p, exp->e1->toChars());
3393 err = true;
3394 }
3395 if (!tf->isnogc && sc->func->setGC())
3396 {
3397 exp->error("@nogc %s '%s' cannot call non-@nogc %s '%s'",
3398 sc->func->kind(), sc->func->toPrettyChars(), p, exp->e1->toChars());
3399 err = true;
3400 }
3401 if (tf->trust <= TRUSTsystem && sc->func->setUnsafe())
3402 {
3403 exp->error("@safe %s '%s' cannot call @system %s '%s'",
3404 sc->func->kind(), sc->func->toPrettyChars(), p, exp->e1->toChars());
3405 err = true;
3406 }
3407 if (err)
3408 return setError();
3409 }
3410
3411 if (t1->ty == Tpointer)
3412 {
3413 Expression *e = new PtrExp(exp->loc, exp->e1);
3414 e->type = tf;
3415 exp->e1 = e;
3416 }
3417 t1 = tf;
3418 }
3419 else if (exp->e1->op == TOKvar)
3420 {
3421 // Do overload resolution
3422 VarExp *ve = (VarExp *)exp->e1;
3423
3424 exp->f = ve->var->isFuncDeclaration();
3425 assert(exp->f);
3426 tiargs = NULL;
3427
3428 if (ve->hasOverloads)
3429 exp->f = resolveFuncCall(exp->loc, sc, exp->f, tiargs, NULL, exp->arguments, 2);
3430 else
3431 {
3432 exp->f = exp->f->toAliasFunc();
3433 TypeFunction *tf = (TypeFunction *)exp->f->type;
3434 if (!tf->callMatch(NULL, exp->arguments))
3435 {
3436 OutBuffer buf;
3437
3438 buf.writeByte('(');
3439 argExpTypesToCBuffer(&buf, exp->arguments);
3440 buf.writeByte(')');
3441
3442 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3443 ::error(exp->loc, "%s %s is not callable using argument types %s",
3444 exp->e1->toChars(), parametersTypeToChars(tf->parameters, tf->varargs),
3445 buf.peekString());
3446
3447 exp->f = NULL;
3448 }
3449 }
3450 if (!exp->f || exp->f->errors)
3451 return setError();
3452
3453 if (exp->f->needThis())
3454 {
3455 // Change the ancestor lambdas to delegate before hasThis(sc) call.
3456 if (exp->f->checkNestedReference(sc, exp->loc))
3457 return setError();
3458
3459 if (hasThis(sc))
3460 {
3461 // Supply an implicit 'this', as in
3462 // this.ident
3463
3464 Expression *ex = new ThisExp(exp->loc);
3465 ex = semantic(ex, sc);
3466 exp->e1 = new DotVarExp(exp->loc, ex, ve->var);
3467 // Note: we cannot use f directly, because further overload resolution
3468 // through the supplied 'this' may cause different result.
3469 goto Lagain;
3470 }
3471 else if (isNeedThisScope(sc, exp->f))
3472 {
3473 exp->error("need 'this' for '%s' of type '%s'", exp->f->toChars(), exp->f->type->toChars());
3474 return setError();
3475 }
3476 }
3477
3478 exp->checkDeprecated(sc, exp->f);
3479 exp->checkPurity(sc, exp->f);
3480 exp->checkSafety(sc, exp->f);
3481 exp->checkNogc(sc, exp->f);
3482 checkAccess(exp->loc, sc, NULL, exp->f);
3483 if (exp->f->checkNestedReference(sc, exp->loc))
3484 return setError();
3485
3486 ethis = NULL;
3487 tthis = NULL;
3488
3489 if (ve->hasOverloads)
3490 {
3491 exp->e1 = new VarExp(ve->loc, exp->f, false);
3492 exp->e1->type = exp->f->type;
3493 }
3494 t1 = exp->f->type;
3495 }
3496 assert(t1->ty == Tfunction);
3497
3498 Expression *argprefix;
3499 if (!exp->arguments)
3500 exp->arguments = new Expressions();
3501 if (functionParameters(exp->loc, sc, (TypeFunction *)(t1), tthis, exp->arguments, exp->f, &exp->type, &argprefix))
3502 return setError();
3503
3504 if (!exp->type)
3505 {
3506 exp->e1 = e1org; // Bugzilla 10922, avoid recursive expression printing
3507 exp->error("forward reference to inferred return type of function call '%s'", exp->toChars());
3508 return setError();
3509 }
3510
3511 if (exp->f && exp->f->tintro)
3512 {
3513 Type *t = exp->type;
3514 int offset = 0;
3515 TypeFunction *tf = (TypeFunction *)exp->f->tintro;
3516
3517 if (tf->next->isBaseOf(t, &offset) && offset)
3518 {
3519 exp->type = tf->next;
3520 result = Expression::combine(argprefix, exp->castTo(sc, t));
3521 return;
3522 }
3523 }
3524
3525 // Handle the case of a direct lambda call
3526 if (exp->f && exp->f->isFuncLiteralDeclaration() &&
3527 sc->func && !sc->intypeof)
3528 {
3529 exp->f->tookAddressOf = 0;
3530 }
3531
3532 result = Expression::combine(argprefix, exp);
3533 }
3534
visit(AddrExp * exp)3535 void visit(AddrExp *exp)
3536 {
3537 if (exp->type)
3538 {
3539 result = exp;
3540 return;
3541 }
3542
3543 if (Expression *ex = unaSemantic(exp, sc))
3544 {
3545 result = ex;
3546 return;
3547 }
3548 int wasCond = exp->e1->op == TOKquestion;
3549 if (exp->e1->op == TOKdotti)
3550 {
3551 DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)exp->e1;
3552 TemplateInstance *ti = dti->ti;
3553 {
3554 //assert(ti->needsTypeInference(sc));
3555 ti->semantic(sc);
3556 if (!ti->inst || ti->errors) // if template failed to expand
3557 return setError();
3558 Dsymbol *s = ti->toAlias();
3559 FuncDeclaration *f = s->isFuncDeclaration();
3560 if (f)
3561 {
3562 exp->e1 = new DotVarExp(exp->e1->loc, dti->e1, f);
3563 exp->e1 = semantic(exp->e1, sc);
3564 }
3565 }
3566 }
3567 else if (exp->e1->op == TOKscope)
3568 {
3569 TemplateInstance *ti = ((ScopeExp *)exp->e1)->sds->isTemplateInstance();
3570 if (ti)
3571 {
3572 //assert(ti->needsTypeInference(sc));
3573 ti->semantic(sc);
3574 if (!ti->inst || ti->errors) // if template failed to expand
3575 return setError();
3576 Dsymbol *s = ti->toAlias();
3577 FuncDeclaration *f = s->isFuncDeclaration();
3578 if (f)
3579 {
3580 exp->e1 = new VarExp(exp->e1->loc, f);
3581 exp->e1 = semantic(exp->e1, sc);
3582 }
3583 }
3584 }
3585 exp->e1 = exp->e1->toLvalue(sc, NULL);
3586 if (exp->e1->op == TOKerror)
3587 {
3588 result = exp->e1;
3589 return;
3590 }
3591 if (checkNonAssignmentArrayOp(exp->e1))
3592 return setError();
3593
3594 if (!exp->e1->type)
3595 {
3596 exp->error("cannot take address of %s", exp->e1->toChars());
3597 return setError();
3598 }
3599
3600 bool hasOverloads = false;
3601 if (FuncDeclaration *f = isFuncAddress(exp, &hasOverloads))
3602 {
3603 if (!hasOverloads && f->checkForwardRef(exp->loc))
3604 return setError();
3605 }
3606 else if (!exp->e1->type->deco)
3607 {
3608 if (exp->e1->op == TOKvar)
3609 {
3610 VarExp *ve = (VarExp *)exp->e1;
3611 Declaration *d = ve->var;
3612 exp->error("forward reference to %s %s", d->kind(), d->toChars());
3613 }
3614 else
3615 exp->error("forward reference to %s", exp->e1->toChars());
3616 return setError();
3617 }
3618
3619 exp->type = exp->e1->type->pointerTo();
3620
3621 // See if this should really be a delegate
3622 if (exp->e1->op == TOKdotvar)
3623 {
3624 DotVarExp *dve = (DotVarExp *)exp->e1;
3625 FuncDeclaration *f = dve->var->isFuncDeclaration();
3626 if (f)
3627 {
3628 f = f->toAliasFunc(); // FIXME, should see overloads - Bugzilla 1983
3629 if (!dve->hasOverloads)
3630 f->tookAddressOf++;
3631
3632 Expression *e;
3633 if (f->needThis())
3634 e = new DelegateExp(exp->loc, dve->e1, f, dve->hasOverloads);
3635 else // It is a function pointer. Convert &v.f() --> (v, &V.f())
3636 e = new CommaExp(exp->loc, dve->e1, new AddrExp(exp->loc, new VarExp(exp->loc, f, dve->hasOverloads)));
3637 e = semantic(e, sc);
3638 result = e;
3639 return;
3640 }
3641
3642 // Look for misaligned pointer in @safe mode
3643 if (checkUnsafeAccess(sc, dve, !exp->type->isMutable(), true))
3644 return setError();
3645
3646 if (dve->e1->op == TOKvar && global.params.vsafe)
3647 {
3648 VarExp *ve = (VarExp *)dve->e1;
3649 VarDeclaration *v = ve->var->isVarDeclaration();
3650 if (v)
3651 {
3652 if (!checkAddressVar(sc, exp, v))
3653 return setError();
3654 }
3655 }
3656 else if ((dve->e1->op == TOKthis || dve->e1->op == TOKsuper) && global.params.vsafe)
3657 {
3658 ThisExp *ve = (ThisExp *)dve->e1;
3659 VarDeclaration *v = ve->var->isVarDeclaration();
3660 if (v && v->storage_class & STCref)
3661 {
3662 if (!checkAddressVar(sc, exp, v))
3663 return setError();
3664 }
3665 }
3666 }
3667 else if (exp->e1->op == TOKvar)
3668 {
3669 VarExp *ve = (VarExp *)exp->e1;
3670
3671 VarDeclaration *v = ve->var->isVarDeclaration();
3672 if (v)
3673 {
3674 if (!checkAddressVar(sc, exp, v))
3675 return setError();
3676
3677 ve->checkPurity(sc, v);
3678 }
3679
3680 FuncDeclaration *f = ve->var->isFuncDeclaration();
3681 if (f)
3682 {
3683 /* Because nested functions cannot be overloaded,
3684 * mark here that we took its address because castTo()
3685 * may not be called with an exact match.
3686 */
3687 if (!ve->hasOverloads || f->isNested())
3688 f->tookAddressOf++;
3689 if (f->isNested())
3690 {
3691 if (f->isFuncLiteralDeclaration())
3692 {
3693 if (!f->FuncDeclaration::isNested())
3694 {
3695 /* Supply a 'null' for a this pointer if no this is available
3696 */
3697 Expression *e = new DelegateExp(exp->loc, new NullExp(exp->loc, Type::tnull), f, ve->hasOverloads);
3698 e = semantic(e, sc);
3699 result = e;
3700 return;
3701 }
3702 }
3703 Expression *e = new DelegateExp(exp->loc, exp->e1, f, ve->hasOverloads);
3704 e = semantic(e, sc);
3705 result = e;
3706 return;
3707 }
3708 if (f->needThis())
3709 {
3710 if (hasThis(sc))
3711 {
3712 /* Should probably supply 'this' after overload resolution,
3713 * not before.
3714 */
3715 Expression *ethis = new ThisExp(exp->loc);
3716 Expression *e = new DelegateExp(exp->loc, ethis, f, ve->hasOverloads);
3717 e = semantic(e, sc);
3718 result = e;
3719 return;
3720 }
3721 if (sc->func && !sc->intypeof)
3722 {
3723 if (sc->func->setUnsafe())
3724 {
3725 exp->error("'this' reference necessary to take address of member %s in @safe function %s",
3726 f->toChars(), sc->func->toChars());
3727 }
3728 }
3729 }
3730 }
3731 }
3732 else if ((exp->e1->op == TOKthis || exp->e1->op == TOKsuper) && global.params.vsafe)
3733 {
3734 ThisExp *ve = (ThisExp *)exp->e1;
3735 VarDeclaration *v = ve->var->isVarDeclaration();
3736 if (v)
3737 {
3738 if (!checkAddressVar(sc, exp, v))
3739 return setError();
3740 }
3741 }
3742 else if (exp->e1->op == TOKcall)
3743 {
3744 CallExp *ce = (CallExp *)exp->e1;
3745 if (ce->e1->type->ty == Tfunction)
3746 {
3747 TypeFunction *tf = (TypeFunction *)ce->e1->type;
3748 if (tf->isref && sc->func && !sc->intypeof && sc->func->setUnsafe())
3749 {
3750 exp->error("cannot take address of ref return of %s() in @safe function %s",
3751 ce->e1->toChars(), sc->func->toChars());
3752 }
3753 }
3754 }
3755 else if (exp->e1->op == TOKindex)
3756 {
3757 /* For:
3758 * int[3] a;
3759 * &a[i]
3760 * check 'a' the same as for a regular variable
3761 */
3762 IndexExp *ei = (IndexExp *)exp->e1;
3763 Type *tyi = ei->e1->type->toBasetype();
3764 if (tyi->ty == Tsarray && ei->e1->op == TOKvar)
3765 {
3766 VarExp *ve = (VarExp *)ei->e1;
3767 VarDeclaration *v = ve->var->isVarDeclaration();
3768 if (v)
3769 {
3770 if (!checkAddressVar(sc, exp, v))
3771 return setError();
3772
3773 ve->checkPurity(sc, v);
3774 }
3775 }
3776 }
3777 else if (wasCond)
3778 {
3779 /* a ? b : c was transformed to *(a ? &b : &c), but we still
3780 * need to do safety checks
3781 */
3782 assert(exp->e1->op == TOKstar);
3783 PtrExp *pe = (PtrExp *)exp->e1;
3784 assert(pe->e1->op == TOKquestion);
3785 CondExp *ce = (CondExp *)pe->e1;
3786 assert(ce->e1->op == TOKaddress);
3787 assert(ce->e2->op == TOKaddress);
3788
3789 // Re-run semantic on the address expressions only
3790 ce->e1->type = NULL;
3791 ce->e1 = semantic(ce->e1, sc);
3792 ce->e2->type = NULL;
3793 ce->e2 = semantic(ce->e2, sc);
3794 }
3795
3796 result = exp->optimize(WANTvalue);
3797 }
3798
visit(PtrExp * exp)3799 void visit(PtrExp *exp)
3800 {
3801 if (exp->type)
3802 {
3803 result = exp;
3804 return;
3805 }
3806
3807 Expression *e = exp->op_overload(sc);
3808 if (e)
3809 {
3810 result = e;
3811 return;
3812 }
3813
3814 Type *tb = exp->e1->type->toBasetype();
3815 switch (tb->ty)
3816 {
3817 case Tpointer:
3818 exp->type = ((TypePointer *)tb)->next;
3819 break;
3820
3821 case Tsarray:
3822 case Tarray:
3823 exp->error("using * on an array is no longer supported; use *(%s).ptr instead", exp->e1->toChars());
3824 exp->type = ((TypeArray *)tb)->next;
3825 exp->e1 = exp->e1->castTo(sc, exp->type->pointerTo());
3826 break;
3827
3828 default:
3829 exp->error("can only * a pointer, not a '%s'", exp->e1->type->toChars());
3830 /* fall through */
3831
3832 case Terror:
3833 return setError();
3834 }
3835 if (exp->checkValue())
3836 return setError();
3837
3838 result = exp;
3839 }
3840
visit(NegExp * exp)3841 void visit(NegExp *exp)
3842 {
3843 if (exp->type)
3844 {
3845 result = exp;
3846 return;
3847 }
3848
3849 Expression *e = exp->op_overload(sc);
3850 if (e)
3851 {
3852 result = e;
3853 return;
3854 }
3855
3856 exp->type = exp->e1->type;
3857 Type *tb = exp->type->toBasetype();
3858 if (tb->ty == Tarray || tb->ty == Tsarray)
3859 {
3860 if (!isArrayOpValid(exp->e1))
3861 {
3862 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
3863 return setError();
3864 }
3865 result = exp;
3866 return;
3867 }
3868
3869 if (!Target::isVectorOpSupported(tb, exp->op))
3870 {
3871 result = exp->incompatibleTypes();
3872 return;
3873 }
3874 if (exp->e1->checkNoBool())
3875 return setError();
3876 if (exp->e1->checkArithmetic())
3877 return setError();
3878
3879 result = exp;
3880 }
3881
visit(UAddExp * exp)3882 void visit(UAddExp *exp)
3883 {
3884 assert(!exp->type);
3885
3886 Expression *e = exp->op_overload(sc);
3887 if (e)
3888 {
3889 result = e;
3890 return;
3891 }
3892
3893 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op))
3894 {
3895 result = exp->incompatibleTypes();
3896 return;
3897 }
3898 if (exp->e1->checkNoBool())
3899 return setError();
3900 if (exp->e1->checkArithmetic())
3901 return setError();
3902
3903 result = exp->e1;
3904 }
3905
visit(ComExp * exp)3906 void visit(ComExp *exp)
3907 {
3908 if (exp->type)
3909 {
3910 result = exp;
3911 return;
3912 }
3913
3914 Expression *e = exp->op_overload(sc);
3915 if (e)
3916 {
3917 result = e;
3918 return;
3919 }
3920
3921 exp->type = exp->e1->type;
3922 Type *tb = exp->type->toBasetype();
3923 if (tb->ty == Tarray || tb->ty == Tsarray)
3924 {
3925 if (!isArrayOpValid(exp->e1))
3926 {
3927 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
3928 return setError();
3929 }
3930 result = exp;
3931 return;
3932 }
3933
3934 if (!Target::isVectorOpSupported(tb, exp->op))
3935 {
3936 result = exp->incompatibleTypes();
3937 return;
3938 }
3939 if (exp->e1->checkNoBool())
3940 return setError();
3941 if (exp->e1->checkIntegral())
3942 return setError();
3943
3944 result = exp;
3945 }
3946
visit(NotExp * e)3947 void visit(NotExp *e)
3948 {
3949 if (e->type)
3950 {
3951 result = e;
3952 return;
3953 }
3954
3955 setNoderefOperand(e);
3956
3957 // Note there is no operator overload
3958 if (Expression *ex = unaSemantic(e, sc))
3959 {
3960 result = ex;
3961 return;
3962 }
3963
3964 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
3965 if (e->e1->op == TOKtype)
3966 e->e1 = resolveAliasThis(sc, e->e1);
3967
3968 e->e1 = resolveProperties(sc, e->e1);
3969 e->e1 = e->e1->toBoolean(sc);
3970 if (e->e1->type == Type::terror)
3971 {
3972 result = e->e1;
3973 return;
3974 }
3975
3976 if (!Target::isVectorOpSupported(e->e1->type->toBasetype(), e->op))
3977 {
3978 result = e->incompatibleTypes();
3979 return;
3980 }
3981 // Bugzilla 13910: Today NotExp can take an array as its operand.
3982 if (checkNonAssignmentArrayOp(e->e1))
3983 return setError();
3984
3985 e->type = Type::tbool;
3986 result = e;
3987 }
3988
visit(DeleteExp * exp)3989 void visit(DeleteExp *exp)
3990 {
3991 if (Expression *ex = unaSemantic(exp, sc))
3992 {
3993 result = ex;
3994 return;
3995 }
3996 exp->e1 = resolveProperties(sc, exp->e1);
3997 exp->e1 = exp->e1->modifiableLvalue(sc, NULL);
3998 if (exp->e1->op == TOKerror)
3999 {
4000 result = exp->e1;
4001 return;
4002 }
4003 exp->type = Type::tvoid;
4004
4005 AggregateDeclaration *ad = NULL;
4006 Type *tb = exp->e1->type->toBasetype();
4007 switch (tb->ty)
4008 { case Tclass:
4009 {
4010 ClassDeclaration *cd = ((TypeClass *)tb)->sym;
4011
4012 if (cd->isCOMinterface())
4013 { /* Because COM classes are deleted by IUnknown.Release()
4014 */
4015 exp->error("cannot delete instance of COM interface %s", cd->toChars());
4016 return setError();
4017 }
4018
4019 ad = cd;
4020 break;
4021 }
4022 case Tpointer:
4023 tb = ((TypePointer *)tb)->next->toBasetype();
4024 if (tb->ty == Tstruct)
4025 {
4026 ad = ((TypeStruct *)tb)->sym;
4027 FuncDeclaration *f = ad->aggDelete;
4028 FuncDeclaration *fd = ad->dtor;
4029
4030 if (!f)
4031 {
4032 semanticTypeInfo(sc, tb);
4033 break;
4034 }
4035
4036 /* Construct:
4037 * ea = copy e1 to a tmp to do side effects only once
4038 * eb = call destructor
4039 * ec = call deallocator
4040 */
4041 Expression *ea = NULL;
4042 Expression *eb = NULL;
4043 Expression *ec = NULL;
4044 VarDeclaration *v = NULL;
4045
4046 if (fd && f)
4047 {
4048 v = copyToTemp(0, "__tmpea", exp->e1);
4049 v->semantic(sc);
4050 ea = new DeclarationExp(exp->loc, v);
4051 ea->type = v->type;
4052 }
4053
4054 if (fd)
4055 {
4056 Expression *e = ea ? new VarExp(exp->loc, v) : exp->e1;
4057 e = new DotVarExp(Loc(), e, fd, false);
4058 eb = new CallExp(exp->loc, e);
4059 eb = semantic(eb, sc);
4060 }
4061
4062 if (f)
4063 {
4064 Type *tpv = Type::tvoid->pointerTo();
4065 Expression *e = ea ? new VarExp(exp->loc, v) : exp->e1->castTo(sc, tpv);
4066 e = new CallExp(exp->loc, new VarExp(exp->loc, f, false), e);
4067 ec = semantic(e, sc);
4068 }
4069 ea = Expression::combine(ea, eb);
4070 ea = Expression::combine(ea, ec);
4071 assert(ea);
4072 result = ea;
4073 return;
4074 }
4075 break;
4076
4077 case Tarray:
4078 {
4079 Type *tv = tb->nextOf()->baseElemOf();
4080 if (tv->ty == Tstruct)
4081 {
4082 ad = ((TypeStruct *)tv)->sym;
4083 if (ad->dtor)
4084 semanticTypeInfo(sc, ad->type);
4085 }
4086 break;
4087 }
4088 default:
4089 exp->error("cannot delete type %s", exp->e1->type->toChars());
4090 return setError();
4091 }
4092
4093 bool err = false;
4094 if (ad)
4095 {
4096 if (ad->dtor)
4097 {
4098 err |= exp->checkPurity(sc, ad->dtor);
4099 err |= exp->checkSafety(sc, ad->dtor);
4100 err |= exp->checkNogc(sc, ad->dtor);
4101 }
4102 if (ad->aggDelete && tb->ty != Tarray)
4103 {
4104 err |= exp->checkPurity(sc, ad->aggDelete);
4105 err |= exp->checkSafety(sc, ad->aggDelete);
4106 err |= exp->checkNogc(sc, ad->aggDelete);
4107 }
4108 if (err)
4109 return setError();
4110 }
4111
4112 if (!sc->intypeof && sc->func &&
4113 !exp->isRAII &&
4114 sc->func->setUnsafe())
4115 {
4116 exp->error("%s is not @safe but is used in @safe function %s", exp->toChars(), sc->func->toChars());
4117 err = true;
4118 }
4119 if (err)
4120 return setError();
4121
4122 result = exp;
4123 }
4124
visit(CastExp * exp)4125 void visit(CastExp *exp)
4126 {
4127 //static int x; assert(++x < 10);
4128 if (exp->type)
4129 {
4130 result = exp;
4131 return;
4132 }
4133
4134 if (exp->to)
4135 {
4136 exp->to = exp->to->semantic(exp->loc, sc);
4137 if (exp->to == Type::terror)
4138 return setError();
4139
4140 if (!exp->to->hasPointers())
4141 setNoderefOperand(exp);
4142
4143 // When e1 is a template lambda, this cast may instantiate it with
4144 // the type 'to'.
4145 exp->e1 = inferType(exp->e1, exp->to);
4146 }
4147
4148 if (Expression *ex = unaSemantic(exp, sc))
4149 {
4150 result = ex;
4151 return;
4152 }
4153 Expression *e1x = resolveProperties(sc, exp->e1);
4154 if (e1x->op == TOKerror)
4155 {
4156 result = e1x;
4157 return;
4158 }
4159 if (e1x->checkType())
4160 return setError();
4161 exp->e1 = e1x;
4162
4163 if (!exp->e1->type)
4164 {
4165 exp->error("cannot cast %s", exp->e1->toChars());
4166 return setError();
4167 }
4168
4169 if (!exp->to) // Handle cast(const) and cast(immutable), etc.
4170 {
4171 exp->to = exp->e1->type->castMod(exp->mod);
4172 exp->to = exp->to->semantic(exp->loc, sc);
4173 if (exp->to == Type::terror)
4174 return setError();
4175 }
4176
4177 if (exp->to->ty == Ttuple)
4178 {
4179 exp->error("cannot cast %s to tuple type %s", exp->e1->toChars(), exp->to->toChars());
4180 return setError();
4181 }
4182 if (exp->e1->type->ty != Tvoid ||
4183 (exp->e1->op == TOKfunction && exp->to->ty == Tvoid) ||
4184 exp->e1->op == TOKtype ||
4185 exp->e1->op == TOKtemplate)
4186 {
4187 if (exp->e1->checkValue())
4188 return setError();
4189 }
4190
4191 // cast(void) is used to mark e1 as unused, so it is safe
4192 if (exp->to->ty == Tvoid)
4193 {
4194 exp->type = exp->to;
4195 result = exp;
4196 return;
4197 }
4198
4199 if (!exp->to->equals(exp->e1->type) && exp->mod == (unsigned char)~0)
4200 {
4201 if (Expression *e = exp->op_overload(sc))
4202 {
4203 result = e->implicitCastTo(sc, exp->to);
4204 return;
4205 }
4206 }
4207
4208 Type *t1b = exp->e1->type->toBasetype();
4209 Type *tob = exp->to->toBasetype();
4210
4211 if (tob->ty == Tstruct && !tob->equals(t1b))
4212 {
4213 /* Look to replace:
4214 * cast(S)t
4215 * with:
4216 * S(t)
4217 */
4218
4219 // Rewrite as to.call(e1)
4220 Expression *e = new TypeExp(exp->loc, exp->to);
4221 e = new CallExp(exp->loc, e, exp->e1);
4222 e = trySemantic(e, sc);
4223 if (e)
4224 {
4225 result = e;
4226 return;
4227 }
4228 }
4229
4230 if (!t1b->equals(tob) && (t1b->ty == Tarray || t1b->ty == Tsarray))
4231 {
4232 if (checkNonAssignmentArrayOp(exp->e1))
4233 return setError();
4234 }
4235
4236 // Look for casting to a vector type
4237 if (tob->ty == Tvector && t1b->ty != Tvector)
4238 {
4239 result = new VectorExp(exp->loc, exp->e1, exp->to);
4240 return;
4241 }
4242
4243 Expression *ex = exp->e1->castTo(sc, exp->to);
4244 if (ex->op == TOKerror)
4245 {
4246 result = ex;
4247 return;
4248 }
4249
4250 // Check for unsafe casts
4251 if (sc->func && !sc->intypeof &&
4252 !isSafeCast(ex, t1b, tob) &&
4253 sc->func->setUnsafe())
4254 {
4255 exp->error("cast from %s to %s not allowed in safe code", exp->e1->type->toChars(), exp->to->toChars());
4256 return setError();
4257 }
4258
4259 result = ex;
4260 }
4261
visit(VectorExp * exp)4262 void visit(VectorExp *exp)
4263 {
4264 if (exp->type)
4265 {
4266 result = exp;
4267 return;
4268 }
4269
4270 exp->e1 = semantic(exp->e1, sc);
4271 exp->type = exp->to->semantic(exp->loc, sc);
4272 if (exp->e1->op == TOKerror || exp->type->ty == Terror)
4273 {
4274 result = exp->e1;
4275 return;
4276 }
4277
4278 Type *tb = exp->type->toBasetype();
4279 assert(tb->ty == Tvector);
4280 TypeVector *tv = (TypeVector *)tb;
4281 Type *te = tv->elementType();
4282 exp->dim = (int)(tv->size(exp->loc) / te->size(exp->loc));
4283
4284 exp->e1 = exp->e1->optimize(WANTvalue);
4285 bool res = false;
4286 if (exp->e1->op == TOKarrayliteral)
4287 {
4288 for (size_t i = 0; i < exp->dim; i++)
4289 {
4290 // Do not stop on first error - check all AST nodes even if error found
4291 res |= checkVectorElem(exp, ((ArrayLiteralExp *)exp->e1)->getElement(i));
4292 }
4293 }
4294 else if (exp->e1->type->ty == Tvoid)
4295 res = checkVectorElem(exp, exp->e1);
4296
4297 Expression *e = exp;
4298 if (res)
4299 e = new ErrorExp();
4300 result = e;
4301 }
4302
visit(VectorArrayExp * e)4303 void visit(VectorArrayExp *e)
4304 {
4305 if (!e->type)
4306 {
4307 unaSemantic(e, sc);
4308 e->e1 = resolveProperties(sc, e->e1);
4309
4310 if (e->e1->op == TOKerror)
4311 {
4312 result = e->e1;
4313 return;
4314 }
4315 assert(e->e1->type->ty == Tvector);
4316 TypeVector *tv = (TypeVector *)e->e1->type;
4317 e->type = tv->basetype;
4318 }
4319 result = e;
4320 }
4321
visit(SliceExp * exp)4322 void visit(SliceExp *exp)
4323 {
4324 if (exp->type)
4325 {
4326 result = exp;
4327 return;
4328 }
4329
4330 // operator overloading should be handled in ArrayExp already.
4331
4332 if (Expression *ex = unaSemantic(exp, sc))
4333 {
4334 result = ex;
4335 return;
4336 }
4337 exp->e1 = resolveProperties(sc, exp->e1);
4338 if (exp->e1->op == TOKtype && exp->e1->type->ty != Ttuple)
4339 {
4340 if (exp->lwr || exp->upr)
4341 {
4342 exp->error("cannot slice type '%s'", exp->e1->toChars());
4343 return setError();
4344 }
4345 Expression *e = new TypeExp(exp->loc, exp->e1->type->arrayOf());
4346 result = semantic(e, sc);
4347 return;
4348 }
4349 if (!exp->lwr && !exp->upr)
4350 {
4351 if (exp->e1->op == TOKarrayliteral)
4352 {
4353 // Convert [a,b,c][] to [a,b,c]
4354 Type *t1b = exp->e1->type->toBasetype();
4355 Expression *e = exp->e1;
4356 if (t1b->ty == Tsarray)
4357 {
4358 e = e->copy();
4359 e->type = t1b->nextOf()->arrayOf();
4360 }
4361 result = e;
4362 return;
4363 }
4364 if (exp->e1->op == TOKslice)
4365 {
4366 // Convert e[][] to e[]
4367 SliceExp *se = (SliceExp *)exp->e1;
4368 if (!se->lwr && !se->upr)
4369 {
4370 result = se;
4371 return;
4372 }
4373 }
4374 if (isArrayOpOperand(exp->e1))
4375 {
4376 // Convert (a[]+b[])[] to a[]+b[]
4377 result = exp->e1;
4378 return;
4379 }
4380 }
4381 if (exp->e1->op == TOKerror)
4382 {
4383 result = exp->e1;
4384 return;
4385 }
4386 if (exp->e1->type->ty == Terror)
4387 return setError();
4388
4389 Type *t1b = exp->e1->type->toBasetype();
4390 if (t1b->ty == Tpointer)
4391 {
4392 if (((TypePointer *)t1b)->next->ty == Tfunction)
4393 {
4394 exp->error("cannot slice function pointer %s", exp->e1->toChars());
4395 return setError();
4396 }
4397 if (!exp->lwr || !exp->upr)
4398 {
4399 exp->error("need upper and lower bound to slice pointer");
4400 return setError();
4401 }
4402 if (sc->func && !sc->intypeof && sc->func->setUnsafe())
4403 {
4404 exp->error("pointer slicing not allowed in safe functions");
4405 return setError();
4406 }
4407 }
4408 else if (t1b->ty == Tarray)
4409 {
4410 }
4411 else if (t1b->ty == Tsarray)
4412 {
4413 if (!exp->arrayop && global.params.vsafe)
4414 {
4415 /* Slicing a static array is like taking the address of it.
4416 * Perform checks as if e[] was &e
4417 */
4418 VarDeclaration *v = NULL;
4419 if (exp->e1->op == TOKdotvar)
4420 {
4421 DotVarExp *dve = (DotVarExp *)exp->e1;
4422 if (dve->e1->op == TOKvar)
4423 {
4424 VarExp *ve = (VarExp *)dve->e1;
4425 v = ve->var->isVarDeclaration();
4426 }
4427 else if (dve->e1->op == TOKthis || dve->e1->op == TOKsuper)
4428 {
4429 ThisExp *ve = (ThisExp *)dve->e1;
4430 v = ve->var->isVarDeclaration();
4431 if (v && !(v->storage_class & STCref))
4432 v = NULL;
4433 }
4434 }
4435 else if (exp->e1->op == TOKvar)
4436 {
4437 VarExp *ve = (VarExp *)exp->e1;
4438 v = ve->var->isVarDeclaration();
4439 }
4440 else if (exp->e1->op == TOKthis || exp->e1->op == TOKsuper)
4441 {
4442 ThisExp *ve = (ThisExp *)exp->e1;
4443 v = ve->var->isVarDeclaration();
4444 }
4445
4446 if (v)
4447 {
4448 if (!checkAddressVar(sc, exp, v))
4449 return setError();
4450 }
4451 }
4452 }
4453 else if (t1b->ty == Ttuple)
4454 {
4455 if (!exp->lwr && !exp->upr)
4456 {
4457 result = exp->e1;
4458 return;
4459 }
4460 if (!exp->lwr || !exp->upr)
4461 {
4462 exp->error("need upper and lower bound to slice tuple");
4463 return setError();
4464 }
4465 }
4466 else if (t1b->ty == Tvector)
4467 {
4468 // Convert e1 to corresponding static array
4469 TypeVector *tv1 = (TypeVector *)t1b;
4470 t1b = tv1->basetype;
4471 t1b = t1b->castMod(tv1->mod);
4472 exp->e1->type = t1b;
4473 }
4474 else
4475 {
4476 exp->error("%s cannot be sliced with []",
4477 t1b->ty == Tvoid ? exp->e1->toChars() : t1b->toChars());
4478 return setError();
4479 }
4480
4481 /* Run semantic on lwr and upr.
4482 */
4483 Scope *scx = sc;
4484 if (t1b->ty == Tsarray || t1b->ty == Tarray || t1b->ty == Ttuple)
4485 {
4486 // Create scope for 'length' variable
4487 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, exp);
4488 sym->loc = exp->loc;
4489 sym->parent = sc->scopesym;
4490 sc = sc->push(sym);
4491 }
4492 if (exp->lwr)
4493 {
4494 if (t1b->ty == Ttuple) sc = sc->startCTFE();
4495 exp->lwr = semantic(exp->lwr, sc);
4496 exp->lwr = resolveProperties(sc, exp->lwr);
4497 if (t1b->ty == Ttuple) sc = sc->endCTFE();
4498 exp->lwr = exp->lwr->implicitCastTo(sc, Type::tsize_t);
4499 }
4500 if (exp->upr)
4501 {
4502 if (t1b->ty == Ttuple) sc = sc->startCTFE();
4503 exp->upr = semantic(exp->upr, sc);
4504 exp->upr = resolveProperties(sc, exp->upr);
4505 if (t1b->ty == Ttuple) sc = sc->endCTFE();
4506 exp->upr = exp->upr->implicitCastTo(sc, Type::tsize_t);
4507 }
4508 if (sc != scx)
4509 sc = sc->pop();
4510 if ((exp->lwr && exp->lwr->type == Type::terror) ||
4511 (exp->upr && exp->upr->type == Type::terror))
4512 {
4513 return setError();
4514 }
4515
4516 if (t1b->ty == Ttuple)
4517 {
4518 exp->lwr = exp->lwr->ctfeInterpret();
4519 exp->upr = exp->upr->ctfeInterpret();
4520 uinteger_t i1 = exp->lwr->toUInteger();
4521 uinteger_t i2 = exp->upr->toUInteger();
4522
4523 TupleExp *te;
4524 TypeTuple *tup;
4525 size_t length;
4526 if (exp->e1->op == TOKtuple) // slicing an expression tuple
4527 {
4528 te = (TupleExp *)exp->e1;
4529 tup = NULL;
4530 length = te->exps->dim;
4531 }
4532 else if (exp->e1->op == TOKtype) // slicing a type tuple
4533 {
4534 te = NULL;
4535 tup = (TypeTuple *)t1b;
4536 length = Parameter::dim(tup->arguments);
4537 }
4538 else
4539 assert(0);
4540
4541 if (i2 < i1 || length < i2)
4542 {
4543 exp->error("string slice [%llu .. %llu] is out of bounds", i1, i2);
4544 return setError();
4545 }
4546
4547 size_t j1 = (size_t) i1;
4548 size_t j2 = (size_t) i2;
4549 Expression *e;
4550 if (exp->e1->op == TOKtuple)
4551 {
4552 Expressions *exps = new Expressions;
4553 exps->setDim(j2 - j1);
4554 for (size_t i = 0; i < j2 - j1; i++)
4555 {
4556 (*exps)[i] = (*te->exps)[j1 + i];
4557 }
4558 e = new TupleExp(exp->loc, te->e0, exps);
4559 }
4560 else
4561 {
4562 Parameters *args = new Parameters;
4563 args->reserve(j2 - j1);
4564 for (size_t i = j1; i < j2; i++)
4565 {
4566 Parameter *arg = Parameter::getNth(tup->arguments, i);
4567 args->push(arg);
4568 }
4569 e = new TypeExp(exp->e1->loc, new TypeTuple(args));
4570 }
4571 e = semantic(e, sc);
4572 result = e;
4573 return;
4574 }
4575
4576 exp->type = t1b->nextOf()->arrayOf();
4577 // Allow typedef[] -> typedef[]
4578 if (exp->type->equals(t1b))
4579 exp->type = exp->e1->type;
4580
4581 if (exp->lwr && exp->upr)
4582 {
4583 exp->lwr = exp->lwr->optimize(WANTvalue);
4584 exp->upr = exp->upr->optimize(WANTvalue);
4585
4586 IntRange lwrRange = getIntRange(exp->lwr);
4587 IntRange uprRange = getIntRange(exp->upr);
4588
4589 if (t1b->ty == Tsarray || t1b->ty == Tarray)
4590 {
4591 Expression *el = new ArrayLengthExp(exp->loc, exp->e1);
4592 el = semantic(el, sc);
4593 el = el->optimize(WANTvalue);
4594 if (el->op == TOKint64)
4595 {
4596 dinteger_t length = el->toInteger();
4597 IntRange bounds(SignExtendedNumber(0), SignExtendedNumber(length));
4598 exp->upperIsInBounds = bounds.contains(uprRange);
4599 }
4600 }
4601 else if (t1b->ty == Tpointer)
4602 {
4603 exp->upperIsInBounds = true;
4604 }
4605 else
4606 assert(0);
4607
4608 exp->lowerIsLessThanUpper = (lwrRange.imax <= uprRange.imin);
4609
4610 //printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", upperIsInBounds, lowerIsLessThanUpper);
4611 }
4612
4613 result = exp;
4614 }
4615
visit(ArrayLengthExp * e)4616 void visit(ArrayLengthExp *e)
4617 {
4618 if (e->type)
4619 {
4620 result = e;
4621 return;
4622 }
4623
4624 if (Expression *ex = unaSemantic(e, sc))
4625 {
4626 result = ex;
4627 return;
4628 }
4629 e->e1 = resolveProperties(sc, e->e1);
4630
4631 e->type = Type::tsize_t;
4632 result = e;
4633 }
4634
visit(IntervalExp * e)4635 void visit(IntervalExp *e)
4636 {
4637 if (e->type)
4638 {
4639 result = e;
4640 return;
4641 }
4642
4643 Expression *le = e->lwr;
4644 le = semantic(le, sc);
4645 le = resolveProperties(sc, le);
4646
4647 Expression *ue = e->upr;
4648 ue = semantic(ue, sc);
4649 ue = resolveProperties(sc, ue);
4650
4651 if (le->op == TOKerror)
4652 {
4653 result = le;
4654 return;
4655 }
4656 if (ue->op == TOKerror)
4657 {
4658 result = ue;
4659 return;
4660 }
4661
4662 e->lwr = le;
4663 e->upr = ue;
4664
4665 e->type = Type::tvoid;
4666 result = e;
4667 }
4668
visit(DelegatePtrExp * e)4669 void visit(DelegatePtrExp *e)
4670 {
4671 if (!e->type)
4672 {
4673 unaSemantic(e, sc);
4674 e->e1 = resolveProperties(sc, e->e1);
4675
4676 if (e->e1->op == TOKerror)
4677 {
4678 result = e->e1;
4679 return;
4680 }
4681 e->type = Type::tvoidptr;
4682 }
4683 result = e;
4684 }
4685
visit(DelegateFuncptrExp * e)4686 void visit(DelegateFuncptrExp *e)
4687 {
4688 if (!e->type)
4689 {
4690 unaSemantic(e, sc);
4691 e->e1 = resolveProperties(sc, e->e1);
4692
4693 if (e->e1->op == TOKerror)
4694 {
4695 result = e->e1;
4696 return;
4697 }
4698 e->type = e->e1->type->nextOf()->pointerTo();
4699 }
4700 result = e;
4701 }
4702
visit(ArrayExp * exp)4703 void visit(ArrayExp *exp)
4704 {
4705 assert(!exp->type);
4706
4707 Expression *e = exp->op_overload(sc);
4708 if (e)
4709 {
4710 result = e;
4711 return;
4712 }
4713
4714 if (isAggregate(exp->e1->type))
4715 exp->error("no [] operator overload for type %s", exp->e1->type->toChars());
4716 else
4717 exp->error("only one index allowed to index %s", exp->e1->type->toChars());
4718 return setError();
4719 }
4720
visit(DotExp * exp)4721 void visit(DotExp *exp)
4722 {
4723 exp->e1 = semantic(exp->e1, sc);
4724 exp->e2 = semantic(exp->e2, sc);
4725
4726 if (exp->e1->op == TOKtype)
4727 {
4728 result = exp->e2;
4729 return;
4730 }
4731 if (exp->e2->op == TOKtype)
4732 {
4733 result = exp->e2;
4734 return;
4735 }
4736 if (exp->e2->op == TOKtemplate)
4737 {
4738 TemplateDeclaration *td = ((TemplateExp *)exp->e2)->td;
4739 Expression *e = new DotTemplateExp(exp->loc, exp->e1, td);
4740 result = semantic(e, sc);
4741 return;
4742 }
4743 if (!exp->type)
4744 exp->type = exp->e2->type;
4745 result = exp;
4746 }
4747
visit(CommaExp * e)4748 void visit(CommaExp *e)
4749 {
4750 if (e->type)
4751 {
4752 result = e;
4753 return;
4754 }
4755
4756 // Allow `((a,b),(x,y))`
4757 if (e->allowCommaExp)
4758 {
4759 if (e->e1 && e->e1->op == TOKcomma)
4760 ((CommaExp *)e->e1)->allowCommaExp = true;
4761 if (e->e2 && e->e2->op == TOKcomma)
4762 ((CommaExp *)e->e2)->allowCommaExp = true;
4763 }
4764
4765 if (Expression *ex = binSemanticProp(e, sc))
4766 {
4767 result = ex;
4768 return;
4769 }
4770 e->e1 = e->e1->addDtorHook(sc);
4771
4772 if (checkNonAssignmentArrayOp(e->e1))
4773 return setError();
4774
4775 e->type = e->e2->type;
4776 if (e->type != Type::tvoid && !e->allowCommaExp && !e->isGenerated)
4777 e->deprecation("Using the result of a comma expression is deprecated");
4778 result = e;
4779 }
4780
visit(IndexExp * exp)4781 void visit(IndexExp *exp)
4782 {
4783 if (exp->type)
4784 {
4785 result = exp;
4786 return;
4787 }
4788
4789 // operator overloading should be handled in ArrayExp already.
4790
4791 if (!exp->e1->type)
4792 exp->e1 = semantic(exp->e1, sc);
4793 assert(exp->e1->type); // semantic() should already be run on it
4794 if (exp->e1->op == TOKtype && exp->e1->type->ty != Ttuple)
4795 {
4796 exp->e2 = semantic(exp->e2, sc);
4797 exp->e2 = resolveProperties(sc, exp->e2);
4798 Type *nt;
4799 if (exp->e2->op == TOKtype)
4800 nt = new TypeAArray(exp->e1->type, exp->e2->type);
4801 else
4802 nt = new TypeSArray(exp->e1->type, exp->e2);
4803 Expression *e = new TypeExp(exp->loc, nt);
4804 result = semantic(e, sc);
4805 return;
4806 }
4807 if (exp->e1->op == TOKerror)
4808 {
4809 result = exp->e1;
4810 return;
4811 }
4812 if (exp->e1->type->ty == Terror)
4813 return setError();
4814
4815 // Note that unlike C we do not implement the int[ptr]
4816
4817 Type *t1b = exp->e1->type->toBasetype();
4818
4819 if (t1b->ty == Tvector)
4820 {
4821 // Convert e1 to corresponding static array
4822 TypeVector *tv1 = (TypeVector *)t1b;
4823 t1b = tv1->basetype;
4824 t1b = t1b->castMod(tv1->mod);
4825 exp->e1->type = t1b;
4826 }
4827
4828 /* Run semantic on e2
4829 */
4830 Scope *scx = sc;
4831 if (t1b->ty == Tsarray || t1b->ty == Tarray || t1b->ty == Ttuple)
4832 {
4833 // Create scope for 'length' variable
4834 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, exp);
4835 sym->loc = exp->loc;
4836 sym->parent = sc->scopesym;
4837 sc = sc->push(sym);
4838 }
4839 if (t1b->ty == Ttuple) sc = sc->startCTFE();
4840 exp->e2 = semantic(exp->e2, sc);
4841 exp->e2 = resolveProperties(sc, exp->e2);
4842 if (t1b->ty == Ttuple) sc = sc->endCTFE();
4843 if (exp->e2->op == TOKtuple)
4844 {
4845 TupleExp *te = (TupleExp *)exp->e2;
4846 if (te->exps && te->exps->dim == 1)
4847 exp->e2 = Expression::combine(te->e0, (*te->exps)[0]); // bug 4444 fix
4848 }
4849 if (sc != scx)
4850 sc = sc->pop();
4851 if (exp->e2->type == Type::terror)
4852 return setError();
4853
4854 if (checkNonAssignmentArrayOp(exp->e1))
4855 return setError();
4856
4857 switch (t1b->ty)
4858 {
4859 case Tpointer:
4860 if (((TypePointer *)t1b)->next->ty == Tfunction)
4861 {
4862 exp->error("cannot index function pointer %s", exp->e1->toChars());
4863 return setError();
4864 }
4865 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t);
4866 if (exp->e2->type == Type::terror)
4867 return setError();
4868 exp->e2 = exp->e2->optimize(WANTvalue);
4869 if (exp->e2->op == TOKint64 && exp->e2->toInteger() == 0)
4870 ;
4871 else if (sc->func && sc->func->setUnsafe())
4872 {
4873 exp->error("safe function '%s' cannot index pointer '%s'",
4874 sc->func->toPrettyChars(), exp->e1->toChars());
4875 return setError();
4876 }
4877 exp->type = ((TypeNext *)t1b)->next;
4878 break;
4879
4880 case Tarray:
4881 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t);
4882 if (exp->e2->type == Type::terror)
4883 return setError();
4884 exp->type = ((TypeNext *)t1b)->next;
4885 break;
4886
4887 case Tsarray:
4888 {
4889 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t);
4890 if (exp->e2->type == Type::terror)
4891 return setError();
4892 exp->type = t1b->nextOf();
4893 break;
4894 }
4895
4896 case Taarray:
4897 {
4898 TypeAArray *taa = (TypeAArray *)t1b;
4899 /* We can skip the implicit conversion if they differ only by
4900 * constness (Bugzilla 2684, see also bug 2954b)
4901 */
4902 if (!arrayTypeCompatibleWithoutCasting(exp->e2->type, taa->index))
4903 {
4904 exp->e2 = exp->e2->implicitCastTo(sc, taa->index); // type checking
4905 if (exp->e2->type == Type::terror)
4906 return setError();
4907 }
4908
4909 semanticTypeInfo(sc, taa);
4910
4911 exp->type = taa->next;
4912 break;
4913 }
4914
4915 case Ttuple:
4916 {
4917 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t);
4918 if (exp->e2->type == Type::terror)
4919 return setError();
4920 exp->e2 = exp->e2->ctfeInterpret();
4921 uinteger_t index = exp->e2->toUInteger();
4922
4923 TupleExp *te;
4924 TypeTuple *tup;
4925 size_t length;
4926 if (exp->e1->op == TOKtuple)
4927 {
4928 te = (TupleExp *)exp->e1;
4929 tup = NULL;
4930 length = te->exps->dim;
4931 }
4932 else if (exp->e1->op == TOKtype)
4933 {
4934 te = NULL;
4935 tup = (TypeTuple *)t1b;
4936 length = Parameter::dim(tup->arguments);
4937 }
4938 else
4939 assert(0);
4940
4941 if (length <= index)
4942 {
4943 exp->error("array index [%llu] is outside array bounds [0 .. %llu]",
4944 index, (ulonglong)length);
4945 return setError();
4946 }
4947
4948 Expression *e;
4949 if (exp->e1->op == TOKtuple)
4950 {
4951 e = (*te->exps)[(size_t)index];
4952 e = Expression::combine(te->e0, e);
4953 }
4954 else
4955 e = new TypeExp(exp->e1->loc, Parameter::getNth(tup->arguments, (size_t)index)->type);
4956 result = e;
4957 return;
4958 }
4959
4960 default:
4961 exp->error("%s must be an array or pointer type, not %s",
4962 exp->e1->toChars(), exp->e1->type->toChars());
4963 return setError();
4964 }
4965
4966 if (t1b->ty == Tsarray || t1b->ty == Tarray)
4967 {
4968 Expression *el = new ArrayLengthExp(exp->loc, exp->e1);
4969 el = semantic(el, sc);
4970 el = el->optimize(WANTvalue);
4971 if (el->op == TOKint64)
4972 {
4973 exp->e2 = exp->e2->optimize(WANTvalue);
4974 dinteger_t length = el->toInteger();
4975 if (length)
4976 {
4977 IntRange bounds(SignExtendedNumber(0), SignExtendedNumber(length - 1));
4978 exp->indexIsInBounds = bounds.contains(getIntRange(exp->e2));
4979 }
4980 }
4981 }
4982
4983 result = exp;
4984 }
4985
visit(PostExp * exp)4986 void visit(PostExp *exp)
4987 {
4988 if (exp->type)
4989 {
4990 result = exp;
4991 return;
4992 }
4993
4994 if (Expression *ex = binSemantic(exp, sc))
4995 {
4996 result = ex;
4997 return;
4998 }
4999 Expression *e1x = resolveProperties(sc, exp->e1);
5000 if (e1x->op == TOKerror)
5001 {
5002 result = e1x;
5003 return;
5004 }
5005 exp->e1 = e1x;
5006
5007 Expression *e = exp->op_overload(sc);
5008 if (e)
5009 {
5010 result = e;
5011 return;
5012 }
5013
5014 if (exp->e1->checkReadModifyWrite(exp->op))
5015 return setError();
5016 if (exp->e1->op == TOKslice)
5017 {
5018 const char *s = exp->op == TOKplusplus ? "increment" : "decrement";
5019 exp->error("cannot post-%s array slice '%s', use pre-%s instead", s, exp->e1->toChars(), s);
5020 return setError();
5021 }
5022
5023 exp->e1 = exp->e1->optimize(WANTvalue);
5024
5025 Type *t1 = exp->e1->type->toBasetype();
5026 if (t1->ty == Tclass || t1->ty == Tstruct || exp->e1->op == TOKarraylength)
5027 {
5028 /* Check for operator overloading,
5029 * but rewrite in terms of ++e instead of e++
5030 */
5031
5032 /* If e1 is not trivial, take a reference to it
5033 */
5034 Expression *de = NULL;
5035 if (exp->e1->op != TOKvar && exp->e1->op != TOKarraylength)
5036 {
5037 // ref v = e1;
5038 VarDeclaration *v = copyToTemp(STCref, "__postref", exp->e1);
5039 de = new DeclarationExp(exp->loc, v);
5040 exp->e1 = new VarExp(exp->e1->loc, v);
5041 }
5042
5043 /* Rewrite as:
5044 * auto tmp = e1; ++e1; tmp
5045 */
5046 VarDeclaration *tmp = copyToTemp(0, "__pitmp", exp->e1);
5047 Expression *ea = new DeclarationExp(exp->loc, tmp);
5048
5049 Expression *eb = exp->e1->syntaxCopy();
5050 eb = new PreExp(exp->op == TOKplusplus ? TOKpreplusplus : TOKpreminusminus, exp->loc, eb);
5051
5052 Expression *ec = new VarExp(exp->loc, tmp);
5053
5054 // Combine de,ea,eb,ec
5055 if (de)
5056 ea = new CommaExp(exp->loc, de, ea);
5057 e = new CommaExp(exp->loc, ea, eb);
5058 e = new CommaExp(exp->loc, e, ec);
5059 e = semantic(e, sc);
5060 result = e;
5061 return;
5062 }
5063
5064 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1);
5065
5066 e = exp;
5067 if (exp->e1->checkScalar())
5068 return setError();
5069 if (exp->e1->checkNoBool())
5070 return setError();
5071
5072 if (exp->e1->type->ty == Tpointer)
5073 e = scaleFactor(exp, sc);
5074 else
5075 exp->e2 = exp->e2->castTo(sc, exp->e1->type);
5076 e->type = exp->e1->type;
5077 result = e;
5078 }
5079
visit(PreExp * exp)5080 void visit(PreExp *exp)
5081 {
5082 Expression *e = exp->op_overload(sc);
5083 // printf("PreExp::semantic('%s')\n", exp->toChars());
5084
5085 if (e)
5086 {
5087 result = e;
5088 return;
5089 }
5090
5091 // Rewrite as e1+=1 or e1-=1
5092 if (exp->op == TOKpreplusplus)
5093 e = new AddAssignExp(exp->loc, exp->e1, new IntegerExp(exp->loc, 1, Type::tint32));
5094 else
5095 e = new MinAssignExp(exp->loc, exp->e1, new IntegerExp(exp->loc, 1, Type::tint32));
5096 result = semantic(e, sc);
5097 }
5098
visit(AssignExp * exp)5099 void visit(AssignExp *exp)
5100 {
5101 //printf("e1->op = %d, '%s'\n", exp->e1->op, Token::toChars(exp->e1->op));
5102 //printf("e2->op = %d, '%s'\n", exp->e2->op, Token::toChars(exp->e2->op));
5103 if (exp->type)
5104 {
5105 result = exp;
5106 return;
5107 }
5108
5109 Expression *e1old = exp->e1;
5110
5111 if (exp->e2->op == TOKcomma)
5112 {
5113 /* Rewrite to get rid of the comma from rvalue
5114 */
5115 if (!((CommaExp *)exp->e2)->isGenerated)
5116 exp->deprecation("Using the result of a comma expression is deprecated");
5117 Expression *e0;
5118 exp->e2 = Expression::extractLast(exp->e2, &e0);
5119 Expression *e = Expression::combine(e0, exp);
5120 result = semantic(e, sc);
5121 return;
5122 }
5123
5124 /* Look for operator overloading of a[arguments] = e2.
5125 * Do it before e1->semantic() otherwise the ArrayExp will have been
5126 * converted to unary operator overloading already.
5127 */
5128 if (exp->e1->op == TOKarray)
5129 {
5130 Expression *res;
5131
5132 ArrayExp *ae = (ArrayExp *)exp->e1;
5133 ae->e1 = semantic(ae->e1, sc);
5134 ae->e1 = resolveProperties(sc, ae->e1);
5135 Expression *ae1old = ae->e1;
5136
5137 const bool maybeSlice =
5138 (ae->arguments->dim == 0 ||
5139 (ae->arguments->dim == 1 && (*ae->arguments)[0]->op == TOKinterval));
5140 IntervalExp *ie = NULL;
5141 if (maybeSlice && ae->arguments->dim)
5142 {
5143 assert((*ae->arguments)[0]->op == TOKinterval);
5144 ie = (IntervalExp *)(*ae->arguments)[0];
5145 }
5146
5147 while (true)
5148 {
5149 if (ae->e1->op == TOKerror)
5150 {
5151 result = ae->e1;
5152 return;
5153 }
5154 Expression *e0 = NULL;
5155 Expression *ae1save = ae->e1;
5156 ae->lengthVar = NULL;
5157
5158 Type *t1b = ae->e1->type->toBasetype();
5159 AggregateDeclaration *ad = isAggregate(t1b);
5160 if (!ad)
5161 break;
5162 if (search_function(ad, Id::indexass))
5163 {
5164 // Deal with $
5165 res = resolveOpDollar(sc, ae, &e0);
5166 if (!res) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
5167 goto Lfallback;
5168 if (res->op == TOKerror)
5169 {
5170 result = res;
5171 return;
5172 }
5173
5174 res = semantic(exp->e2, sc);
5175 if (res->op == TOKerror)
5176 {
5177 result = res;
5178 return;
5179 }
5180 exp->e2 = res;
5181
5182 /* Rewrite (a[arguments] = e2) as:
5183 * a.opIndexAssign(e2, arguments)
5184 */
5185 Expressions *a = (Expressions *)ae->arguments->copy();
5186 a->insert(0, exp->e2);
5187 res = new DotIdExp(exp->loc, ae->e1, Id::indexass);
5188 res = new CallExp(exp->loc, res, a);
5189 if (maybeSlice) // a[] = e2 might be: a.opSliceAssign(e2)
5190 res = trySemantic(res, sc);
5191 else
5192 res = semantic(res, sc);
5193 if (res)
5194 {
5195 res = Expression::combine(e0, res);
5196 result = res;
5197 return;
5198 }
5199 }
5200 Lfallback:
5201 if (maybeSlice && search_function(ad, Id::sliceass))
5202 {
5203 // Deal with $
5204 res = resolveOpDollar(sc, ae, ie, &e0);
5205 if (res->op == TOKerror)
5206 {
5207 result = res;
5208 return;
5209 }
5210
5211 res = semantic(exp->e2, sc);
5212 if (res->op == TOKerror)
5213 {
5214 result = res;
5215 return;
5216 }
5217 exp->e2 = res;
5218
5219 /* Rewrite (a[i..j] = e2) as:
5220 * a.opSliceAssign(e2, i, j)
5221 */
5222 Expressions *a = new Expressions();
5223 a->push(exp->e2);
5224 if (ie)
5225 {
5226 a->push(ie->lwr);
5227 a->push(ie->upr);
5228 }
5229 res = new DotIdExp(exp->loc, ae->e1, Id::sliceass);
5230 res = new CallExp(exp->loc, res, a);
5231 res = semantic(res, sc);
5232 res = Expression::combine(e0, res);
5233 result = res;
5234 return;
5235 }
5236
5237 // No operator overloading member function found yet, but
5238 // there might be an alias this to try.
5239 if (ad->aliasthis && t1b != ae->att1)
5240 {
5241 if (!ae->att1 && t1b->checkAliasThisRec())
5242 ae->att1 = t1b;
5243
5244 /* Rewrite (a[arguments] op e2) as:
5245 * a.aliasthis[arguments] op e2
5246 */
5247 ae->e1 = resolveAliasThis(sc, ae1save, true);
5248 if (ae->e1)
5249 continue;
5250 }
5251 break;
5252 }
5253 ae->e1 = ae1old; // recovery
5254 ae->lengthVar = NULL;
5255 }
5256
5257 /* Run exp->e1 semantic.
5258 */
5259 {
5260 Expression *e1x = exp->e1;
5261
5262 /* With UFCS, e.f = value
5263 * Could mean:
5264 * .f(e, value)
5265 * or:
5266 * .f(e) = value
5267 */
5268 if (e1x->op == TOKdotti)
5269 {
5270 DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)e1x;
5271 Expression *e = semanticY(dti, sc, 1);
5272 if (!e)
5273 {
5274 result = resolveUFCSProperties(sc, e1x, exp->e2);
5275 return;
5276 }
5277 e1x = e;
5278 }
5279 else if (e1x->op == TOKdotid)
5280 {
5281 DotIdExp *die = (DotIdExp *)e1x;
5282 Expression *e = semanticY(die, sc, 1);
5283 if (e && isDotOpDispatch(e))
5284 {
5285 unsigned errors = global.startGagging();
5286 e = resolvePropertiesX(sc, e, exp->e2);
5287 if (global.endGagging(errors))
5288 e = NULL; /* fall down to UFCS */
5289 else
5290 {
5291 result = e;
5292 return;
5293 }
5294 }
5295 if (!e)
5296 {
5297 result = resolveUFCSProperties(sc, e1x, exp->e2);
5298 return;
5299 }
5300 e1x = e;
5301 }
5302 else
5303 {
5304 if (e1x->op == TOKslice)
5305 ((SliceExp *)e1x)->arrayop = true;
5306
5307 e1x = semantic(e1x, sc);
5308 }
5309
5310 /* We have f = value.
5311 * Could mean:
5312 * f(value)
5313 * or:
5314 * f() = value
5315 */
5316 if (Expression *e = resolvePropertiesX(sc, e1x, exp->e2))
5317 {
5318 result = e;
5319 return;
5320 }
5321 if (e1x->checkRightThis(sc))
5322 return setError();
5323 exp->e1 = e1x;
5324 assert(exp->e1->type);
5325 }
5326 Type *t1 = exp->e1->type->toBasetype();
5327
5328 /* Run exp->e2 semantic.
5329 * Different from other binary expressions, the analysis of e2
5330 * depends on the result of e1 in assignments.
5331 */
5332 {
5333 Expression *e2x = inferType(exp->e2, t1->baseElemOf());
5334
5335 e2x = semantic(e2x, sc);
5336 e2x = resolveProperties(sc, e2x);
5337
5338 if (e2x->op == TOKtype)
5339 e2x = resolveAliasThis(sc, e2x); //https://issues.dlang.org/show_bug.cgi?id=17684
5340 if (e2x->op == TOKerror)
5341 {
5342 result = e2x;
5343 return;
5344 }
5345 if (e2x->checkValue())
5346 return setError();
5347 exp->e2 = e2x;
5348 }
5349
5350 /* Rewrite tuple assignment as a tuple of assignments.
5351 */
5352 {
5353 Expression *e2x = exp->e2;
5354
5355 Ltupleassign:
5356 if (exp->e1->op == TOKtuple && e2x->op == TOKtuple)
5357 {
5358 TupleExp *tup1 = (TupleExp *)exp->e1;
5359 TupleExp *tup2 = (TupleExp *)e2x;
5360 size_t dim = tup1->exps->dim;
5361 Expression *e = NULL;
5362 if (dim != tup2->exps->dim)
5363 {
5364 exp->error("mismatched tuple lengths, %d and %d", (int)dim, (int)tup2->exps->dim);
5365 return setError();
5366 }
5367 if (dim == 0)
5368 {
5369 e = new IntegerExp(exp->loc, 0, Type::tint32);
5370 e = new CastExp(exp->loc, e, Type::tvoid); // avoid "has no effect" error
5371 e = Expression::combine(Expression::combine(tup1->e0, tup2->e0), e);
5372 }
5373 else
5374 {
5375 Expressions *exps = new Expressions;
5376 exps->setDim(dim);
5377 for (size_t i = 0; i < dim; i++)
5378 {
5379 Expression *ex1 = (*tup1->exps)[i];
5380 Expression *ex2 = (*tup2->exps)[i];
5381 (*exps)[i] = new AssignExp(exp->loc, ex1, ex2);
5382 }
5383 e = new TupleExp(exp->loc, Expression::combine(tup1->e0, tup2->e0), exps);
5384 }
5385 result = semantic(e, sc);
5386 return;
5387 }
5388
5389 /* Look for form: e1 = e2->aliasthis.
5390 */
5391 if (exp->e1->op == TOKtuple)
5392 {
5393 TupleDeclaration *td = isAliasThisTuple(e2x);
5394 if (!td)
5395 goto Lnomatch;
5396
5397 assert(exp->e1->type->ty == Ttuple);
5398 TypeTuple *tt = (TypeTuple *)exp->e1->type;
5399
5400 Expression *e0 = NULL;
5401 Expression *ev = extractSideEffect(sc, "__tup", &e0, e2x);
5402
5403 Expressions *iexps = new Expressions();
5404 iexps->push(ev);
5405
5406 for (size_t u = 0; u < iexps->dim ; u++)
5407 {
5408 Lexpand:
5409 Expression *e = (*iexps)[u];
5410
5411 Parameter *arg = Parameter::getNth(tt->arguments, u);
5412 //printf("[%d] iexps->dim = %d, ", u, iexps->dim);
5413 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars());
5414 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars());
5415
5416 if (!arg || !e->type->implicitConvTo(arg->type))
5417 {
5418 // expand initializer to tuple
5419 if (expandAliasThisTuples(iexps, u) != -1)
5420 {
5421 if (iexps->dim <= u)
5422 break;
5423 goto Lexpand;
5424 }
5425 goto Lnomatch;
5426 }
5427 }
5428 e2x = new TupleExp(e2x->loc, e0, iexps);
5429 e2x = semantic(e2x, sc);
5430 if (e2x->op == TOKerror)
5431 {
5432 result = e2x;
5433 return;
5434 }
5435 // Do not need to overwrite exp->e2
5436 goto Ltupleassign;
5437 }
5438 Lnomatch:
5439 ;
5440 }
5441
5442 /* Inside constructor, if this is the first assignment of object field,
5443 * rewrite this to initializing the field.
5444 */
5445 if (exp->op == TOKassign && exp->e1->checkModifiable(sc) == 2)
5446 {
5447 //printf("[%s] change to init - %s\n", exp->loc.toChars(), toChars());
5448 exp->op = TOKconstruct;
5449
5450 // Bugzilla 13515: set Index::modifiable flag for complex AA element initialization
5451 if (exp->e1->op == TOKindex)
5452 {
5453 Expression *e1x = ((IndexExp *)exp->e1)->markSettingAAElem();
5454 if (e1x->op == TOKerror)
5455 {
5456 result = e1x;
5457 return;
5458 }
5459 }
5460 }
5461 else if (exp->op == TOKconstruct && exp->e1->op == TOKvar &&
5462 ((VarExp *)exp->e1)->var->storage_class & (STCout | STCref))
5463 {
5464 exp->memset |= referenceInit;
5465 }
5466
5467 /* If it is an assignment from a 'foreign' type,
5468 * check for operator overloading.
5469 */
5470 if (exp->memset & referenceInit)
5471 {
5472 // If this is an initialization of a reference,
5473 // do nothing
5474 }
5475 else if (t1->ty == Tstruct)
5476 {
5477 Expression *e1x = exp->e1;
5478 Expression *e2x = exp->e2;
5479 StructDeclaration *sd = ((TypeStruct *)t1)->sym;
5480
5481 if (exp->op == TOKconstruct)
5482 {
5483 Type *t2 = e2x->type->toBasetype();
5484 if (t2->ty == Tstruct && sd == ((TypeStruct *)t2)->sym)
5485 {
5486 sd->size(exp->loc);
5487 if (sd->sizeok != SIZEOKdone)
5488 return setError();
5489 if (!sd->ctor)
5490 sd->ctor = sd->searchCtor();
5491
5492 // Bugzilla 15661: Look for the form from last of comma chain.
5493 Expression *e2y = e2x;
5494 while (e2y->op == TOKcomma)
5495 e2y = ((CommaExp *)e2y)->e2;
5496
5497 CallExp *ce = (e2y->op == TOKcall) ? (CallExp *)e2y : NULL;
5498 DotVarExp *dve = (ce && ce->e1->op == TOKdotvar)
5499 ? (DotVarExp *)ce->e1 : NULL;
5500 if (sd->ctor && ce && dve && dve->var->isCtorDeclaration() &&
5501 e2y->type->implicitConvTo(t1))
5502 {
5503 /* Look for form of constructor call which is:
5504 * __ctmp.ctor(arguments...)
5505 */
5506
5507 /* Before calling the constructor, initialize
5508 * variable with a bit copy of the default
5509 * initializer
5510 */
5511 AssignExp *ae = exp;
5512 if (sd->zeroInit == 1 && !sd->isNested())
5513 {
5514 // Bugzilla 14606: Always use BlitExp for the special expression: (struct = 0)
5515 ae = new BlitExp(ae->loc, ae->e1, new IntegerExp(exp->loc, 0, Type::tint32));
5516 }
5517 else
5518 {
5519 // Keep ae->op == TOKconstruct
5520 ae->e2 = sd->isNested() ? t1->defaultInitLiteral(exp->loc) : t1->defaultInit(exp->loc);
5521 }
5522 ae->type = e1x->type;
5523
5524 /* Replace __ctmp being constructed with e1.
5525 * We need to copy constructor call expression,
5526 * because it may be used in other place.
5527 */
5528 DotVarExp *dvx = (DotVarExp *)dve->copy();
5529 dvx->e1 = e1x;
5530 CallExp *cx = (CallExp *)ce->copy();
5531 cx->e1 = dvx;
5532
5533 Expression *e0;
5534 Expression::extractLast(e2x, &e0);
5535
5536 Expression *e = Expression::combine(ae, cx);
5537 e = Expression::combine(e0, e);
5538 e = semantic(e, sc);
5539 result = e;
5540 return;
5541 }
5542 if (sd->postblit)
5543 {
5544 /* We have a copy constructor for this
5545 */
5546 if (e2x->op == TOKquestion)
5547 {
5548 /* Rewrite as:
5549 * a ? e1 = b : e1 = c;
5550 */
5551 CondExp *econd = (CondExp *)e2x;
5552 Expression *ea1 = new ConstructExp(econd->e1->loc, e1x, econd->e1);
5553 Expression *ea2 = new ConstructExp(econd->e1->loc, e1x, econd->e2);
5554 Expression *e = new CondExp(exp->loc, econd->econd, ea1, ea2);
5555 result = semantic(e, sc);
5556 return;
5557 }
5558
5559 if (e2x->isLvalue())
5560 {
5561 if (!e2x->type->implicitConvTo(e1x->type))
5562 {
5563 exp->error("conversion error from %s to %s", e2x->type->toChars(), e1x->type->toChars());
5564 return setError();
5565 }
5566
5567 /* Rewrite as:
5568 * (e1 = e2).postblit();
5569 *
5570 * Blit assignment e1 = e2 returns a reference to the original e1,
5571 * then call the postblit on it.
5572 */
5573 Expression *e = e1x->copy();
5574 e->type = e->type->mutableOf();
5575 e = new BlitExp(exp->loc, e, e2x);
5576 e = new DotVarExp(exp->loc, e, sd->postblit, false);
5577 e = new CallExp(exp->loc, e);
5578 result = semantic(e, sc);
5579 return;
5580 }
5581 else
5582 {
5583 /* The struct value returned from the function is transferred
5584 * so should not call the destructor on it.
5585 */
5586 e2x = valueNoDtor(e2x);
5587 }
5588 }
5589 }
5590 else if (!e2x->implicitConvTo(t1))
5591 {
5592 sd->size(exp->loc);
5593 if (sd->sizeok != SIZEOKdone)
5594 return setError();
5595 if (!sd->ctor)
5596 sd->ctor = sd->searchCtor();
5597
5598 if (sd->ctor)
5599 {
5600 /* Look for implicit constructor call
5601 * Rewrite as:
5602 * e1 = init, e1.ctor(e2)
5603 */
5604 Expression *einit;
5605 einit = new BlitExp(exp->loc, e1x, e1x->type->defaultInit(exp->loc));
5606 einit->type = e1x->type;
5607
5608 Expression *e;
5609 e = new DotIdExp(exp->loc, e1x, Id::ctor);
5610 e = new CallExp(exp->loc, e, e2x);
5611 e = new CommaExp(exp->loc, einit, e);
5612 e = semantic(e, sc);
5613 result = e;
5614 return;
5615 }
5616 if (search_function(sd, Id::call))
5617 {
5618 /* Look for static opCall
5619 * (See bugzilla 2702 for more discussion)
5620 * Rewrite as:
5621 * e1 = typeof(e1).opCall(arguments)
5622 */
5623 e2x = typeDotIdExp(e2x->loc, e1x->type, Id::call);
5624 e2x = new CallExp(exp->loc, e2x, exp->e2);
5625
5626 e2x = semantic(e2x, sc);
5627 e2x = resolveProperties(sc, e2x);
5628 if (e2x->op == TOKerror)
5629 {
5630 result = e2x;
5631 return;
5632 }
5633 if (e2x->checkValue())
5634 return setError();
5635 }
5636 }
5637 else // Bugzilla 11355
5638 {
5639 AggregateDeclaration *ad2 = isAggregate(e2x->type);
5640 if (ad2 && ad2->aliasthis && !(exp->att2 && e2x->type == exp->att2))
5641 {
5642 if (!exp->att2 && exp->e2->type->checkAliasThisRec())
5643 exp->att2 = exp->e2->type;
5644
5645 /* Rewrite (e1 op e2) as:
5646 * (e1 op e2.aliasthis)
5647 */
5648 exp->e2 = new DotIdExp(exp->e2->loc, exp->e2, ad2->aliasthis->ident);
5649 result = semantic(exp, sc);
5650 return;
5651 }
5652 }
5653 }
5654 else if (exp->op == TOKassign)
5655 {
5656 if (e1x->op == TOKindex &&
5657 ((IndexExp *)e1x)->e1->type->toBasetype()->ty == Taarray)
5658 {
5659 /*
5660 * Rewrite:
5661 * aa[key] = e2;
5662 * as:
5663 * ref __aatmp = aa;
5664 * ref __aakey = key;
5665 * ref __aaval = e2;
5666 * (__aakey in __aatmp
5667 * ? __aatmp[__aakey].opAssign(__aaval)
5668 * : ConstructExp(__aatmp[__aakey], __aaval));
5669 */
5670 IndexExp *ie = (IndexExp *)e1x;
5671 Type *t2 = e2x->type->toBasetype();
5672
5673 Expression *e0 = NULL;
5674 Expression *ea = extractSideEffect(sc, "__aatmp", &e0, ie->e1);
5675 Expression *ek = extractSideEffect(sc, "__aakey", &e0, ie->e2);
5676 Expression *ev = extractSideEffect(sc, "__aaval", &e0, e2x);
5677
5678 AssignExp *ae = (AssignExp *)exp->copy();
5679 ae->e1 = new IndexExp(exp->loc, ea, ek);
5680 ae->e1 = semantic(ae->e1, sc);
5681 ae->e1 = ae->e1->optimize(WANTvalue);
5682 ae->e2 = ev;
5683 Expression *e = ae->op_overload(sc);
5684 if (e)
5685 {
5686 Expression *ey = NULL;
5687 if (t2->ty == Tstruct && sd == t2->toDsymbol(sc))
5688 {
5689 ey = ev;
5690 }
5691 else if (!ev->implicitConvTo(ie->type) && sd->ctor)
5692 {
5693 // Look for implicit constructor call
5694 // Rewrite as S().ctor(e2)
5695 ey = new StructLiteralExp(exp->loc, sd, NULL);
5696 ey = new DotIdExp(exp->loc, ey, Id::ctor);
5697 ey = new CallExp(exp->loc, ey, ev);
5698 ey = trySemantic(ey, sc);
5699 }
5700 if (ey)
5701 {
5702 Expression *ex;
5703 ex = new IndexExp(exp->loc, ea, ek);
5704 ex = semantic(ex, sc);
5705 ex = ex->optimize(WANTvalue);
5706 ex = ex->modifiableLvalue(sc, ex); // allocate new slot
5707 ey = new ConstructExp(exp->loc, ex, ey);
5708 ey = semantic(ey, sc);
5709 if (ey->op == TOKerror)
5710 {
5711 result = ey;
5712 return;
5713 }
5714 ex = e;
5715
5716 // Bugzilla 14144: The whole expression should have the common type
5717 // of opAssign() return and assigned AA entry.
5718 // Even if there's no common type, expression should be typed as void.
5719 Type *t = NULL;
5720 if (!typeMerge(sc, TOKquestion, &t, &ex, &ey))
5721 {
5722 ex = new CastExp(ex->loc, ex, Type::tvoid);
5723 ey = new CastExp(ey->loc, ey, Type::tvoid);
5724 }
5725 e = new CondExp(exp->loc, new InExp(exp->loc, ek, ea), ex, ey);
5726 }
5727 e = Expression::combine(e0, e);
5728 e = semantic(e, sc);
5729 result = e;
5730 return;
5731 }
5732 }
5733 else
5734 {
5735 Expression *e = exp->op_overload(sc);
5736 if (e)
5737 {
5738 result = e;
5739 return;
5740 }
5741 }
5742 }
5743 else
5744 assert(exp->op == TOKblit);
5745
5746 exp->e1 = e1x;
5747 exp->e2 = e2x;
5748 }
5749 else if (t1->ty == Tclass)
5750 {
5751 // Disallow assignment operator overloads for same type
5752 if (exp->op == TOKassign && !exp->e2->implicitConvTo(exp->e1->type))
5753 {
5754 Expression *e = exp->op_overload(sc);
5755 if (e)
5756 {
5757 result = e;
5758 return;
5759 }
5760 }
5761 }
5762 else if (t1->ty == Tsarray)
5763 {
5764 // SliceExp cannot have static array type without context inference.
5765 assert(exp->e1->op != TOKslice);
5766
5767 Expression *e1x = exp->e1;
5768 Expression *e2x = exp->e2;
5769
5770 if (e2x->implicitConvTo(e1x->type))
5771 {
5772 if (exp->op != TOKblit &&
5773 ((e2x->op == TOKslice && ((UnaExp *)e2x)->e1->isLvalue()) ||
5774 (e2x->op == TOKcast && ((UnaExp *)e2x)->e1->isLvalue()) ||
5775 (e2x->op != TOKslice && e2x->isLvalue())))
5776 {
5777 if (e1x->checkPostblit(sc, t1))
5778 return setError();
5779 }
5780
5781 // e2 matches to t1 because of the implicit length match, so
5782 if (isUnaArrayOp(e2x->op) || isBinArrayOp(e2x->op))
5783 {
5784 // convert e1 to e1[]
5785 // e.g. e1[] = a[] + b[];
5786 SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL);
5787 sle->arrayop = true;
5788 e1x = semantic(sle, sc);
5789 }
5790 else
5791 {
5792 // convert e2 to t1 later
5793 // e.g. e1 = [1, 2, 3];
5794 }
5795 }
5796 else
5797 {
5798 if (e2x->implicitConvTo(t1->nextOf()->arrayOf()) > MATCHnomatch)
5799 {
5800 uinteger_t dim1 = ((TypeSArray *)t1)->dim->toInteger();
5801 uinteger_t dim2 = dim1;
5802 if (e2x->op == TOKarrayliteral)
5803 {
5804 ArrayLiteralExp *ale = (ArrayLiteralExp *)e2x;
5805 dim2 = ale->elements ? ale->elements->dim : 0;
5806 }
5807 else if (e2x->op == TOKslice)
5808 {
5809 Type *tx = toStaticArrayType((SliceExp *)e2x);
5810 if (tx)
5811 dim2 = ((TypeSArray *)tx)->dim->toInteger();
5812 }
5813 if (dim1 != dim2)
5814 {
5815 exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2);
5816 return setError();
5817 }
5818 }
5819
5820 // May be block or element-wise assignment, so
5821 // convert e1 to e1[]
5822 if (exp->op != TOKassign)
5823 {
5824 // If multidimensional static array, treat as one large array
5825 dinteger_t dim = ((TypeSArray *)t1)->dim->toInteger();
5826 Type *t = t1;
5827 while (1)
5828 {
5829 t = t->nextOf()->toBasetype();
5830 if (t->ty != Tsarray)
5831 break;
5832 dim *= ((TypeSArray *)t)->dim->toInteger();
5833 e1x->type = t->nextOf()->sarrayOf(dim);
5834 }
5835 }
5836 SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL);
5837 sle->arrayop = true;
5838 e1x = semantic(sle, sc);
5839 }
5840 if (e1x->op == TOKerror)
5841 {
5842 result = e1x;
5843 return;
5844 }
5845 if (e2x->op == TOKerror)
5846 {
5847 result = e2x;
5848 return;
5849 }
5850
5851 exp->e1 = e1x;
5852 exp->e2 = e2x;
5853 t1 = e1x->type->toBasetype();
5854 }
5855
5856 /* Check the mutability of e1.
5857 */
5858 if (exp->e1->op == TOKarraylength)
5859 {
5860 // e1 is not an lvalue, but we let code generator handle it
5861 ArrayLengthExp *ale = (ArrayLengthExp *)exp->e1;
5862
5863 Expression *ale1x = ale->e1;
5864 ale1x = ale1x->modifiableLvalue(sc, exp->e1);
5865 if (ale1x->op == TOKerror)
5866 {
5867 result = ale1x;
5868 return;
5869 }
5870 ale->e1 = ale1x;
5871
5872 Type *tn = ale->e1->type->toBasetype()->nextOf();
5873 checkDefCtor(ale->loc, tn);
5874 semanticTypeInfo(sc, tn);
5875 }
5876 else if (exp->e1->op == TOKslice)
5877 {
5878 Type *tn = exp->e1->type->nextOf();
5879 if (exp->op == TOKassign && !tn->isMutable())
5880 {
5881 exp->error("slice %s is not mutable", exp->e1->toChars());
5882 return setError();
5883 }
5884
5885 // For conditional operator, both branches need conversion.
5886 SliceExp *se = (SliceExp *)exp->e1;
5887 while (se->e1->op == TOKslice)
5888 se = (SliceExp *)se->e1;
5889 if (se->e1->op == TOKquestion &&
5890 se->e1->type->toBasetype()->ty == Tsarray)
5891 {
5892 se->e1 = se->e1->modifiableLvalue(sc, exp->e1);
5893 if (se->e1->op == TOKerror)
5894 {
5895 result = se->e1;
5896 return;
5897 }
5898 }
5899 }
5900 else
5901 {
5902 Expression *e1x = exp->e1;
5903
5904 // Try to do a decent error message with the expression
5905 // before it got constant folded
5906 if (e1x->op != TOKvar)
5907 e1x = e1x->optimize(WANTvalue);
5908
5909 if (exp->op == TOKassign)
5910 e1x = e1x->modifiableLvalue(sc, e1old);
5911
5912 if (e1x->op == TOKerror)
5913 {
5914 result = e1x;
5915 return;
5916 }
5917 exp->e1 = e1x;
5918 }
5919
5920 /* Tweak e2 based on the type of e1.
5921 */
5922 Expression *e2x = exp->e2;
5923 Type *t2 = e2x->type->toBasetype();
5924
5925 // If it is a array, get the element type. Note that it may be
5926 // multi-dimensional.
5927 Type *telem = t1;
5928 while (telem->ty == Tarray)
5929 telem = telem->nextOf();
5930
5931 if (exp->e1->op == TOKslice &&
5932 t1->nextOf() && (telem->ty != Tvoid || e2x->op == TOKnull) &&
5933 e2x->implicitConvTo(t1->nextOf())
5934 )
5935 {
5936 // Check for block assignment. If it is of type void[], void[][], etc,
5937 // '= null' is the only allowable block assignment (Bug 7493)
5938 // memset
5939 exp->memset |= blockAssign; // make it easy for back end to tell what this is
5940 e2x = e2x->implicitCastTo(sc, t1->nextOf());
5941 if (exp->op != TOKblit && e2x->isLvalue() &&
5942 exp->e1->checkPostblit(sc, t1->nextOf()))
5943 return setError();
5944 }
5945 else if (exp->e1->op == TOKslice &&
5946 (t2->ty == Tarray || t2->ty == Tsarray) &&
5947 t2->nextOf()->implicitConvTo(t1->nextOf()))
5948 {
5949 // Check element-wise assignment.
5950
5951 /* If assigned elements number is known at compile time,
5952 * check the mismatch.
5953 */
5954 SliceExp *se1 = (SliceExp *)exp->e1;
5955 TypeSArray *tsa1 = (TypeSArray *)toStaticArrayType(se1);
5956 TypeSArray *tsa2 = NULL;
5957 if (e2x->op == TOKarrayliteral)
5958 tsa2 = (TypeSArray *)t2->nextOf()->sarrayOf(((ArrayLiteralExp *)e2x)->elements->dim);
5959 else if (e2x->op == TOKslice)
5960 tsa2 = (TypeSArray *)toStaticArrayType((SliceExp *)e2x);
5961 else if (t2->ty == Tsarray)
5962 tsa2 = (TypeSArray *)t2;
5963 if (tsa1 && tsa2)
5964 {
5965 uinteger_t dim1 = tsa1->dim->toInteger();
5966 uinteger_t dim2 = tsa2->dim->toInteger();
5967 if (dim1 != dim2)
5968 {
5969 exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2);
5970 return setError();
5971 }
5972 }
5973
5974 if (exp->op != TOKblit &&
5975 ((e2x->op == TOKslice && ((UnaExp *)e2x)->e1->isLvalue()) ||
5976 (e2x->op == TOKcast && ((UnaExp *)e2x)->e1->isLvalue()) ||
5977 (e2x->op != TOKslice && e2x->isLvalue())))
5978 {
5979 if (exp->e1->checkPostblit(sc, t1->nextOf()))
5980 return setError();
5981 }
5982
5983 if (0 && global.params.warnings != DIAGNOSTICoff && !global.gag && exp->op == TOKassign &&
5984 e2x->op != TOKslice && e2x->op != TOKassign &&
5985 e2x->op != TOKarrayliteral && e2x->op != TOKstring &&
5986 !(e2x->op == TOKadd || e2x->op == TOKmin ||
5987 e2x->op == TOKmul || e2x->op == TOKdiv ||
5988 e2x->op == TOKmod || e2x->op == TOKxor ||
5989 e2x->op == TOKand || e2x->op == TOKor ||
5990 e2x->op == TOKpow ||
5991 e2x->op == TOKtilde || e2x->op == TOKneg))
5992 {
5993 const char* e1str = exp->e1->toChars();
5994 const char* e2str = e2x->toChars();
5995 exp->warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s",
5996 e1str, e2str, e1str, e2str);
5997 }
5998
5999 Type *t2n = t2->nextOf();
6000 Type *t1n = t1->nextOf();
6001 int offset;
6002 if (t2n->equivalent(t1n) ||
6003 (t1n->isBaseOf(t2n, &offset) && offset == 0))
6004 {
6005 /* Allow copy of distinct qualifier elements.
6006 * eg.
6007 * char[] dst; const(char)[] src;
6008 * dst[] = src;
6009 *
6010 * class C {} class D : C {}
6011 * C[2] ca; D[] da;
6012 * ca[] = da;
6013 */
6014 if (isArrayOpValid(e2x))
6015 {
6016 // Don't add CastExp to keep AST for array operations
6017 e2x = e2x->copy();
6018 e2x->type = exp->e1->type->constOf();
6019 }
6020 else
6021 e2x = e2x->castTo(sc, exp->e1->type->constOf());
6022 }
6023 else
6024 {
6025 /* Bugzilla 15778: A string literal has an array type of immutable
6026 * elements by default, and normally it cannot be convertible to
6027 * array type of mutable elements. But for element-wise assignment,
6028 * elements need to be const at best. So we should give a chance
6029 * to change code unit size for polysemous string literal.
6030 */
6031 if (e2x->op == TOKstring)
6032 e2x = e2x->implicitCastTo(sc, exp->e1->type->constOf());
6033 else
6034 e2x = e2x->implicitCastTo(sc, exp->e1->type);
6035 }
6036 if (t1n->toBasetype()->ty == Tvoid && t2n->toBasetype()->ty == Tvoid)
6037 {
6038 if (!sc->intypeof && sc->func && sc->func->setUnsafe())
6039 {
6040 exp->error("cannot copy void[] to void[] in @safe code");
6041 return setError();
6042 }
6043 }
6044 }
6045 else
6046 {
6047 if (0 && global.params.warnings != DIAGNOSTICoff && !global.gag && exp->op == TOKassign &&
6048 t1->ty == Tarray && t2->ty == Tsarray &&
6049 e2x->op != TOKslice &&
6050 t2->implicitConvTo(t1))
6051 { // Disallow ar[] = sa (Converted to ar[] = sa[])
6052 // Disallow da = sa (Converted to da = sa[])
6053 const char* e1str = exp->e1->toChars();
6054 const char* e2str = e2x->toChars();
6055 const char* atypestr = exp->e1->op == TOKslice ? "element-wise" : "slice";
6056 exp->warning("explicit %s assignment %s = (%s)[] is better than %s = %s",
6057 atypestr, e1str, e2str, e1str, e2str);
6058 }
6059 if (exp->op == TOKblit)
6060 e2x = e2x->castTo(sc, exp->e1->type);
6061 else
6062 e2x = e2x->implicitCastTo(sc, exp->e1->type);
6063 }
6064 if (e2x->op == TOKerror)
6065 {
6066 result = e2x;
6067 return;
6068 }
6069 exp->e2 = e2x;
6070 t2 = exp->e2->type->toBasetype();
6071
6072 /* Look for array operations
6073 */
6074 if ((t2->ty == Tarray || t2->ty == Tsarray) && isArrayOpValid(exp->e2))
6075 {
6076 // Look for valid array operations
6077 if (!(exp->memset & blockAssign) && exp->e1->op == TOKslice &&
6078 (isUnaArrayOp(exp->e2->op) || isBinArrayOp(exp->e2->op)))
6079 {
6080 exp->type = exp->e1->type;
6081 if (exp->op == TOKconstruct) // Bugzilla 10282: tweak mutability of e1 element
6082 exp->e1->type = exp->e1->type->nextOf()->mutableOf()->arrayOf();
6083 result = arrayOp(exp, sc);
6084 return;
6085 }
6086
6087 // Drop invalid array operations in e2
6088 // d = a[] + b[], d = (a[] + b[])[0..2], etc
6089 if (checkNonAssignmentArrayOp(exp->e2, !(exp->memset & blockAssign) && exp->op == TOKassign))
6090 return setError();
6091
6092 // Remains valid array assignments
6093 // d = d[], d = [1,2,3], etc
6094 }
6095
6096 /* Don't allow assignment to classes that were allocated on the stack with:
6097 * scope Class c = new Class();
6098 */
6099
6100 if (exp->e1->op == TOKvar && exp->op == TOKassign)
6101 {
6102 VarExp *ve = (VarExp *)exp->e1;
6103 VarDeclaration *vd = ve->var->isVarDeclaration();
6104 if (vd && (vd->onstack || vd->mynew))
6105 {
6106 assert(t1->ty == Tclass);
6107 exp->error("cannot rebind scope variables");
6108 }
6109 }
6110 if (exp->e1->op == TOKvar && ((VarExp *)exp->e1)->var->ident == Id::ctfe)
6111 {
6112 exp->error("cannot modify compiler-generated variable __ctfe");
6113 }
6114
6115 exp->type = exp->e1->type;
6116 assert(exp->type);
6117 Expression *res = exp->op == TOKassign ? exp->reorderSettingAAElem(sc) : exp;
6118 checkAssignEscape(sc, res, false);
6119 result = res;
6120 }
6121
visit(CatAssignExp * exp)6122 void visit(CatAssignExp *exp)
6123 {
6124 if (exp->type)
6125 {
6126 result = exp;
6127 return;
6128 }
6129
6130 //printf("CatAssignExp::semantic() %s\n", toChars());
6131 Expression *e = exp->op_overload(sc);
6132 if (e)
6133 {
6134 result = e;
6135 return;
6136 }
6137
6138 if (exp->e1->op == TOKslice)
6139 {
6140 SliceExp *se = (SliceExp *)exp->e1;
6141 if (se->e1->type->toBasetype()->ty == Tsarray)
6142 {
6143 exp->error("cannot append to static array %s", se->e1->type->toChars());
6144 return setError();
6145 }
6146 }
6147
6148 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1);
6149 if (exp->e1->op == TOKerror)
6150 {
6151 result = exp->e1;
6152 return;
6153 }
6154 if (exp->e2->op == TOKerror)
6155 {
6156 result = exp->e2;
6157 return;
6158 }
6159
6160 if (checkNonAssignmentArrayOp(exp->e2))
6161 return setError();
6162
6163 Type *tb1 = exp->e1->type->toBasetype();
6164 Type *tb1next = tb1->nextOf();
6165 Type *tb2 = exp->e2->type->toBasetype();
6166
6167 if ((tb1->ty == Tarray) &&
6168 (tb2->ty == Tarray || tb2->ty == Tsarray) &&
6169 (exp->e2->implicitConvTo(exp->e1->type)
6170 || (tb2->nextOf()->implicitConvTo(tb1next) &&
6171 (tb2->nextOf()->size(Loc()) == tb1next->size(Loc())))
6172 )
6173 )
6174 {
6175 // Append array
6176 if (exp->e1->checkPostblit(sc, tb1next))
6177 return setError();
6178 exp->e2 = exp->e2->castTo(sc, exp->e1->type);
6179 }
6180 else if ((tb1->ty == Tarray) &&
6181 exp->e2->implicitConvTo(tb1next)
6182 )
6183 {
6184 // Append element
6185 if (exp->e2->checkPostblit(sc, tb2))
6186 return setError();
6187 exp->e2 = exp->e2->castTo(sc, tb1next);
6188 exp->e2 = doCopyOrMove(sc, exp->e2);
6189 }
6190 else if (tb1->ty == Tarray &&
6191 (tb1next->ty == Tchar || tb1next->ty == Twchar) &&
6192 exp->e2->type->ty != tb1next->ty &&
6193 exp->e2->implicitConvTo(Type::tdchar)
6194 )
6195 { // Append dchar to char[] or wchar[]
6196 exp->e2 = exp->e2->castTo(sc, Type::tdchar);
6197
6198 /* Do not allow appending wchar to char[] because if wchar happens
6199 * to be a surrogate pair, nothing good can result.
6200 */
6201 }
6202 else
6203 {
6204 exp->error("cannot append type %s to type %s", tb2->toChars(), tb1->toChars());
6205 return setError();
6206 }
6207 if (exp->e2->checkValue())
6208 return setError();
6209
6210 exp->type = exp->e1->type;
6211 result = exp->reorderSettingAAElem(sc);
6212 }
6213
visit(PowAssignExp * exp)6214 void visit(PowAssignExp *exp)
6215 {
6216 if (exp->type)
6217 {
6218 result = exp;
6219 return;
6220 }
6221
6222 Expression *e = exp->op_overload(sc);
6223 if (e)
6224 {
6225 result = e;
6226 return;
6227 }
6228
6229 if (exp->e1->checkReadModifyWrite(exp->op, exp->e2))
6230 return setError();
6231
6232 assert(exp->e1->type && exp->e2->type);
6233 if (exp->e1->op == TOKslice || exp->e1->type->ty == Tarray || exp->e1->type->ty == Tsarray)
6234 {
6235 // T[] ^^= ...
6236 if (exp->e2->implicitConvTo(exp->e1->type->nextOf()))
6237 {
6238 // T[] ^^= T
6239 exp->e2 = exp->e2->castTo(sc, exp->e1->type->nextOf());
6240 }
6241 else if (Expression *ex = typeCombine(exp, sc))
6242 {
6243 result = ex;
6244 return;
6245 }
6246
6247 // Check element types are arithmetic
6248 Type *tb1 = exp->e1->type->nextOf()->toBasetype();
6249 Type *tb2 = exp->e2->type->toBasetype();
6250 if (tb2->ty == Tarray || tb2->ty == Tsarray)
6251 tb2 = tb2->nextOf()->toBasetype();
6252
6253 if ( (tb1->isintegral() || tb1->isfloating()) &&
6254 (tb2->isintegral() || tb2->isfloating()))
6255 {
6256 exp->type = exp->e1->type;
6257 result = arrayOp(exp, sc);
6258 return;
6259 }
6260 }
6261 else
6262 {
6263 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1);
6264 }
6265
6266 if ((exp->e1->type->isintegral() || exp->e1->type->isfloating()) &&
6267 (exp->e2->type->isintegral() || exp->e2->type->isfloating()))
6268 {
6269 Expression *e0 = NULL;
6270 e = exp->reorderSettingAAElem(sc);
6271 e = Expression::extractLast(e, &e0);
6272 assert(e == exp);
6273
6274 if (exp->e1->op == TOKvar)
6275 {
6276 // Rewrite: e1 = e1 ^^ e2
6277 e = new PowExp(exp->loc, exp->e1->syntaxCopy(), exp->e2);
6278 e = new AssignExp(exp->loc, exp->e1, e);
6279 }
6280 else
6281 {
6282 // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
6283 VarDeclaration *v = copyToTemp(STCref, "__powtmp", exp->e1);
6284 Expression *de = new DeclarationExp(exp->e1->loc, v);
6285 VarExp *ve = new VarExp(exp->e1->loc, v);
6286 e = new PowExp(exp->loc, ve, exp->e2);
6287 e = new AssignExp(exp->loc, new VarExp(exp->e1->loc, v), e);
6288 e = new CommaExp(exp->loc, de, e);
6289 }
6290 e = Expression::combine(e0, e);
6291 e = semantic(e, sc);
6292 result = e;
6293 return;
6294 }
6295 result = exp->incompatibleTypes();
6296 }
6297
visit(AddExp * exp)6298 void visit(AddExp *exp)
6299 {
6300 if (exp->type)
6301 {
6302 result = exp;
6303 return;
6304 }
6305
6306 if (Expression *ex = binSemanticProp(exp, sc))
6307 {
6308 result = ex;
6309 return;
6310 }
6311 Expression *e = exp->op_overload(sc);
6312 if (e)
6313 {
6314 result = e;
6315 return;
6316 }
6317
6318 Type *tb1 = exp->e1->type->toBasetype();
6319 Type *tb2 = exp->e2->type->toBasetype();
6320
6321 bool err = false;
6322 if (tb1->ty == Tdelegate ||
6323 (tb1->ty == Tpointer && tb1->nextOf()->ty == Tfunction))
6324 {
6325 err |= exp->e1->checkArithmetic();
6326 }
6327 if (tb2->ty == Tdelegate ||
6328 (tb2->ty == Tpointer && tb2->nextOf()->ty == Tfunction))
6329 {
6330 err |= exp->e2->checkArithmetic();
6331 }
6332 if (err)
6333 return setError();
6334
6335 if ((tb1->ty == Tpointer && exp->e2->type->isintegral()) ||
6336 (tb2->ty == Tpointer && exp->e1->type->isintegral()))
6337 {
6338 result = scaleFactor(exp, sc);
6339 return;
6340 }
6341
6342 if (tb1->ty == Tpointer && tb2->ty == Tpointer)
6343 {
6344 result = exp->incompatibleTypes();
6345 return;
6346 }
6347
6348 if (Expression *ex = typeCombine(exp, sc))
6349 {
6350 result = ex;
6351 return;
6352 }
6353
6354 Type *tb = exp->type->toBasetype();
6355 if (tb->ty == Tarray || tb->ty == Tsarray)
6356 {
6357 if (!isArrayOpValid(exp))
6358 {
6359 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
6360 return setError();
6361 }
6362 result = exp;
6363 return;
6364 }
6365
6366 tb1 = exp->e1->type->toBasetype();
6367 if (!Target::isVectorOpSupported(tb1, exp->op, tb2))
6368 {
6369 result = exp->incompatibleTypes();
6370 return;
6371 }
6372 if ((tb1->isreal() && exp->e2->type->isimaginary()) ||
6373 (tb1->isimaginary() && exp->e2->type->isreal()))
6374 {
6375 switch (exp->type->toBasetype()->ty)
6376 {
6377 case Tfloat32:
6378 case Timaginary32:
6379 exp->type = Type::tcomplex32;
6380 break;
6381
6382 case Tfloat64:
6383 case Timaginary64:
6384 exp->type = Type::tcomplex64;
6385 break;
6386
6387 case Tfloat80:
6388 case Timaginary80:
6389 exp->type = Type::tcomplex80;
6390 break;
6391
6392 default:
6393 assert(0);
6394 }
6395 }
6396 result = exp;
6397 }
6398
visit(MinExp * exp)6399 void visit(MinExp *exp)
6400 {
6401 if (exp->type)
6402 {
6403 result = exp;
6404 return;
6405 }
6406
6407 if (Expression *ex = binSemanticProp(exp, sc))
6408 {
6409 result = ex;
6410 return;
6411 }
6412 Expression *e = exp->op_overload(sc);
6413 if (e)
6414 {
6415 result = e;
6416 return;
6417 }
6418
6419 Type *t1 = exp->e1->type->toBasetype();
6420 Type *t2 = exp->e2->type->toBasetype();
6421
6422 bool err = false;
6423 if (t1->ty == Tdelegate ||
6424 (t1->ty == Tpointer && t1->nextOf()->ty == Tfunction))
6425 {
6426 err |= exp->e1->checkArithmetic();
6427 }
6428 if (t2->ty == Tdelegate ||
6429 (t2->ty == Tpointer && t2->nextOf()->ty == Tfunction))
6430 {
6431 err |= exp->e2->checkArithmetic();
6432 }
6433 if (err)
6434 return setError();
6435
6436 if (t1->ty == Tpointer)
6437 {
6438 if (t2->ty == Tpointer)
6439 {
6440 // Need to divide the result by the stride
6441 // Replace (ptr - ptr) with (ptr - ptr) / stride
6442 d_int64 stride;
6443
6444 // make sure pointer types are compatible
6445 if (Expression *ex = typeCombine(exp, sc))
6446 {
6447 result = ex;
6448 return;
6449 }
6450
6451 exp->type = Type::tptrdiff_t;
6452 stride = t2->nextOf()->size();
6453 if (stride == 0)
6454 {
6455 e = new IntegerExp(exp->loc, 0, Type::tptrdiff_t);
6456 }
6457 else
6458 {
6459 e = new DivExp(exp->loc, exp, new IntegerExp(Loc(), stride, Type::tptrdiff_t));
6460 e->type = Type::tptrdiff_t;
6461 }
6462 }
6463 else if (t2->isintegral())
6464 e = scaleFactor(exp, sc);
6465 else
6466 {
6467 exp->error("can't subtract %s from pointer", t2->toChars());
6468 e = new ErrorExp();
6469 }
6470 result = e;
6471 return;
6472 }
6473 if (t2->ty == Tpointer)
6474 {
6475 exp->type = exp->e2->type;
6476 exp->error("can't subtract pointer from %s", exp->e1->type->toChars());
6477 return setError();
6478 }
6479
6480 if (Expression *ex = typeCombine(exp, sc))
6481 {
6482 result = ex;
6483 return;
6484 }
6485
6486 Type *tb = exp->type->toBasetype();
6487 if (tb->ty == Tarray || tb->ty == Tsarray)
6488 {
6489 if (!isArrayOpValid(exp))
6490 {
6491 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
6492 return setError();
6493 }
6494 result = exp;
6495 return;
6496 }
6497
6498 t1 = exp->e1->type->toBasetype();
6499 t2 = exp->e2->type->toBasetype();
6500 if (!Target::isVectorOpSupported(t1, exp->op, t2))
6501 {
6502 result = exp->incompatibleTypes();
6503 return;
6504 }
6505 if ((t1->isreal() && t2->isimaginary()) ||
6506 (t1->isimaginary() && t2->isreal()))
6507 {
6508 switch (exp->type->ty)
6509 {
6510 case Tfloat32:
6511 case Timaginary32:
6512 exp->type = Type::tcomplex32;
6513 break;
6514
6515 case Tfloat64:
6516 case Timaginary64:
6517 exp->type = Type::tcomplex64;
6518 break;
6519
6520 case Tfloat80:
6521 case Timaginary80:
6522 exp->type = Type::tcomplex80;
6523 break;
6524
6525 default:
6526 assert(0);
6527 }
6528 }
6529 result = exp;
6530 }
6531
visit(CatExp * exp)6532 void visit(CatExp *exp)
6533 {
6534 //printf("CatExp::semantic() %s\n", exp->toChars());
6535 if (exp->type)
6536 {
6537 result = exp;
6538 return;
6539 }
6540
6541 if (Expression *ex = binSemanticProp(exp, sc))
6542 {
6543 result = ex;
6544 return;
6545 }
6546 Expression *e = exp->op_overload(sc);
6547 if (e)
6548 {
6549 result = e;
6550 return;
6551 }
6552
6553 Type *tb1 = exp->e1->type->toBasetype();
6554 Type *tb2 = exp->e2->type->toBasetype();
6555
6556 bool f1 = checkNonAssignmentArrayOp(exp->e1);
6557 bool f2 = checkNonAssignmentArrayOp(exp->e2);
6558 if (f1 || f2)
6559 return setError();
6560
6561 /* BUG: Should handle things like:
6562 * char c;
6563 * c ~ ' '
6564 * ' ' ~ c;
6565 */
6566 Type *tb1next = tb1->nextOf();
6567 Type *tb2next = tb2->nextOf();
6568
6569 // Check for: array ~ array
6570 if (tb1next && tb2next &&
6571 (tb1next->implicitConvTo(tb2next) >= MATCHconst ||
6572 tb2next->implicitConvTo(tb1next) >= MATCHconst ||
6573 (exp->e1->op == TOKarrayliteral && exp->e1->implicitConvTo(tb2)) ||
6574 (exp->e2->op == TOKarrayliteral && exp->e2->implicitConvTo(tb1))
6575 )
6576 )
6577 {
6578 /* Bugzilla 9248: Here to avoid the case of:
6579 * void*[] a = [cast(void*)1];
6580 * void*[] b = [cast(void*)2];
6581 * a ~ b;
6582 * becoming:
6583 * a ~ [cast(void*)b];
6584 */
6585
6586 /* Bugzilla 14682: Also to avoid the case of:
6587 * int[][] a;
6588 * a ~ [];
6589 * becoming:
6590 * a ~ cast(int[])[];
6591 */
6592 goto Lpeer;
6593 }
6594
6595 // Check for: array ~ element
6596 if ((tb1->ty == Tsarray || tb1->ty == Tarray) && tb2->ty != Tvoid)
6597 {
6598 if (exp->e1->op == TOKarrayliteral)
6599 {
6600 exp->e2 = exp->e2->isLvalue() ? callCpCtor(sc, exp->e2) : valueNoDtor(exp->e2);
6601 // Bugzilla 14686: Postblit call appears in AST, and this is
6602 // finally translated to an ArrayLiteralExp in below otpimize().
6603 }
6604 else if (exp->e1->op == TOKstring)
6605 {
6606 // No postblit call exists on character (integer) value.
6607 }
6608 else
6609 {
6610 if (exp->e2->checkPostblit(sc, tb2))
6611 return setError();
6612 // Postblit call will be done in runtime helper function
6613 }
6614
6615 if (exp->e1->op == TOKarrayliteral && exp->e1->implicitConvTo(tb2->arrayOf()))
6616 {
6617 exp->e1 = exp->e1->implicitCastTo(sc, tb2->arrayOf());
6618 exp->type = tb2->arrayOf();
6619 goto L2elem;
6620 }
6621 if (exp->e2->implicitConvTo(tb1next) >= MATCHconvert)
6622 {
6623 exp->e2 = exp->e2->implicitCastTo(sc, tb1next);
6624 exp->type = tb1next->arrayOf();
6625 L2elem:
6626 if (tb2->ty == Tarray || tb2->ty == Tsarray)
6627 {
6628 // Make e2 into [e2]
6629 exp->e2 = new ArrayLiteralExp(exp->e2->loc, exp->type, exp->e2);
6630 }
6631 result = exp->optimize(WANTvalue);
6632 return;
6633 }
6634 }
6635 // Check for: element ~ array
6636 if ((tb2->ty == Tsarray || tb2->ty == Tarray) && tb1->ty != Tvoid)
6637 {
6638 if (exp->e2->op == TOKarrayliteral)
6639 {
6640 exp->e1 = exp->e1->isLvalue() ? callCpCtor(sc, exp->e1) : valueNoDtor(exp->e1);
6641 }
6642 else if (exp->e2->op == TOKstring)
6643 {
6644 }
6645 else
6646 {
6647 if (exp->e1->checkPostblit(sc, tb1))
6648 return setError();
6649 }
6650
6651 if (exp->e2->op == TOKarrayliteral && exp->e2->implicitConvTo(tb1->arrayOf()))
6652 {
6653 exp->e2 = exp->e2->implicitCastTo(sc, tb1->arrayOf());
6654 exp->type = tb1->arrayOf();
6655 goto L1elem;
6656 }
6657 if (exp->e1->implicitConvTo(tb2next) >= MATCHconvert)
6658 {
6659 exp->e1 = exp->e1->implicitCastTo(sc, tb2next);
6660 exp->type = tb2next->arrayOf();
6661 L1elem:
6662 if (tb1->ty == Tarray || tb1->ty == Tsarray)
6663 {
6664 // Make e1 into [e1]
6665 exp->e1 = new ArrayLiteralExp(exp->e1->loc, exp->type, exp->e1);
6666 }
6667 result = exp->optimize(WANTvalue);
6668 return;
6669 }
6670 }
6671
6672 Lpeer:
6673 if ((tb1->ty == Tsarray || tb1->ty == Tarray) &&
6674 (tb2->ty == Tsarray || tb2->ty == Tarray) &&
6675 (tb1next->mod || tb2next->mod) &&
6676 (tb1next->mod != tb2next->mod)
6677 )
6678 {
6679 Type *t1 = tb1next->mutableOf()->constOf()->arrayOf();
6680 Type *t2 = tb2next->mutableOf()->constOf()->arrayOf();
6681 if (exp->e1->op == TOKstring && !((StringExp *)exp->e1)->committed)
6682 exp->e1->type = t1;
6683 else
6684 exp->e1 = exp->e1->castTo(sc, t1);
6685 if (exp->e2->op == TOKstring && !((StringExp *)exp->e2)->committed)
6686 exp->e2->type = t2;
6687 else
6688 exp->e2 = exp->e2->castTo(sc, t2);
6689 }
6690
6691 if (Expression *ex = typeCombine(exp, sc))
6692 {
6693 result = ex;
6694 return;
6695 }
6696 exp->type = exp->type->toHeadMutable();
6697
6698 Type *tb = exp->type->toBasetype();
6699 if (tb->ty == Tsarray)
6700 exp->type = tb->nextOf()->arrayOf();
6701 if (exp->type->ty == Tarray && tb1next && tb2next &&
6702 tb1next->mod != tb2next->mod)
6703 {
6704 exp->type = exp->type->nextOf()->toHeadMutable()->arrayOf();
6705 }
6706 if (Type *tbn = tb->nextOf())
6707 {
6708 if (exp->checkPostblit(sc, tbn))
6709 return setError();
6710 }
6711 Type *t1 = exp->e1->type->toBasetype();
6712 Type *t2 = exp->e2->type->toBasetype();
6713 if ((t1->ty == Tarray || t1->ty == Tsarray) &&
6714 (t2->ty == Tarray || t2->ty == Tsarray))
6715 {
6716 // Normalize to ArrayLiteralExp or StringExp as far as possible
6717 e = exp->optimize(WANTvalue);
6718 }
6719 else
6720 {
6721 //printf("(%s) ~ (%s)\n", exp->e1->toChars(), exp->e2->toChars());
6722 result = exp->incompatibleTypes();
6723 return;
6724 }
6725 result = e;
6726 }
6727
visit(MulExp * exp)6728 void visit(MulExp *exp)
6729 {
6730 if (exp->type)
6731 {
6732 result = exp;
6733 return;
6734 }
6735
6736 if (Expression *ex = binSemanticProp(exp, sc))
6737 {
6738 result = ex;
6739 return;
6740 }
6741 Expression *e = exp->op_overload(sc);
6742 if (e)
6743 {
6744 result = e;
6745 return;
6746 }
6747
6748 if (Expression *ex = typeCombine(exp, sc))
6749 {
6750 result = ex;
6751 return;
6752 }
6753
6754 Type *tb = exp->type->toBasetype();
6755 if (tb->ty == Tarray || tb->ty == Tsarray)
6756 {
6757 if (!isArrayOpValid(exp))
6758 {
6759 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
6760 return setError();
6761 }
6762 result = exp;
6763 return;
6764 }
6765
6766 if (exp->checkArithmeticBin())
6767 return setError();
6768
6769 if (exp->type->isfloating())
6770 {
6771 Type *t1 = exp->e1->type;
6772 Type *t2 = exp->e2->type;
6773
6774 if (t1->isreal())
6775 {
6776 exp->type = t2;
6777 }
6778 else if (t2->isreal())
6779 {
6780 exp->type = t1;
6781 }
6782 else if (t1->isimaginary())
6783 {
6784 if (t2->isimaginary())
6785 {
6786
6787 switch (t1->toBasetype()->ty)
6788 {
6789 case Timaginary32:
6790 exp->type = Type::tfloat32;
6791 break;
6792
6793 case Timaginary64:
6794 exp->type = Type::tfloat64;
6795 break;
6796
6797 case Timaginary80:
6798 exp->type = Type::tfloat80;
6799 break;
6800
6801 default:
6802 assert(0);
6803 }
6804
6805 // iy * iv = -yv
6806 exp->e1->type = exp->type;
6807 exp->e2->type = exp->type;
6808 e = new NegExp(exp->loc, exp);
6809 e = semantic(e, sc);
6810 result = e;
6811 return;
6812 }
6813 else
6814 exp->type = t2; // t2 is complex
6815 }
6816 else if (t2->isimaginary())
6817 {
6818 exp->type = t1; // t1 is complex
6819 }
6820 }
6821 else if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
6822 {
6823 result = exp->incompatibleTypes();
6824 return;
6825 }
6826 result = exp;
6827 }
6828
visit(DivExp * exp)6829 void visit(DivExp *exp)
6830 {
6831 if (exp->type)
6832 {
6833 result = exp;
6834 return;
6835 }
6836
6837 if (Expression *ex = binSemanticProp(exp, sc))
6838 {
6839 result = ex;
6840 return;
6841 }
6842 Expression *e = exp->op_overload(sc);
6843 if (e)
6844 {
6845 result = e;
6846 return;
6847 }
6848
6849 if (Expression *ex = typeCombine(exp, sc))
6850 {
6851 result = ex;
6852 return;
6853 }
6854
6855 Type *tb = exp->type->toBasetype();
6856 if (tb->ty == Tarray || tb->ty == Tsarray)
6857 {
6858 if (!isArrayOpValid(exp))
6859 {
6860 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
6861 return setError();
6862 }
6863 result = exp;
6864 return;
6865 }
6866
6867 if (exp->checkArithmeticBin())
6868 return setError();
6869
6870 if (exp->type->isfloating())
6871 {
6872 Type *t1 = exp->e1->type;
6873 Type *t2 = exp->e2->type;
6874
6875 if (t1->isreal())
6876 {
6877 exp->type = t2;
6878 if (t2->isimaginary())
6879 {
6880 // x/iv = i(-x/v)
6881 exp->e2->type = t1;
6882 e = new NegExp(exp->loc, exp);
6883 e = semantic(e, sc);
6884 result = e;
6885 return;
6886 }
6887 }
6888 else if (t2->isreal())
6889 {
6890 exp->type = t1;
6891 }
6892 else if (t1->isimaginary())
6893 {
6894 if (t2->isimaginary())
6895 {
6896 switch (t1->toBasetype()->ty)
6897 {
6898 case Timaginary32:
6899 exp->type = Type::tfloat32;
6900 break;
6901
6902 case Timaginary64:
6903 exp->type = Type::tfloat64;
6904 break;
6905
6906 case Timaginary80:
6907 exp->type = Type::tfloat80;
6908 break;
6909
6910 default:
6911 assert(0);
6912 }
6913 }
6914 else
6915 exp->type = t2; // t2 is complex
6916 }
6917 else if (t2->isimaginary())
6918 {
6919 exp->type = t1; // t1 is complex
6920 }
6921 }
6922 else if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
6923 {
6924 result = exp->incompatibleTypes();
6925 return;
6926 }
6927 result = exp;
6928 }
6929
visit(ModExp * exp)6930 void visit(ModExp *exp)
6931 {
6932 if (exp->type)
6933 {
6934 result = exp;
6935 return;
6936 }
6937
6938 if (Expression *ex = binSemanticProp(exp, sc))
6939 {
6940 result = ex;
6941 return;
6942 }
6943 Expression *e = exp->op_overload(sc);
6944 if (e)
6945 {
6946 result = e;
6947 return;
6948 }
6949
6950 if (Expression *ex = typeCombine(exp, sc))
6951 {
6952 result = ex;
6953 return;
6954 }
6955
6956 Type *tb = exp->type->toBasetype();
6957 if (tb->ty == Tarray || tb->ty == Tsarray)
6958 {
6959 if (!isArrayOpValid(exp))
6960 {
6961 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
6962 return setError();
6963 }
6964 result = exp;
6965 return;
6966 }
6967 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
6968 {
6969 result = exp->incompatibleTypes();
6970 return;
6971 }
6972
6973 if (exp->checkArithmeticBin())
6974 return setError();
6975
6976 if (exp->type->isfloating())
6977 {
6978 exp->type = exp->e1->type;
6979 if (exp->e2->type->iscomplex())
6980 {
6981 exp->error("cannot perform modulo complex arithmetic");
6982 return setError();
6983 }
6984 }
6985 result = exp;
6986 }
6987
loadStdMath()6988 Module *loadStdMath()
6989 {
6990 static Import *impStdMath = NULL;
6991 if (!impStdMath)
6992 {
6993 Identifiers *a = new Identifiers();
6994 a->push(Id::std);
6995 Import *s = new Import(Loc(), a, Id::math, NULL, false);
6996 s->load(NULL);
6997 if (s->mod)
6998 {
6999 s->mod->importAll(NULL);
7000 s->mod->semantic(NULL);
7001 }
7002 impStdMath = s;
7003 }
7004 return impStdMath->mod;
7005 }
7006
visit(PowExp * exp)7007 void visit(PowExp *exp)
7008 {
7009 if (exp->type)
7010 {
7011 result = exp;
7012 return;
7013 }
7014
7015 //printf("PowExp::semantic() %s\n", exp->toChars());
7016 if (Expression *ex = binSemanticProp(exp, sc))
7017 {
7018 result = ex;
7019 return;
7020 }
7021 Expression *e = exp->op_overload(sc);
7022 if (e)
7023 {
7024 result = e;
7025 return;
7026 }
7027
7028 if (Expression *ex = typeCombine(exp, sc))
7029 {
7030 result = ex;
7031 return;
7032 }
7033
7034 Type *tb = exp->type->toBasetype();
7035 if (tb->ty == Tarray || tb->ty == Tsarray)
7036 {
7037 if (!isArrayOpValid(exp))
7038 {
7039 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
7040 return setError();
7041 }
7042 result = exp;
7043 return;
7044 }
7045
7046 if (exp->checkArithmeticBin())
7047 return setError();
7048
7049 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
7050 {
7051 result = exp->incompatibleTypes();
7052 return;
7053 }
7054
7055 // For built-in numeric types, there are several cases.
7056 // TODO: backend support, especially for e1 ^^ 2.
7057
7058 // First, attempt to fold the expression.
7059 e = exp->optimize(WANTvalue);
7060 if (e->op != TOKpow)
7061 {
7062 e = semantic(e, sc);
7063 result = e;
7064 return;
7065 }
7066
7067 // Determine if we're raising to an integer power.
7068 sinteger_t intpow = 0;
7069 if (exp->e2->op == TOKint64 && ((sinteger_t)exp->e2->toInteger() == 2 || (sinteger_t)exp->e2->toInteger() == 3))
7070 intpow = exp->e2->toInteger();
7071 else if (exp->e2->op == TOKfloat64 && (exp->e2->toReal() == ldouble((sinteger_t)exp->e2->toReal())))
7072 intpow = (sinteger_t)(exp->e2->toReal());
7073
7074 // Deal with x^^2, x^^3 immediately, since they are of practical importance.
7075 if (intpow == 2 || intpow == 3)
7076 {
7077 // Replace x^^2 with (tmp = x, tmp*tmp)
7078 // Replace x^^3 with (tmp = x, tmp*tmp*tmp)
7079 VarDeclaration *tmp = copyToTemp(0, "__powtmp", exp->e1);
7080 Expression *de = new DeclarationExp(exp->loc, tmp);
7081 Expression *ve = new VarExp(exp->loc, tmp);
7082
7083 /* Note that we're reusing ve. This should be ok.
7084 */
7085 Expression *me = new MulExp(exp->loc, ve, ve);
7086 if (intpow == 3)
7087 me = new MulExp(exp->loc, me, ve);
7088 e = new CommaExp(exp->loc, de, me);
7089 e = semantic(e, sc);
7090 result = e;
7091 return;
7092 }
7093
7094 Module *mmath = loadStdMath();
7095 if (!mmath)
7096 {
7097 //exp->error("requires std.math for ^^ operators");
7098 //fatal();
7099
7100 // Leave handling of PowExp to the backend, or throw
7101 // an error gracefully if no backend support exists.
7102 if (Expression *ex = typeCombine(exp, sc))
7103 {
7104 result = ex;
7105 return;
7106 }
7107 result = exp;
7108 return;
7109 }
7110 e = new ScopeExp(exp->loc, mmath);
7111
7112 if (exp->e2->op == TOKfloat64 && exp->e2->toReal() == CTFloat::half)
7113 {
7114 // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
7115 e = new CallExp(exp->loc, new DotIdExp(exp->loc, e, Id::_sqrt), exp->e1);
7116 }
7117 else
7118 {
7119 // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
7120 e = new CallExp(exp->loc, new DotIdExp(exp->loc, e, Id::_pow), exp->e1, exp->e2);
7121 }
7122 e = semantic(e, sc);
7123 result = e;
7124 }
7125
visit(ShlExp * exp)7126 void visit(ShlExp *exp)
7127 {
7128 //printf("ShlExp::semantic(), type = %p\n", exp->type);
7129 if (exp->type)
7130 {
7131 result = exp;
7132 return;
7133 }
7134
7135 if (Expression *ex = binSemanticProp(exp, sc))
7136 {
7137 result = ex;
7138 return;
7139 }
7140 Expression *e = exp->op_overload(sc);
7141 if (e)
7142 {
7143 result = e;
7144 return;
7145 }
7146
7147 if (exp->checkIntegralBin())
7148 return setError();
7149 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
7150 {
7151 result = exp->incompatibleTypes();
7152 return;
7153 }
7154 exp->e1 = integralPromotions(exp->e1, sc);
7155 if (exp->e2->type->toBasetype()->ty != Tvector)
7156 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt);
7157
7158 exp->type = exp->e1->type;
7159 result = exp;
7160 }
7161
visit(ShrExp * exp)7162 void visit(ShrExp *exp)
7163 {
7164 if (exp->type)
7165 {
7166 result = exp;
7167 return;
7168 }
7169
7170 if (Expression *ex = binSemanticProp(exp, sc))
7171 {
7172 result = ex;
7173 return;
7174 }
7175 Expression *e = exp->op_overload(sc);
7176 if (e)
7177 {
7178 result = e;
7179 return;
7180 }
7181
7182 if (exp->checkIntegralBin())
7183 return setError();
7184 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
7185 {
7186 result = exp->incompatibleTypes();
7187 return;
7188 }
7189 exp->e1 = integralPromotions(exp->e1, sc);
7190 if (exp->e2->type->toBasetype()->ty != Tvector)
7191 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt);
7192
7193 exp->type = exp->e1->type;
7194 result = exp;
7195 }
7196
visit(UshrExp * exp)7197 void visit(UshrExp *exp)
7198 {
7199 if (exp->type)
7200 {
7201 result = exp;
7202 return;
7203 }
7204
7205 if (Expression *ex = binSemanticProp(exp, sc))
7206 {
7207 result = ex;
7208 return;
7209 }
7210 Expression *e = exp->op_overload(sc);
7211 if (e)
7212 {
7213 result = e;
7214 return;
7215 }
7216
7217 if (exp->checkIntegralBin())
7218 return setError();
7219 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype()))
7220 {
7221 result = exp->incompatibleTypes();
7222 return;
7223 }
7224 exp->e1 = integralPromotions(exp->e1, sc);
7225 if (exp->e2->type->toBasetype()->ty != Tvector)
7226 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt);
7227
7228 exp->type = exp->e1->type;
7229 result = exp;
7230 }
7231
visit(AndExp * exp)7232 void visit(AndExp *exp)
7233 {
7234 if (exp->type)
7235 {
7236 result = exp;
7237 return;
7238 }
7239
7240 if (Expression *ex = binSemanticProp(exp, sc))
7241 {
7242 result = ex;
7243 return;
7244 }
7245 Expression *e = exp->op_overload(sc);
7246 if (e)
7247 {
7248 result = e;
7249 return;
7250 }
7251
7252 if (exp->e1->type->toBasetype()->ty == Tbool &&
7253 exp->e2->type->toBasetype()->ty == Tbool)
7254 {
7255 exp->type = exp->e1->type;
7256 result = exp;
7257 return;
7258 }
7259
7260 if (Expression *ex = typeCombine(exp, sc))
7261 {
7262 result = ex;
7263 return;
7264 }
7265
7266 Type *tb = exp->type->toBasetype();
7267 if (tb->ty == Tarray || tb->ty == Tsarray)
7268 {
7269 if (!isArrayOpValid(exp))
7270 {
7271 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
7272 return setError();
7273 }
7274 result = exp;
7275 return;
7276 }
7277
7278 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
7279 {
7280 result = exp->incompatibleTypes();
7281 return;
7282 }
7283 if (exp->checkIntegralBin())
7284 return setError();
7285
7286 result = exp;
7287 }
7288
visit(OrExp * exp)7289 void visit(OrExp *exp)
7290 {
7291 if (exp->type)
7292 {
7293 result = exp;
7294 return;
7295 }
7296
7297 if (Expression *ex = binSemanticProp(exp, sc))
7298 {
7299 result = ex;
7300 return;
7301 }
7302 Expression *e = exp->op_overload(sc);
7303 if (e)
7304 {
7305 result = e;
7306 return;
7307 }
7308
7309 if (exp->e1->type->toBasetype()->ty == Tbool &&
7310 exp->e2->type->toBasetype()->ty == Tbool)
7311 {
7312 exp->type = exp->e1->type;
7313 result = exp;
7314 return;
7315 }
7316
7317 if (Expression *ex = typeCombine(exp, sc))
7318 {
7319 result = ex;
7320 return;
7321 }
7322
7323 Type *tb = exp->type->toBasetype();
7324 if (tb->ty == Tarray || tb->ty == Tsarray)
7325 {
7326 if (!isArrayOpValid(exp))
7327 {
7328 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
7329 return setError();
7330 }
7331 result = exp;
7332 return;
7333 }
7334
7335 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
7336 {
7337 result = exp->incompatibleTypes();
7338 return;
7339 }
7340 if (exp->checkIntegralBin())
7341 return setError();
7342
7343 result = exp;
7344 }
7345
visit(XorExp * exp)7346 void visit(XorExp *exp)
7347 {
7348 if (exp->type)
7349 {
7350 result = exp;
7351 return;
7352 }
7353
7354 if (Expression *ex = binSemanticProp(exp, sc))
7355 {
7356 result = ex;
7357 return;
7358 }
7359 Expression *e = exp->op_overload(sc);
7360 if (e)
7361 {
7362 result = e;
7363 return;
7364 }
7365
7366 if (exp->e1->type->toBasetype()->ty == Tbool &&
7367 exp->e2->type->toBasetype()->ty == Tbool)
7368 {
7369 exp->type = exp->e1->type;
7370 result = exp;
7371 return;
7372 }
7373
7374 if (Expression *ex = typeCombine(exp, sc))
7375 {
7376 result = ex;
7377 return;
7378 }
7379
7380 Type *tb = exp->type->toBasetype();
7381 if (tb->ty == Tarray || tb->ty == Tsarray)
7382 {
7383 if (!isArrayOpValid(exp))
7384 {
7385 exp->error("invalid array operation %s (possible missing [])", exp->toChars());
7386 return setError();
7387 }
7388 result = exp;
7389 return;
7390 }
7391
7392 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype()))
7393 {
7394 result = exp->incompatibleTypes();
7395 return;
7396 }
7397 if (exp->checkIntegralBin())
7398 return setError();
7399
7400 result = exp;
7401 }
7402
visit(OrOrExp * exp)7403 void visit(OrOrExp *exp)
7404 {
7405 if (exp->type)
7406 {
7407 result = exp;
7408 return;
7409 }
7410
7411 setNoderefOperands(exp);
7412
7413 // same as for AndAnd
7414 Expression *e1x = semantic(exp->e1, sc);
7415
7416 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7417 if (e1x->op == TOKtype)
7418 e1x = resolveAliasThis(sc, e1x);
7419
7420 e1x = resolveProperties(sc, e1x);
7421 e1x = e1x->toBoolean(sc);
7422 unsigned cs1 = sc->callSuper;
7423
7424 if (sc->flags & SCOPEcondition)
7425 {
7426 /* If in static if, don't evaluate e2 if we don't have to.
7427 */
7428 e1x = e1x->optimize(WANTvalue);
7429 if (e1x->isBool(true))
7430 {
7431 result = new IntegerExp(exp->loc, 1, Type::tbool);
7432 return;
7433 }
7434 }
7435
7436 Expression *e2x = semantic(exp->e2, sc);
7437 sc->mergeCallSuper(exp->loc, cs1);
7438
7439 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7440 if (e2x->op == TOKtype)
7441 e2x = resolveAliasThis(sc, e2x);
7442
7443 e2x = resolveProperties(sc, e2x);
7444
7445 bool f1 = checkNonAssignmentArrayOp(e1x);
7446 bool f2 = checkNonAssignmentArrayOp(e2x);
7447 if (f1 || f2)
7448 return setError();
7449
7450 // Unless the right operand is 'void', the expression is converted to 'bool'.
7451 if (e2x->type->ty != Tvoid)
7452 e2x = e2x->toBoolean(sc);
7453
7454 if (e2x->op == TOKtype || e2x->op == TOKscope)
7455 {
7456 exp->error("%s is not an expression", exp->e2->toChars());
7457 return setError();
7458 }
7459 if (e1x->op == TOKerror)
7460 {
7461 result = e1x;
7462 return;
7463 }
7464 if (e2x->op == TOKerror)
7465 {
7466 result = e2x;
7467 return;
7468 }
7469
7470 // The result type is 'bool', unless the right operand has type 'void'.
7471 if (e2x->type->ty == Tvoid)
7472 exp->type = Type::tvoid;
7473 else
7474 exp->type = Type::tbool;
7475
7476 exp->e1 = e1x;
7477 exp->e2 = e2x;
7478 result = exp;
7479 }
7480
visit(AndAndExp * exp)7481 void visit(AndAndExp *exp)
7482 {
7483 if (exp->type)
7484 {
7485 result = exp;
7486 return;
7487 }
7488
7489 setNoderefOperands(exp);
7490
7491 // same as for OrOr
7492 Expression *e1x = semantic(exp->e1, sc);
7493
7494 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7495 if (e1x->op == TOKtype)
7496 e1x = resolveAliasThis(sc, e1x);
7497
7498 e1x = resolveProperties(sc, e1x);
7499 e1x = e1x->toBoolean(sc);
7500 unsigned cs1 = sc->callSuper;
7501
7502 if (sc->flags & SCOPEcondition)
7503 {
7504 /* If in static if, don't evaluate e2 if we don't have to.
7505 */
7506 e1x = e1x->optimize(WANTvalue);
7507 if (e1x->isBool(false))
7508 {
7509 result = new IntegerExp(exp->loc, 0, Type::tbool);
7510 return;
7511 }
7512 }
7513
7514 Expression *e2x = semantic(exp->e2, sc);
7515 sc->mergeCallSuper(exp->loc, cs1);
7516
7517 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7518 if (e2x->op == TOKtype)
7519 e2x = resolveAliasThis(sc, e2x);
7520
7521 e2x = resolveProperties(sc, e2x);
7522
7523 bool f1 = checkNonAssignmentArrayOp(e1x);
7524 bool f2 = checkNonAssignmentArrayOp(e2x);
7525 if (f1 || f2)
7526 return setError();
7527
7528 // Unless the right operand is 'void', the expression is converted to 'bool'.
7529 if (e2x->type->ty != Tvoid)
7530 e2x = e2x->toBoolean(sc);
7531
7532 if (e2x->op == TOKtype || e2x->op == TOKscope)
7533 {
7534 exp->error("%s is not an expression", exp->e2->toChars());
7535 return setError();
7536 }
7537 if (e1x->op == TOKerror)
7538 {
7539 result = e1x;
7540 return;
7541 }
7542 if (e2x->op == TOKerror)
7543 {
7544 result = e2x;
7545 return;
7546 }
7547
7548 // The result type is 'bool', unless the right operand has type 'void'.
7549 if (e2x->type->ty == Tvoid)
7550 exp->type = Type::tvoid;
7551 else
7552 exp->type = Type::tbool;
7553
7554 exp->e1 = e1x;
7555 exp->e2 = e2x;
7556 result = exp;
7557 }
7558
visit(InExp * exp)7559 void visit(InExp *exp)
7560 {
7561 if (exp->type)
7562 {
7563 result = exp;
7564 return;
7565 }
7566
7567 if (Expression *ex = binSemanticProp(exp, sc))
7568 {
7569 result = ex;
7570 return;
7571 }
7572 Expression *e = exp->op_overload(sc);
7573 if (e)
7574 {
7575 result = e;
7576 return;
7577 }
7578
7579 Type *t2b = exp->e2->type->toBasetype();
7580 switch (t2b->ty)
7581 {
7582 case Taarray:
7583 {
7584 TypeAArray *ta = (TypeAArray *)t2b;
7585
7586 // Special handling for array keys
7587 if (!arrayTypeCompatible(exp->e1->loc, exp->e1->type, ta->index))
7588 {
7589 // Convert key to type of key
7590 exp->e1 = exp->e1->implicitCastTo(sc, ta->index);
7591 }
7592
7593 semanticTypeInfo(sc, ta->index);
7594
7595 // Return type is pointer to value
7596 exp->type = ta->nextOf()->pointerTo();
7597 break;
7598 }
7599
7600 default:
7601 result = exp->incompatibleTypes();
7602 return;
7603
7604 case Terror:
7605 return setError();
7606 }
7607 result = exp;
7608 }
7609
visit(RemoveExp * e)7610 void visit(RemoveExp *e)
7611 {
7612 if (Expression *ex = binSemantic(e, sc))
7613 {
7614 result = ex;
7615 return;
7616 }
7617 result = e;
7618 }
7619
visit(CmpExp * exp)7620 void visit(CmpExp *exp)
7621 {
7622 if (exp->type)
7623 {
7624 result = exp;
7625 return;
7626 }
7627
7628 setNoderefOperands(exp);
7629
7630 if (Expression *ex = binSemanticProp(exp, sc))
7631 {
7632 result = ex;
7633 return;
7634 }
7635 Type *t1 = exp->e1->type->toBasetype();
7636 Type *t2 = exp->e2->type->toBasetype();
7637 if ((t1->ty == Tclass && exp->e2->op == TOKnull) ||
7638 (t2->ty == Tclass && exp->e1->op == TOKnull))
7639 {
7640 exp->error("do not use null when comparing class types");
7641 return setError();
7642 }
7643
7644 Expression *e = exp->op_overload(sc);
7645 if (e)
7646 {
7647 if (!e->type->isscalar() && e->type->equals(exp->e1->type))
7648 {
7649 exp->error("recursive opCmp expansion");
7650 return setError();
7651 }
7652 if (e->op == TOKcall)
7653 {
7654 e = new CmpExp(exp->op, exp->loc, e, new IntegerExp(exp->loc, 0, Type::tint32));
7655 e = semantic(e, sc);
7656 }
7657 result = e;
7658 return;
7659 }
7660
7661 if (Expression *ex = typeCombine(exp, sc))
7662 {
7663 result = ex;
7664 return;
7665 }
7666
7667 bool f1 = checkNonAssignmentArrayOp(exp->e1);
7668 bool f2 = checkNonAssignmentArrayOp(exp->e2);
7669 if (f1 || f2)
7670 return setError();
7671
7672 exp->type = Type::tbool;
7673
7674 // Special handling for array comparisons
7675 t1 = exp->e1->type->toBasetype();
7676 t2 = exp->e2->type->toBasetype();
7677 if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) &&
7678 (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer))
7679 {
7680 Type *t1next = t1->nextOf();
7681 Type *t2next = t2->nextOf();
7682 if (t1next->implicitConvTo(t2next) < MATCHconst &&
7683 t2next->implicitConvTo(t1next) < MATCHconst &&
7684 (t1next->ty != Tvoid && t2next->ty != Tvoid))
7685 {
7686 exp->error("array comparison type mismatch, %s vs %s", t1next->toChars(), t2next->toChars());
7687 return setError();
7688 }
7689 if ((t1->ty == Tarray || t1->ty == Tsarray) &&
7690 (t2->ty == Tarray || t2->ty == Tsarray))
7691 {
7692 semanticTypeInfo(sc, t1->nextOf());
7693 }
7694 }
7695 else if (t1->ty == Tstruct || t2->ty == Tstruct ||
7696 (t1->ty == Tclass && t2->ty == Tclass))
7697 {
7698 if (t2->ty == Tstruct)
7699 exp->error("need member function opCmp() for %s %s to compare", t2->toDsymbol(sc)->kind(), t2->toChars());
7700 else
7701 exp->error("need member function opCmp() for %s %s to compare", t1->toDsymbol(sc)->kind(), t1->toChars());
7702 return setError();
7703 }
7704 else if (t1->iscomplex() || t2->iscomplex())
7705 {
7706 exp->error("compare not defined for complex operands");
7707 return setError();
7708 }
7709 else if (t1->ty == Taarray || t2->ty == Taarray)
7710 {
7711 exp->error("%s is not defined for associative arrays", Token::toChars(exp->op));
7712 return setError();
7713 }
7714 else if (!Target::isVectorOpSupported(t1, exp->op, t2))
7715 {
7716 result = exp->incompatibleTypes();
7717 return;
7718 }
7719 else
7720 {
7721 bool r1 = exp->e1->checkValue();
7722 bool r2 = exp->e2->checkValue();
7723 if (r1 || r2)
7724 return setError();
7725 }
7726
7727 TOK altop;
7728 switch (exp->op)
7729 {
7730 // Refer rel_integral[] table
7731 case TOKunord: altop = TOKerror; break;
7732 case TOKlg: altop = TOKnotequal; break;
7733 case TOKleg: altop = TOKerror; break;
7734 case TOKule: altop = TOKle; break;
7735 case TOKul: altop = TOKlt; break;
7736 case TOKuge: altop = TOKge; break;
7737 case TOKug: altop = TOKgt; break;
7738 case TOKue: altop = TOKequal; break;
7739 default: altop = TOKreserved; break;
7740 }
7741 if (altop == TOKerror &&
7742 (t1->ty == Tarray || t1->ty == Tsarray ||
7743 t2->ty == Tarray || t2->ty == Tsarray))
7744 {
7745 exp->error("'%s' is not defined for array comparisons", Token::toChars(exp->op));
7746 return setError();
7747 }
7748 if (altop != TOKreserved)
7749 {
7750 if (!t1->isfloating())
7751 {
7752 if (altop == TOKerror)
7753 {
7754 const char *s = exp->op == TOKunord ? "false" : "true";
7755 exp->error("floating point operator '%s' always returns %s for non-floating comparisons",
7756 Token::toChars(exp->op), s);
7757 }
7758 else
7759 {
7760 exp->error("use '%s' for non-floating comparisons rather than floating point operator '%s'",
7761 Token::toChars(altop), Token::toChars(exp->op));
7762 }
7763 }
7764 else
7765 {
7766 exp->error("use std.math.isNaN to deal with NaN operands rather than floating point operator '%s'",
7767 Token::toChars(exp->op));
7768 }
7769 return setError();
7770 }
7771
7772 //printf("CmpExp: %s, type = %s\n", e->toChars(), e->type->toChars());
7773 result = exp;
7774 }
7775
visit(EqualExp * exp)7776 void visit(EqualExp *exp)
7777 {
7778 //printf("EqualExp::semantic('%s')\n", toChars());
7779 if (exp->type)
7780 {
7781 result = exp;
7782 return;
7783 }
7784
7785 setNoderefOperands(exp);
7786
7787 if (Expression *e = binSemanticProp(exp, sc))
7788 {
7789 result = e;
7790 return;
7791 }
7792 if (exp->e1->op == TOKtype || exp->e2->op == TOKtype)
7793 {
7794 result = exp->incompatibleTypes();
7795 return;
7796 }
7797
7798 {
7799 Type *t1 = exp->e1->type;
7800 Type *t2 = exp->e2->type;
7801 if (t1->ty == Tenum && t2->ty == Tenum && !t1->equivalent(t2))
7802 exp->deprecation("Comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`",
7803 t1->toChars(), t2->toChars());
7804 }
7805
7806 /* Before checking for operator overloading, check to see if we're
7807 * comparing the addresses of two statics. If so, we can just see
7808 * if they are the same symbol.
7809 */
7810 if (exp->e1->op == TOKaddress && exp->e2->op == TOKaddress)
7811 {
7812 AddrExp *ae1 = (AddrExp *)exp->e1;
7813 AddrExp *ae2 = (AddrExp *)exp->e2;
7814 if (ae1->e1->op == TOKvar && ae2->e1->op == TOKvar)
7815 {
7816 VarExp *ve1 = (VarExp *)ae1->e1;
7817 VarExp *ve2 = (VarExp *)ae2->e1;
7818
7819 if (ve1->var == ve2->var)
7820 {
7821 // They are the same, result is 'true' for ==, 'false' for !=
7822 result = new IntegerExp(exp->loc, (exp->op == TOKequal), Type::tbool);
7823 return;
7824 }
7825 }
7826 }
7827
7828 if (Expression *e = exp->op_overload(sc))
7829 {
7830 result = e;
7831 return;
7832 }
7833
7834 if (Expression *e = typeCombine(exp, sc))
7835 {
7836 result = e;
7837 return;
7838 }
7839
7840 bool f1 = checkNonAssignmentArrayOp(exp->e1);
7841 bool f2 = checkNonAssignmentArrayOp(exp->e2);
7842 if (f1 || f2)
7843 return setError();
7844
7845 exp->type = Type::tbool;
7846
7847 // Special handling for array comparisons
7848 if (!arrayTypeCompatible(exp->loc, exp->e1->type, exp->e2->type))
7849 {
7850 if (exp->e1->type != exp->e2->type && exp->e1->type->isfloating() && exp->e2->type->isfloating())
7851 {
7852 // Cast both to complex
7853 exp->e1 = exp->e1->castTo(sc, Type::tcomplex80);
7854 exp->e2 = exp->e2->castTo(sc, Type::tcomplex80);
7855 }
7856 }
7857 if (exp->e1->type->toBasetype()->ty == Taarray)
7858 semanticTypeInfo(sc, exp->e1->type->toBasetype());
7859
7860 Type *t1 = exp->e1->type->toBasetype();
7861 Type *t2 = exp->e2->type->toBasetype();
7862
7863 if (!Target::isVectorOpSupported(t1, exp->op, t2))
7864 {
7865 result = exp->incompatibleTypes();
7866 return;
7867 }
7868
7869 result = exp;
7870 }
7871
visit(IdentityExp * exp)7872 void visit(IdentityExp *exp)
7873 {
7874 if (exp->type)
7875 {
7876 result = exp;
7877 return;
7878 }
7879
7880 setNoderefOperands(exp);
7881
7882 if (Expression *ex = binSemanticProp(exp, sc))
7883 {
7884 result = ex;
7885 return;
7886 }
7887
7888 if (Expression *ex = typeCombine(exp, sc))
7889 {
7890 result = ex;
7891 return;
7892 }
7893
7894 bool f1 = checkNonAssignmentArrayOp(exp->e1);
7895 bool f2 = checkNonAssignmentArrayOp(exp->e2);
7896 if (f1 || f2)
7897 return setError();
7898
7899 exp->type = Type::tbool;
7900
7901 if (exp->e1->type != exp->e2->type && exp->e1->type->isfloating() && exp->e2->type->isfloating())
7902 {
7903 // Cast both to complex
7904 exp->e1 = exp->e1->castTo(sc, Type::tcomplex80);
7905 exp->e2 = exp->e2->castTo(sc, Type::tcomplex80);
7906 }
7907
7908 Type *tb1 = exp->e1->type->toBasetype();
7909 Type *tb2 = exp->e2->type->toBasetype();
7910 if (!Target::isVectorOpSupported(tb1, exp->op, tb2))
7911 {
7912 result = exp->incompatibleTypes();
7913 return;
7914 }
7915
7916 result = exp;
7917 }
7918
visit(CondExp * exp)7919 void visit(CondExp *exp)
7920 {
7921 if (exp->type)
7922 {
7923 result = exp;
7924 return;
7925 }
7926
7927 if (exp->econd->op == TOKdotid)
7928 ((DotIdExp *)exp->econd)->noderef = true;
7929
7930 Expression *ec = semantic(exp->econd, sc);
7931 ec = resolveProperties(sc, ec);
7932 ec = ec->toBoolean(sc);
7933
7934 unsigned cs0 = sc->callSuper;
7935 unsigned *fi0 = sc->saveFieldInit();
7936 Expression *e1x = semantic(exp->e1, sc);
7937 e1x = resolveProperties(sc, e1x);
7938
7939 unsigned cs1 = sc->callSuper;
7940 unsigned *fi1 = sc->fieldinit;
7941 sc->callSuper = cs0;
7942 sc->fieldinit = fi0;
7943 Expression *e2x = semantic(exp->e2, sc);
7944 e2x = resolveProperties(sc, e2x);
7945
7946 sc->mergeCallSuper(exp->loc, cs1);
7947 sc->mergeFieldInit(exp->loc, fi1);
7948
7949 if (ec->op == TOKerror)
7950 {
7951 result = ec;
7952 return;
7953 }
7954 if (ec->type == Type::terror)
7955 return setError();
7956 exp->econd = ec;
7957
7958 if (e1x->op == TOKerror)
7959 {
7960 result = e1x;
7961 return;
7962 }
7963 if (e1x->type == Type::terror)
7964 return setError();
7965 exp->e1 = e1x;
7966
7967 if (e2x->op == TOKerror)
7968 {
7969 result = e2x;
7970 return;
7971 }
7972 if (e2x->type == Type::terror)
7973 return setError();
7974 exp->e2 = e2x;
7975
7976 bool f0 = checkNonAssignmentArrayOp(exp->econd);
7977 bool f1 = checkNonAssignmentArrayOp(exp->e1);
7978 bool f2 = checkNonAssignmentArrayOp(exp->e2);
7979 if (f0 || f1 || f2)
7980 return setError();
7981
7982 Type *t1 = exp->e1->type;
7983 Type *t2 = exp->e2->type;
7984 // If either operand is void the result is void, we have to cast both
7985 // the expression to void so that we explicitly discard the expression
7986 // value if any (bugzilla 16598)
7987 if (t1->ty == Tvoid || t2->ty == Tvoid)
7988 {
7989 exp->type = Type::tvoid;
7990 exp->e1 = exp->e1->castTo(sc, exp->type);
7991 exp->e2 = exp->e2->castTo(sc, exp->type);
7992 }
7993 else if (t1 == t2)
7994 exp->type = t1;
7995 else
7996 {
7997 if (Expression *ex = typeCombine(exp, sc))
7998 {
7999 result = ex;
8000 return;
8001 }
8002 switch (exp->e1->type->toBasetype()->ty)
8003 {
8004 case Tcomplex32:
8005 case Tcomplex64:
8006 case Tcomplex80:
8007 exp->e2 = exp->e2->castTo(sc, exp->e1->type);
8008 break;
8009 }
8010 switch (exp->e2->type->toBasetype()->ty)
8011 {
8012 case Tcomplex32:
8013 case Tcomplex64:
8014 case Tcomplex80:
8015 exp->e1 = exp->e1->castTo(sc, exp->e2->type);
8016 break;
8017 }
8018 if (exp->type->toBasetype()->ty == Tarray)
8019 {
8020 exp->e1 = exp->e1->castTo(sc, exp->type);
8021 exp->e2 = exp->e2->castTo(sc, exp->type);
8022 }
8023 }
8024 exp->type = exp->type->merge2();
8025
8026 /* Bugzilla 14696: If either e1 or e2 contain temporaries which need dtor,
8027 * make them conditional.
8028 * Rewrite:
8029 * cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2)
8030 * to:
8031 * (auto __cond = cond) ? (... __tmp1) : (... __tmp2)
8032 * and replace edtors of __tmp1 and __tmp2 with:
8033 * __tmp1->edtor --> __cond && __tmp1.dtor()
8034 * __tmp2->edtor --> __cond || __tmp2.dtor()
8035 */
8036 exp->hookDtors(sc);
8037
8038 result = exp;
8039 }
8040
visit(FileInitExp * e)8041 void visit(FileInitExp *e)
8042 {
8043 //printf("FileInitExp::semantic()\n");
8044 e->type = Type::tstring;
8045 result = e;
8046 }
8047
visit(LineInitExp * e)8048 void visit(LineInitExp *e)
8049 {
8050 e->type = Type::tint32;
8051 result = e;
8052 }
8053
visit(ModuleInitExp * e)8054 void visit(ModuleInitExp *e)
8055 {
8056 //printf("ModuleInitExp::semantic()\n");
8057 e->type = Type::tstring;
8058 result = e;
8059 }
8060
visit(FuncInitExp * e)8061 void visit(FuncInitExp *e)
8062 {
8063 //printf("FuncInitExp::semantic()\n");
8064 e->type = Type::tstring;
8065 if (sc->func)
8066 {
8067 result = e->resolveLoc(Loc(), sc);
8068 return;
8069 }
8070 result = e;
8071 }
8072
visit(PrettyFuncInitExp * e)8073 void visit(PrettyFuncInitExp *e)
8074 {
8075 //printf("PrettyFuncInitExp::semantic()\n");
8076 e->type = Type::tstring;
8077 if (sc->func)
8078 {
8079 result = e->resolveLoc(Loc(), sc);
8080 return;
8081 }
8082 result = e;
8083 }
8084 };
8085
8086 /**********************************
8087 * Try to run semantic routines.
8088 * If they fail, return NULL.
8089 */
trySemantic(Expression * exp,Scope * sc)8090 Expression *trySemantic(Expression *exp, Scope* sc)
8091 {
8092 //printf("+trySemantic(%s)\n", toChars());
8093 unsigned errors = global.startGagging();
8094 Expression *e = semantic(exp, sc);
8095 if (global.endGagging(errors))
8096 {
8097 e = NULL;
8098 }
8099 //printf("-trySemantic(%s)\n", toChars());
8100 return e;
8101 }
8102
8103 /**************************
8104 * Helper function for easy error propagation.
8105 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8106 */
unaSemantic(UnaExp * e,Scope * sc)8107 Expression *unaSemantic(UnaExp *e, Scope *sc)
8108 {
8109 Expression *e1x = semantic(e->e1, sc);
8110 if (e1x->op == TOKerror)
8111 return e1x;
8112 e->e1 = e1x;
8113 return NULL;
8114 }
8115
8116 /**************************
8117 * Helper function for easy error propagation.
8118 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8119 */
binSemantic(BinExp * e,Scope * sc)8120 Expression *binSemantic(BinExp *e, Scope *sc)
8121 {
8122 Expression *e1x = semantic(e->e1, sc);
8123 Expression *e2x = semantic(e->e2, sc);
8124
8125 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
8126 if (e1x->op == TOKtype)
8127 e1x = resolveAliasThis(sc, e1x);
8128 if (e2x->op == TOKtype)
8129 e2x = resolveAliasThis(sc, e2x);
8130
8131 if (e1x->op == TOKerror)
8132 return e1x;
8133 if (e2x->op == TOKerror)
8134 return e2x;
8135 e->e1 = e1x;
8136 e->e2 = e2x;
8137 return NULL;
8138 }
8139
binSemanticProp(BinExp * e,Scope * sc)8140 Expression *binSemanticProp(BinExp *e, Scope *sc)
8141 {
8142 if (Expression *ex = binSemantic(e, sc))
8143 return ex;
8144 Expression *e1x = resolveProperties(sc, e->e1);
8145 Expression *e2x = resolveProperties(sc, e->e2);
8146 if (e1x->op == TOKerror)
8147 return e1x;
8148 if (e2x->op == TOKerror)
8149 return e2x;
8150 e->e1 = e1x;
8151 e->e2 = e2x;
8152 return NULL;
8153 }
8154
8155 // entrypoint for semantic ExpressionSemanticVisitor
semantic(Expression * e,Scope * sc)8156 Expression *semantic(Expression *e, Scope *sc)
8157 {
8158 ExpressionSemanticVisitor v = ExpressionSemanticVisitor(sc);
8159 e->accept(&v);
8160 return v.result;
8161 }
8162
semanticX(DotIdExp * exp,Scope * sc)8163 Expression *semanticX(DotIdExp *exp, Scope *sc)
8164 {
8165 //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
8166 if (Expression *ex = unaSemantic(exp, sc))
8167 return ex;
8168
8169 if (exp->ident == Id::_mangleof)
8170 {
8171 // symbol.mangleof
8172 Dsymbol *ds;
8173 switch (exp->e1->op)
8174 {
8175 case TOKscope:
8176 ds = ((ScopeExp *)exp->e1)->sds;
8177 goto L1;
8178 case TOKvar:
8179 ds = ((VarExp *)exp->e1)->var;
8180 goto L1;
8181 case TOKdotvar:
8182 ds = ((DotVarExp *)exp->e1)->var;
8183 goto L1;
8184 case TOKoverloadset:
8185 ds = ((OverExp *)exp->e1)->vars;
8186 goto L1;
8187 case TOKtemplate:
8188 {
8189 TemplateExp *te = (TemplateExp *)exp->e1;
8190 ds = te->fd ? (Dsymbol *)te->fd : te->td;
8191 }
8192 L1:
8193 {
8194 assert(ds);
8195 if (FuncDeclaration *f = ds->isFuncDeclaration())
8196 {
8197 if (f->checkForwardRef(exp->loc))
8198 return new ErrorExp();
8199 }
8200 OutBuffer buf;
8201 mangleToBuffer(ds, &buf);
8202 const char *s = buf.extractString();
8203 Expression *e = new StringExp(exp->loc, const_cast<char*>(s), strlen(s));
8204 e = semantic(e, sc);
8205 return e;
8206 }
8207 default:
8208 break;
8209 }
8210 }
8211
8212 if (exp->e1->op == TOKvar && exp->e1->type->toBasetype()->ty == Tsarray && exp->ident == Id::length)
8213 {
8214 // bypass checkPurity
8215 return exp->e1->type->dotExp(sc, exp->e1, exp->ident, exp->noderef ? 2 : 0);
8216 }
8217
8218 if (exp->e1->op == TOKdot)
8219 {
8220 }
8221 else
8222 {
8223 exp->e1 = resolvePropertiesX(sc, exp->e1);
8224 }
8225 if (exp->e1->op == TOKtuple && exp->ident == Id::offsetof)
8226 {
8227 /* 'distribute' the .offsetof to each of the tuple elements.
8228 */
8229 TupleExp *te = (TupleExp *)exp->e1;
8230 Expressions *exps = new Expressions();
8231 exps->setDim(te->exps->dim);
8232 for (size_t i = 0; i < exps->dim; i++)
8233 {
8234 Expression *e = (*te->exps)[i];
8235 e = semantic(e, sc);
8236 e = new DotIdExp(e->loc, e, Id::offsetof);
8237 (*exps)[i] = e;
8238 }
8239 // Don't evaluate te->e0 in runtime
8240 Expression *e = new TupleExp(exp->loc, NULL, exps);
8241 e = semantic(e, sc);
8242 return e;
8243 }
8244 if (exp->e1->op == TOKtuple && exp->ident == Id::length)
8245 {
8246 TupleExp *te = (TupleExp *)exp->e1;
8247 // Don't evaluate te->e0 in runtime
8248 Expression *e = new IntegerExp(exp->loc, te->exps->dim, Type::tsize_t);
8249 return e;
8250 }
8251
8252 // Bugzilla 14416: Template has no built-in properties except for 'stringof'.
8253 if ((exp->e1->op == TOKdottd || exp->e1->op == TOKtemplate) && exp->ident != Id::stringof)
8254 {
8255 exp->error("template %s does not have property '%s'", exp->e1->toChars(), exp->ident->toChars());
8256 return new ErrorExp();
8257 }
8258
8259 if (!exp->e1->type)
8260 {
8261 exp->error("expression %s does not have property '%s'", exp->e1->toChars(), exp->ident->toChars());
8262 return new ErrorExp();
8263 }
8264
8265 return exp;
8266 }
8267
8268 // Resolve e1.ident without seeing UFCS.
8269 // If flag == 1, stop "not a property" error and return NULL.
semanticY(DotIdExp * exp,Scope * sc,int flag)8270 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag)
8271 {
8272 //printf("DotIdExp::semanticY(this = %p, '%s')\n", this, toChars());
8273
8274 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
8275
8276 /* Special case: rewrite this.id and super.id
8277 * to be classtype.id and baseclasstype.id
8278 * if we have no this pointer.
8279 */
8280 if ((exp->e1->op == TOKthis || exp->e1->op == TOKsuper) && !hasThis(sc))
8281 {
8282 if (AggregateDeclaration *ad = sc->getStructClassScope())
8283 {
8284 if (exp->e1->op == TOKthis)
8285 {
8286 exp->e1 = new TypeExp(exp->e1->loc, ad->type);
8287 }
8288 else
8289 {
8290 ClassDeclaration *cd = ad->isClassDeclaration();
8291 if (cd && cd->baseClass)
8292 exp->e1 = new TypeExp(exp->e1->loc, cd->baseClass->type);
8293 }
8294 }
8295 }
8296
8297 Expression *e = semanticX(exp, sc);
8298 if (e != exp)
8299 return e;
8300
8301 Expression *eleft;
8302 Expression *eright;
8303 if (exp->e1->op == TOKdot)
8304 {
8305 DotExp *de = (DotExp *)exp->e1;
8306 eleft = de->e1;
8307 eright = de->e2;
8308 }
8309 else
8310 {
8311 eleft = NULL;
8312 eright = exp->e1;
8313 }
8314
8315 Type *t1b = exp->e1->type->toBasetype();
8316
8317 if (eright->op == TOKscope) // also used for template alias's
8318 {
8319 ScopeExp *ie = (ScopeExp *)eright;
8320 int flags = SearchLocalsOnly;
8321
8322 /* Disable access to another module's private imports.
8323 * The check for 'is sds our current module' is because
8324 * the current module should have access to its own imports.
8325 */
8326 if (ie->sds->isModule() && ie->sds != sc->_module)
8327 flags |= IgnorePrivateImports;
8328 if (sc->flags & SCOPEignoresymbolvisibility)
8329 flags |= IgnoreSymbolVisibility;
8330 Dsymbol *s = ie->sds->search(exp->loc, exp->ident, flags);
8331 /* Check for visibility before resolving aliases because public
8332 * aliases to private symbols are public.
8333 */
8334 if (s && !(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc->_module, s))
8335 {
8336 if (s->isDeclaration())
8337 ::error(exp->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars());
8338 else
8339 ::deprecation(exp->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars());
8340 // s = NULL
8341 }
8342 if (s)
8343 {
8344 if (Package *p = s->isPackage())
8345 checkAccess(exp->loc, sc, p);
8346
8347 // if 's' is a tuple variable, the tuple is returned.
8348 s = s->toAlias();
8349
8350 exp->checkDeprecated(sc, s);
8351
8352 EnumMember *em = s->isEnumMember();
8353 if (em)
8354 {
8355 return em->getVarExp(exp->loc, sc);
8356 }
8357
8358 VarDeclaration *v = s->isVarDeclaration();
8359 if (v)
8360 {
8361 //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
8362 if (!v->type ||
8363 (!v->type->deco && v->inuse))
8364 {
8365 if (v->inuse)
8366 exp->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
8367 else
8368 exp->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
8369 return new ErrorExp();
8370 }
8371 if (v->type->ty == Terror)
8372 return new ErrorExp();
8373
8374 if ((v->storage_class & STCmanifest) && v->_init && !exp->wantsym)
8375 {
8376 /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2().
8377 * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably
8378 * be reverted. `wantsym` is the hack to work around the problem.
8379 */
8380 if (v->inuse)
8381 {
8382 ::error(exp->loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
8383 return new ErrorExp();
8384 }
8385 e = v->expandInitializer(exp->loc);
8386 v->inuse++;
8387 e = semantic(e, sc);
8388 v->inuse--;
8389 return e;
8390 }
8391
8392 if (v->needThis())
8393 {
8394 if (!eleft)
8395 eleft = new ThisExp(exp->loc);
8396 e = new DotVarExp(exp->loc, eleft, v);
8397 e = semantic(e, sc);
8398 }
8399 else
8400 {
8401 e = new VarExp(exp->loc, v);
8402 if (eleft)
8403 { e = new CommaExp(exp->loc, eleft, e);
8404 e->type = v->type;
8405 }
8406 }
8407 e = e->deref();
8408 return semantic(e, sc);
8409 }
8410
8411 FuncDeclaration *f = s->isFuncDeclaration();
8412 if (f)
8413 {
8414 //printf("it's a function\n");
8415 if (!f->functionSemantic())
8416 return new ErrorExp();
8417 if (f->needThis())
8418 {
8419 if (!eleft)
8420 eleft = new ThisExp(exp->loc);
8421 e = new DotVarExp(exp->loc, eleft, f, true);
8422 e = semantic(e, sc);
8423 }
8424 else
8425 {
8426 e = new VarExp(exp->loc, f, true);
8427 if (eleft)
8428 { e = new CommaExp(exp->loc, eleft, e);
8429 e->type = f->type;
8430 }
8431 }
8432 return e;
8433 }
8434 if (TemplateDeclaration *td = s->isTemplateDeclaration())
8435 {
8436 if (eleft)
8437 e = new DotTemplateExp(exp->loc, eleft, td);
8438 else
8439 e = new TemplateExp(exp->loc, td);
8440 e = semantic(e, sc);
8441 return e;
8442 }
8443 if (OverDeclaration *od = s->isOverDeclaration())
8444 {
8445 e = new VarExp(exp->loc, od, true);
8446 if (eleft)
8447 {
8448 e = new CommaExp(exp->loc, eleft, e);
8449 e->type = Type::tvoid; // ambiguous type?
8450 }
8451 return e;
8452 }
8453 OverloadSet *o = s->isOverloadSet();
8454 if (o)
8455 { //printf("'%s' is an overload set\n", o->toChars());
8456 return new OverExp(exp->loc, o);
8457 }
8458
8459 if (Type *t = s->getType())
8460 {
8461 return semantic(new TypeExp(exp->loc, t), sc);
8462 }
8463
8464 TupleDeclaration *tup = s->isTupleDeclaration();
8465 if (tup)
8466 {
8467 if (eleft)
8468 {
8469 e = new DotVarExp(exp->loc, eleft, tup);
8470 e = semantic(e, sc);
8471 return e;
8472 }
8473 e = new TupleExp(exp->loc, tup);
8474 e = semantic(e, sc);
8475 return e;
8476 }
8477
8478 ScopeDsymbol *sds = s->isScopeDsymbol();
8479 if (sds)
8480 {
8481 //printf("it's a ScopeDsymbol %s\n", exp->ident->toChars());
8482 e = new ScopeExp(exp->loc, sds);
8483 e = semantic(e, sc);
8484 if (eleft)
8485 e = new DotExp(exp->loc, eleft, e);
8486 return e;
8487 }
8488
8489 Import *imp = s->isImport();
8490 if (imp)
8491 {
8492 ie = new ScopeExp(exp->loc, imp->pkg);
8493 return semantic(ie, sc);
8494 }
8495
8496 // BUG: handle other cases like in IdentifierExp::semantic()
8497 assert(0);
8498 }
8499 else if (exp->ident == Id::stringof)
8500 {
8501 const char *p = ie->toChars();
8502 e = new StringExp(exp->loc, const_cast<char *>(p), strlen(p));
8503 e = semantic(e, sc);
8504 return e;
8505 }
8506 if (ie->sds->isPackage() ||
8507 ie->sds->isImport() ||
8508 ie->sds->isModule())
8509 {
8510 flag = 0;
8511 }
8512 if (flag)
8513 return NULL;
8514 s = ie->sds->search_correct(exp->ident);
8515 if (s)
8516 exp->error("undefined identifier '%s' in %s '%s', did you mean %s '%s'?",
8517 exp->ident->toChars(), ie->sds->kind(), ie->sds->toPrettyChars(), s->kind(), s->toChars());
8518 else
8519 exp->error("undefined identifier '%s' in %s '%s'",
8520 exp->ident->toChars(), ie->sds->kind(), ie->sds->toPrettyChars());
8521 return new ErrorExp();
8522 }
8523 else if (t1b->ty == Tpointer && exp->e1->type->ty != Tenum &&
8524 exp->ident != Id::_init && exp->ident != Id::__sizeof &&
8525 exp->ident != Id::__xalignof && exp->ident != Id::offsetof &&
8526 exp->ident != Id::_mangleof && exp->ident != Id::stringof)
8527 {
8528 Type *t1bn = t1b->nextOf();
8529 if (flag)
8530 {
8531 AggregateDeclaration *ad = isAggregate(t1bn);
8532 if (ad && !ad->members) // Bugzilla 11312
8533 return NULL;
8534 }
8535
8536 /* Rewrite:
8537 * p.ident
8538 * as:
8539 * (*p).ident
8540 */
8541 if (flag && t1bn->ty == Tvoid)
8542 return NULL;
8543 e = new PtrExp(exp->loc, exp->e1);
8544 e = semantic(e, sc);
8545 return e->type->dotExp(sc, e, exp->ident, flag | (exp->noderef ? 2 : 0));
8546 }
8547 else
8548 {
8549 if (exp->e1->op == TOKtype || exp->e1->op == TOKtemplate)
8550 flag = 0;
8551 e = exp->e1->type->dotExp(sc, exp->e1, exp->ident, flag | (exp->noderef ? 2 : 0));
8552 if (e)
8553 e = semantic(e, sc);
8554 return e;
8555 }
8556 }
8557
8558 // Resolve e1.ident!tiargs without seeing UFCS.
8559 // If flag == 1, stop "not a property" error and return NULL.
semanticY(DotTemplateInstanceExp * exp,Scope * sc,int flag)8560 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag)
8561 {
8562 DotIdExp *die = new DotIdExp(exp->loc, exp->e1, exp->ti->name);
8563
8564 Expression *e = semanticX(die, sc);
8565 if (e == die)
8566 {
8567 exp->e1 = die->e1; // take back
8568
8569 Type *t1b = exp->e1->type->toBasetype();
8570 if (t1b->ty == Tarray || t1b->ty == Tsarray || t1b->ty == Taarray ||
8571 t1b->ty == Tnull || (t1b->isTypeBasic() && t1b->ty != Tvoid))
8572 {
8573 /* No built-in type has templatized properties, so do shortcut.
8574 * It is necessary in: 1024.max!"a < b"
8575 */
8576 if (flag)
8577 return NULL;
8578 }
8579 e = semanticY(die, sc, flag);
8580 if (flag && e && isDotOpDispatch(e))
8581 {
8582 /* opDispatch!tiargs would be a function template that needs IFTI,
8583 * so it's not a template
8584 */
8585 e = NULL; /* fall down to UFCS */
8586 }
8587 if (flag && !e)
8588 return NULL;
8589 }
8590 assert(e);
8591
8592 if (e->op == TOKerror)
8593 return e;
8594 if (e->op == TOKdotvar)
8595 {
8596 DotVarExp *dve = (DotVarExp *)e;
8597 if (FuncDeclaration *fd = dve->var->isFuncDeclaration())
8598 {
8599 TemplateDeclaration *td = fd->findTemplateDeclRoot();
8600 if (td)
8601 {
8602 e = new DotTemplateExp(dve->loc, dve->e1, td);
8603 e = semantic(e, sc);
8604 }
8605 }
8606 else if (dve->var->isOverDeclaration())
8607 {
8608 exp->e1 = dve->e1; // pull semantic() result
8609 if (!exp->findTempDecl(sc))
8610 goto Lerr;
8611 if (exp->ti->needsTypeInference(sc))
8612 return exp;
8613 exp->ti->semantic(sc);
8614 if (!exp->ti->inst || exp->ti->errors) // if template failed to expand
8615 return new ErrorExp();
8616 Dsymbol *s = exp->ti->toAlias();
8617 Declaration *v = s->isDeclaration();
8618 if (v)
8619 {
8620 if (v->type && !v->type->deco)
8621 v->type = v->type->semantic(v->loc, sc);
8622 e = new DotVarExp(exp->loc, exp->e1, v);
8623 e = semantic(e, sc);
8624 return e;
8625 }
8626 e = new ScopeExp(exp->loc, exp->ti);
8627 e = new DotExp(exp->loc, exp->e1, e);
8628 e = semantic(e, sc);
8629 return e;
8630 }
8631 }
8632 else if (e->op == TOKvar)
8633 {
8634 VarExp *ve = (VarExp *)e;
8635 if (FuncDeclaration *fd = ve->var->isFuncDeclaration())
8636 {
8637 TemplateDeclaration *td = fd->findTemplateDeclRoot();
8638 if (td)
8639 {
8640 e = new TemplateExp(ve->loc, td);
8641 e = semantic(e, sc);
8642 }
8643 }
8644 else if (OverDeclaration *od = ve->var->isOverDeclaration())
8645 {
8646 exp->ti->tempdecl = od;
8647 e = new ScopeExp(exp->loc, exp->ti);
8648 e = semantic(e, sc);
8649 return e;
8650 }
8651 }
8652 if (e->op == TOKdottd)
8653 {
8654 DotTemplateExp *dte = (DotTemplateExp *)e;
8655 exp->e1 = dte->e1; // pull semantic() result
8656
8657 exp->ti->tempdecl = dte->td;
8658 if (!exp->ti->semanticTiargs(sc))
8659 return new ErrorExp();
8660 if (exp->ti->needsTypeInference(sc))
8661 return exp;
8662 exp->ti->semantic(sc);
8663 if (!exp->ti->inst || exp->ti->errors) // if template failed to expand
8664 return new ErrorExp();
8665 Dsymbol *s = exp->ti->toAlias();
8666 Declaration *v = s->isDeclaration();
8667 if (v && (v->isFuncDeclaration() || v->isVarDeclaration()))
8668 {
8669 e = new DotVarExp(exp->loc, exp->e1, v);
8670 e = semantic(e, sc);
8671 return e;
8672 }
8673 e = new ScopeExp(exp->loc, exp->ti);
8674 e = new DotExp(exp->loc, exp->e1, e);
8675 e = semantic(e, sc);
8676 return e;
8677 }
8678 else if (e->op == TOKtemplate)
8679 {
8680 exp->ti->tempdecl = ((TemplateExp *)e)->td;
8681 e = new ScopeExp(exp->loc, exp->ti);
8682 e = semantic(e, sc);
8683 return e;
8684 }
8685 else if (e->op == TOKdot)
8686 {
8687 DotExp *de = (DotExp *)e;
8688
8689 if (de->e2->op == TOKoverloadset)
8690 {
8691 if (!exp->findTempDecl(sc) ||
8692 !exp->ti->semanticTiargs(sc))
8693 {
8694 return new ErrorExp();
8695 }
8696 if (exp->ti->needsTypeInference(sc))
8697 return exp;
8698 exp->ti->semantic(sc);
8699 if (!exp->ti->inst || exp->ti->errors) // if template failed to expand
8700 return new ErrorExp();
8701 Dsymbol *s = exp->ti->toAlias();
8702 Declaration *v = s->isDeclaration();
8703 if (v)
8704 {
8705 if (v->type && !v->type->deco)
8706 v->type = v->type->semantic(v->loc, sc);
8707 e = new DotVarExp(exp->loc, exp->e1, v);
8708 e = semantic(e, sc);
8709 return e;
8710 }
8711 e = new ScopeExp(exp->loc, exp->ti);
8712 e = new DotExp(exp->loc, exp->e1, e);
8713 e = semantic(e, sc);
8714 return e;
8715 }
8716 }
8717 else if (e->op == TOKoverloadset)
8718 {
8719 OverExp *oe = (OverExp *)e;
8720 exp->ti->tempdecl = oe->vars;
8721 e = new ScopeExp(exp->loc, exp->ti);
8722 e = semantic(e, sc);
8723 return e;
8724 }
8725 Lerr:
8726 e->error("%s isn't a template", e->toChars());
8727 return new ErrorExp();
8728 }
8729