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