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