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