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