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