comparison dmd/expression.c @ 1587:def7a1d494fd

Merge DMD 1.051
author Christian Kamm <kamm incasoftware de>
date Fri, 06 Nov 2009 23:58:01 +0100
parents 05c235309d6f
children 2afcaab30a6a
comparison
equal deleted inserted replaced
1586:7f728c52e63c 1587:def7a1d494fd
33 int isnan(double); 33 int isnan(double);
34 #endif 34 #endif
35 #endif 35 #endif
36 36
37 #include "rmem.h" 37 #include "rmem.h"
38 38 #include "port.h"
39 //#include "port.h" 39
40 #include "mtype.h" 40 #include "mtype.h"
41 #include "init.h" 41 #include "init.h"
42 #include "expression.h" 42 #include "expression.h"
43 #include "template.h" 43 #include "template.h"
44 #include "utf.h" 44 #include "utf.h"
371 { 371 {
372 e->error("expression has no value"); 372 e->error("expression has no value");
373 } 373 }
374 374
375 } 375 }
376 else if (e->op == TOKdottd)
377 {
378 e = new CallExp(e->loc, e);
379 e = e->semantic(sc);
380 }
376 return e; 381 return e;
377 } 382 }
378 383
379 /****************************** 384 /******************************
380 * Perform semantic() on an array of Expressions. 385 * Perform semantic() on an array of Expressions.
541 assert(arguments); 546 assert(arguments);
542 size_t nargs = arguments ? arguments->dim : 0; 547 size_t nargs = arguments ? arguments->dim : 0;
543 size_t nparams = Argument::dim(tf->parameters); 548 size_t nparams = Argument::dim(tf->parameters);
544 549
545 if (nargs > nparams && tf->varargs == 0) 550 if (nargs > nparams && tf->varargs == 0)
546 error(loc, "expected %zu arguments, not %zu", nparams, nargs); 551 error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars());
547 552
548 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) 553 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
549 554
550 int done = 0; 555 int done = 0;
551 for (size_t i = 0; i < n; i++) 556 for (size_t i = 0; i < n; i++)
566 { 571 {
567 if (!p->defaultArg) 572 if (!p->defaultArg)
568 { 573 {
569 if (tf->varargs == 2 && i + 1 == nparams) 574 if (tf->varargs == 2 && i + 1 == nparams)
570 goto L2; 575 goto L2;
571 error(loc, "expected %zu arguments, not %zu", nparams, nargs); 576 error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
572 break; 577 break;
573 } 578 }
574 arg = p->defaultArg; 579 arg = p->defaultArg;
575 #if DMDV2 580 #if DMDV2
576 if (arg->op == TOKdefault) 581 if (arg->op == TOKdefault)
588 { 593 {
589 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars()); 594 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
590 if (arg->implicitConvTo(p->type)) 595 if (arg->implicitConvTo(p->type))
591 { 596 {
592 if (nargs != nparams) 597 if (nargs != nparams)
593 error(loc, "expected %zu arguments, not %zu", nparams, nargs); 598 error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
594 goto L1; 599 goto L1;
595 } 600 }
596 L2: 601 L2:
597 Type *tb = p->type->toBasetype(); 602 Type *tb = p->type->toBasetype();
598 Type *tret = p->isLazyArray(); 603 Type *tret = p->isLazyArray();
667 done = 1; 672 done = 1;
668 } 673 }
669 674
670 L1: 675 L1:
671 if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) 676 if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
672 arg = arg->implicitCastTo(sc, p->type); 677 {
678 if (p->type != arg->type)
679 {
680 //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars());
681 if (arg->op == TOKtype)
682 arg->error("cannot pass type %s as function argument", arg->toChars());
683 arg = arg->implicitCastTo(sc, p->type);
684 arg = arg->optimize(WANTvalue);
685 }
686 }
673 if (p->storageClass & (STCout | STCref)) 687 if (p->storageClass & (STCout | STCref))
674 { 688 {
675 // BUG: should check that argument to ref is type 'invariant' 689 // BUG: should check that argument to ref is type 'invariant'
676 // BUG: assignments to ref should also be type 'invariant' 690 // BUG: assignments to ref should also be type 'invariant'
677 arg = arg->modifiableLvalue(sc, arg); 691 arg = arg->modifiableLvalue(sc, arg);
771 #if DMDV2 785 #if DMDV2
772 if (tb->ty == Tstruct) 786 if (tb->ty == Tstruct)
773 { 787 {
774 arg = callCpCtor(loc, sc, arg); 788 arg = callCpCtor(loc, sc, arg);
775 } 789 }
790 #endif
776 791
777 // Give error for overloaded function addresses 792 // Give error for overloaded function addresses
793 #if DMDV2
778 if (arg->op == TOKsymoff) 794 if (arg->op == TOKsymoff)
779 { SymOffExp *se = (SymOffExp *)arg; 795 { SymOffExp *se = (SymOffExp *)arg;
780 if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) 796 if (
797 se->hasOverloads &&
798 !se->var->isFuncDeclaration()->isUnique())
781 arg->error("function %s is overloaded", arg->toChars()); 799 arg->error("function %s is overloaded", arg->toChars());
782 } 800 }
783 #endif 801 #endif
784 arg->rvalue(); 802 arg->rvalue();
785 } 803 }
1212 */ 1230 */
1213 1231
1214 Expression *Expression::deref() 1232 Expression *Expression::deref()
1215 { 1233 {
1216 //printf("Expression::deref()\n"); 1234 //printf("Expression::deref()\n");
1217 if (type->ty == Treference) 1235 // type could be null if forward referencing an 'auto' variable
1218 { Expression *e; 1236 if (type && type->ty == Treference)
1219 1237 {
1220 e = new PtrExp(loc, this); 1238 Expression *e = new PtrExp(loc, this);
1221 e->type = ((TypeReference *)type)->next; 1239 e->type = ((TypeReference *)type)->next;
1222 return e; 1240 return e;
1223 } 1241 }
1224 return this; 1242 return this;
1225 } 1243 }
2153 return e->semantic(sc); 2171 return e->semantic(sc);
2154 } 2172 }
2155 f = s->isFuncDeclaration(); 2173 f = s->isFuncDeclaration();
2156 if (f) 2174 if (f)
2157 { //printf("'%s' is a function\n", f->toChars()); 2175 { //printf("'%s' is a function\n", f->toChars());
2176 if (!f->type->deco)
2177 {
2178 error("forward reference to %s", toChars());
2179 }
2158 return new VarExp(loc, f); 2180 return new VarExp(loc, f);
2159 } 2181 }
2160 cd = s->isClassDeclaration(); 2182 cd = s->isClassDeclaration();
2161 if (cd && thiscd && cd->isBaseOf(thiscd, NULL) && sc->func->needThis()) 2183 if (cd && thiscd && cd->isBaseOf(thiscd, NULL) && sc->func->needThis())
2162 { 2184 {
2207 return e; 2229 return e;
2208 } 2230 }
2209 2231
2210 TemplateInstance *ti = s->isTemplateInstance(); 2232 TemplateInstance *ti = s->isTemplateInstance();
2211 if (ti && !global.errors) 2233 if (ti && !global.errors)
2212 { if (!ti->semanticdone) 2234 { if (!ti->semanticRun)
2213 ti->semantic(sc); 2235 ti->semantic(sc);
2214 s = ti->inst->toAlias(); 2236 s = ti->inst->toAlias();
2215 if (!s->isTemplateInstance()) 2237 if (!s->isTemplateInstance())
2216 goto Lagain; 2238 goto Lagain;
2217 e = new ScopeExp(loc, ti); 2239 e = new ScopeExp(loc, ti);
3164 else 3186 else
3165 { 3187 {
3166 if (v->init) 3188 if (v->init)
3167 { e = v->init->toExpression(); 3189 { e = v->init->toExpression();
3168 if (!e) 3190 if (!e)
3169 error("cannot make expression out of initializer for %s", v->toChars()); 3191 { error("cannot make expression out of initializer for %s", v->toChars());
3192 e = new ErrorExp();
3193 }
3194 else if (v->scope)
3195 { // Do deferred semantic anaylsis
3196 Initializer *i2 = v->init->syntaxCopy();
3197 i2 = i2->semantic(v->scope, v->type);
3198 e = i2->toExpression();
3199 v->scope = NULL;
3200 }
3170 } 3201 }
3171 else 3202 else
3172 { e = v->type->defaultInit(); 3203 { e = v->type->defaultInit();
3173 e->loc = loc; 3204 e->loc = loc;
3174 } 3205 }
3198 //printf("\ti = %d\n", i); 3229 //printf("\ti = %d\n", i);
3199 assert(i < elements->dim); 3230 assert(i < elements->dim);
3200 e = (Expression *)elements->data[i]; 3231 e = (Expression *)elements->data[i];
3201 if (e) 3232 if (e)
3202 { 3233 {
3203 e = e->copy(); 3234 //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars());
3204 e->type = type; 3235
3236 /* If type is a static array, and e is an initializer for that array,
3237 * then the field initializer should be an array literal of e.
3238 */
3239 if (e->type != type && type->ty == Tsarray)
3240 { TypeSArray *tsa = (TypeSArray *)type;
3241 uinteger_t length = tsa->dim->toInteger();
3242 Expressions *z = new Expressions;
3243 z->setDim(length);
3244 for (int q = 0; q < length; ++q)
3245 z->data[q] = e->copy();
3246 e = new ArrayLiteralExp(loc, z);
3247 e->type = type;
3248 }
3249 else
3250 {
3251 e = e->copy();
3252 e->type = type;
3253 }
3205 } 3254 }
3206 } 3255 }
3207 return e; 3256 return e;
3208 } 3257 }
3209 3258
3214 3263
3215 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) 3264 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
3216 { 3265 {
3217 /* Find which field offset is by looking at the field offsets 3266 /* Find which field offset is by looking at the field offsets
3218 */ 3267 */
3219 for (size_t i = 0; i < sd->fields.dim; i++) 3268 if (elements->dim)
3220 { 3269 {
3221 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 3270 for (size_t i = 0; i < sd->fields.dim; i++)
3222 VarDeclaration *v = s->isVarDeclaration(); 3271 {
3223 assert(v); 3272 Dsymbol *s = (Dsymbol *)sd->fields.data[i];
3224 3273 VarDeclaration *v = s->isVarDeclaration();
3225 if (offset == v->offset && 3274 assert(v);
3226 type->size() == v->type->size()) 3275
3227 { Expression *e = (Expression *)elements->data[i]; 3276 if (offset == v->offset &&
3228 if (e) 3277 type->size() == v->type->size())
3229 { 3278 { Expression *e = (Expression *)elements->data[i];
3230 return i; 3279 if (e)
3231 } 3280 {
3232 break; 3281 return i;
3282 }
3283 break;
3284 }
3233 } 3285 }
3234 } 3286 }
3235 return -1; 3287 return -1;
3236 } 3288 }
3237 3289
3363 #endif 3415 #endif
3364 Lagain: 3416 Lagain:
3365 ti = sds->isTemplateInstance(); 3417 ti = sds->isTemplateInstance();
3366 if (ti && !global.errors) 3418 if (ti && !global.errors)
3367 { Dsymbol *s; 3419 { Dsymbol *s;
3368 if (!ti->semanticdone) 3420 if (!ti->semanticRun)
3369 ti->semantic(sc); 3421 ti->semantic(sc);
3370 s = ti->inst->toAlias(); 3422 s = ti->inst->toAlias();
3371 sds2 = s->isScopeDsymbol(); 3423 sds2 = s->isScopeDsymbol();
3372 if (!sds2) 3424 if (!sds2)
3373 { Expression *e; 3425 { Expression *e;
3581 #endif 3633 #endif
3582 } 3634 }
3583 else if (thisexp) 3635 else if (thisexp)
3584 error("e.new is only for allocating nested classes"); 3636 error("e.new is only for allocating nested classes");
3585 else if (fdn) 3637 else if (fdn)
3586 { 3638 {
3587 // make sure the parent context fdn of cd is reachable from sc 3639 // make sure the parent context fdn of cd is reachable from sc
3588 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) 3640 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent)
3589 { 3641 {
3590 if (fdn == sp) 3642 if (fdn == sp)
3591 break; 3643 break;
3604 3656
3605 FuncDeclaration *f = cd->ctor; 3657 FuncDeclaration *f = cd->ctor;
3606 if (f) 3658 if (f)
3607 { 3659 {
3608 assert(f); 3660 assert(f);
3609 f = f->overloadResolve(loc, arguments, sc->module); 3661 f = f->overloadResolve(loc, NULL, arguments, sc->module);
3610 checkDeprecated(sc, f); 3662 checkDeprecated(sc, f);
3611 member = f->isCtorDeclaration(); 3663 member = f->isCtorDeclaration();
3612 assert(member); 3664 assert(member);
3613 3665
3614 cd->accessCheck(loc, sc, member); 3666 cd->accessCheck(loc, sc, member);
3632 Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t); 3684 Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t);
3633 if (!newargs) 3685 if (!newargs)
3634 newargs = new Expressions(); 3686 newargs = new Expressions();
3635 newargs->shift(e); 3687 newargs->shift(e);
3636 3688
3637 f = cd->aggNew->overloadResolve(loc, newargs, sc->module); 3689 f = cd->aggNew->overloadResolve(loc, NULL, newargs, sc->module);
3638 allocator = f->isNewDeclaration(); 3690 allocator = f->isNewDeclaration();
3639 assert(allocator); 3691 assert(allocator);
3640 3692
3641 tf = (TypeFunction *)f->type; 3693 tf = (TypeFunction *)f->type;
3642 functionArguments(loc, sc, tf, newargs); 3694 functionArguments(loc, sc, tf, newargs);
3665 e = new IntegerExp(loc, sd->size(loc), Type::tuns32); 3717 e = new IntegerExp(loc, sd->size(loc), Type::tuns32);
3666 if (!newargs) 3718 if (!newargs)
3667 newargs = new Expressions(); 3719 newargs = new Expressions();
3668 newargs->shift(e); 3720 newargs->shift(e);
3669 3721
3670 f = f->overloadResolve(loc, newargs, sc->module); 3722 f = f->overloadResolve(loc, NULL, newargs, sc->module);
3671 allocator = f->isNewDeclaration(); 3723 allocator = f->isNewDeclaration();
3672 assert(allocator); 3724 assert(allocator);
3673 3725
3674 tf = (TypeFunction *)f->type; 3726 tf = (TypeFunction *)f->type;
3675 functionArguments(loc, sc, tf, newargs); 3727 functionArguments(loc, sc, tf, newargs);
4198 if (0 && exps->dim == 1) 4250 if (0 && exps->dim == 1)
4199 { 4251 {
4200 return (Expression *)exps->data[0]; 4252 return (Expression *)exps->data[0];
4201 } 4253 }
4202 type = new TypeTuple(exps); 4254 type = new TypeTuple(exps);
4255 type = type->semantic(loc, sc);
4203 //printf("-TupleExp::semantic(%s)\n", toChars()); 4256 //printf("-TupleExp::semantic(%s)\n", toChars());
4204 return this; 4257 return this;
4205 } 4258 }
4206 4259
4207 void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4260 void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4261 { 4314 {
4262 fd->semantic(sc); 4315 fd->semantic(sc);
4263 fd->parent = sc->parent; 4316 fd->parent = sc->parent;
4264 if (global.errors) 4317 if (global.errors)
4265 { 4318 {
4266 if (!fd->type->next)
4267 fd->type->next = Type::terror;
4268 } 4319 }
4269 else 4320 else
4270 { 4321 {
4271 fd->semantic2(sc); 4322 fd->semantic2(sc);
4272 if (!global.errors) 4323 if (!global.errors ||
4324 // need to infer return type
4325 (fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()))
4273 { 4326 {
4274 fd->semantic3(sc); 4327 fd->semantic3(sc);
4275 4328
4276 if (!global.errors && global.params.useInline) 4329 if (!global.errors && global.params.useInline)
4277 fd->inlineScan(); 4330 fd->inlineScan();
4278 } 4331 }
4279 } 4332 }
4333
4334 // need to infer return type
4335 if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())
4336 ((TypeFunction *)fd->type)->next = Type::terror;
4280 4337
4281 // Type is a "delegate to" or "pointer to" the function literal 4338 // Type is a "delegate to" or "pointer to" the function literal
4282 if (fd->isNested()) 4339 if (fd->isNested())
4283 { 4340 {
4284 type = new TypeDelegate(fd->type); 4341 type = new TypeDelegate(fd->type);
4375 } 4432 }
4376 } 4433 }
4377 } 4434 }
4378 if (!s->isVarDeclaration()) 4435 if (!s->isVarDeclaration())
4379 { 4436 {
4380 declaration->semantic(sc); 4437 Scope *sc2 = sc;
4438 if (sc2->stc & (STCpure | STCnothrow))
4439 sc2 = sc->push();
4440 sc2->stc &= ~(STCpure | STCnothrow);
4441 declaration->semantic(sc2);
4442 if (sc2 != sc)
4443 sc2->pop();
4381 s->parent = sc->parent; 4444 s->parent = sc->parent;
4382 } 4445 }
4383 if (!global.errors) 4446 if (!global.errors)
4384 { 4447 {
4385 declaration->semantic2(sc); 4448 declaration->semantic2(sc);
4918 e1->checkArithmetic(); 4981 e1->checkArithmetic();
4919 e2->checkArithmetic(); 4982 e2->checkArithmetic();
4920 4983
4921 if (op == TOKmodass && e2->type->iscomplex()) 4984 if (op == TOKmodass && e2->type->iscomplex())
4922 { error("cannot perform modulo complex arithmetic"); 4985 { error("cannot perform modulo complex arithmetic");
4923 return new IntegerExp(0); 4986 return new ErrorExp();
4924 } 4987 }
4925 } 4988 }
4926 return this; 4989 return this;
4927 } 4990 }
4928 4991
4983 op == TOKremove) 5046 op == TOKremove)
4984 return 1; 5047 return 1;
4985 return Expression::checkSideEffect(flag); 5048 return Expression::checkSideEffect(flag);
4986 } 5049 }
4987 5050
5051 // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary
5052 void BinExp::checkComplexMulAssign()
5053 {
5054 // Any multiplication by an imaginary or complex number yields a complex result.
5055 // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
5056 const char *opstr = Token::toChars(op);
5057 if ( e1->type->isreal() && e2->type->iscomplex())
5058 {
5059 error("%s %s %s is undefined. Did you mean %s %s %s.re ?",
5060 e1->type->toChars(), opstr, e2->type->toChars(),
5061 e1->type->toChars(), opstr, e2->type->toChars());
5062 }
5063 else if (e1->type->isimaginary() && e2->type->iscomplex())
5064 {
5065 error("%s %s %s is undefined. Did you mean %s %s %s.im ?",
5066 e1->type->toChars(), opstr, e2->type->toChars(),
5067 e1->type->toChars(), opstr, e2->type->toChars());
5068 }
5069 else if ((e1->type->isreal() || e1->type->isimaginary()) &&
5070 e2->type->isimaginary())
5071 {
5072 error("%s %s %s is an undefined operation", e1->type->toChars(),
5073 opstr, e2->type->toChars());
5074 }
5075 }
5076
5077 // generate an error if this is a nonsensical += or -=, eg real += imaginary
5078 void BinExp::checkComplexAddAssign()
5079 {
5080 // Addition or subtraction of a real and an imaginary is a complex result.
5081 // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
5082 if ( (e1->type->isreal() && (e2->type->isimaginary() || e2->type->iscomplex())) ||
5083 (e1->type->isimaginary() && (e2->type->isreal() || e2->type->iscomplex()))
5084 )
5085 {
5086 error("%s %s %s is undefined (result is complex)",
5087 e1->type->toChars(), Token::toChars(op), e2->type->toChars());
5088 }
5089 }
5090
4988 void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5091 void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4989 { 5092 {
4990 expToCBuffer(buf, hgs, e1, precedence[op]); 5093 expToCBuffer(buf, hgs, e1, precedence[op]);
4991 buf->writeByte(' '); 5094 buf->writeByte(' ');
4992 buf->writestring(Token::toChars(op)); 5095 buf->writestring(Token::toChars(op));
5092 { error("file %s cannot be found, check -Jpath", se->toChars()); 5195 { error("file %s cannot be found, check -Jpath", se->toChars());
5093 goto Lerror; 5196 goto Lerror;
5094 } 5197 }
5095 5198
5096 if (global.params.verbose) 5199 if (global.params.verbose)
5097 printf("file %s\t(%s)\n", (char*)se->string, name); 5200 printf("file %s\t(%s)\n", (char *)se->string, name);
5098 5201
5099 { File f(name); 5202 { File f(name);
5100 if (f.read()) 5203 if (f.read())
5101 { error("cannot read file %s", f.toChars()); 5204 { error("cannot read file %s", f.toChars());
5102 goto Lerror; 5205 goto Lerror;
5175 } 5278 }
5176 5279
5177 #if DMDV2 5280 #if DMDV2
5178 int AssertExp::canThrow() 5281 int AssertExp::canThrow()
5179 { 5282 {
5180 return (global.params.useAssert != 0); 5283 /* assert()s are non-recoverable errors, so functions that
5284 * use them can be considered "nothrow"
5285 */
5286 return 0; //(global.params.useAssert != 0);
5181 } 5287 }
5182 #endif 5288 #endif
5183 5289
5184 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5290 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5185 { 5291 {
5477 } 5583 }
5478 else if (e1->type->ty == Tpointer && 5584 else if (e1->type->ty == Tpointer &&
5479 ident != Id::init && ident != Id::__sizeof && 5585 ident != Id::init && ident != Id::__sizeof &&
5480 ident != Id::alignof && ident != Id::offsetof && 5586 ident != Id::alignof && ident != Id::offsetof &&
5481 ident != Id::mangleof && ident != Id::stringof) 5587 ident != Id::mangleof && ident != Id::stringof)
5482 { 5588 { /* Rewrite:
5589 * p.ident
5590 * as:
5591 * (*p).ident
5592 */
5483 e = new PtrExp(loc, e1); 5593 e = new PtrExp(loc, e1);
5484 e->type = ((TypePointer *)e1->type)->next; 5594 e->type = ((TypePointer *)e1->type)->next;
5485 return e->type->dotExp(sc, e, ident); 5595 return e->type->dotExp(sc, e, ident);
5486 } 5596 }
5487 #if DMDV2 5597 #if DMDV2
5596 5706
5597 e1 = e1->semantic(sc); 5707 e1 = e1->semantic(sc);
5598 type = var->type; 5708 type = var->type;
5599 if (!type && global.errors) 5709 if (!type && global.errors)
5600 { // var is goofed up, just return 0 5710 { // var is goofed up, just return 0
5601 return new IntegerExp(0); 5711 return new ErrorExp();
5602 } 5712 }
5603 assert(type); 5713 assert(type);
5604 5714
5605 if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution 5715 if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution
5606 { 5716 {
5933 6043
5934 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1) 6044 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1)
5935 : UnaExp(loc, TOKcall, sizeof(CallExp), e) 6045 : UnaExp(loc, TOKcall, sizeof(CallExp), e)
5936 { 6046 {
5937 Expressions *arguments = new Expressions(); 6047 Expressions *arguments = new Expressions();
5938 arguments->setDim(1); 6048 if (earg1)
5939 arguments->data[0] = (void *)earg1; 6049 { arguments->setDim(1);
5940 6050 arguments->data[0] = (void *)earg1;
6051 }
5941 this->arguments = arguments; 6052 this->arguments = arguments;
5942 } 6053 }
5943 6054
5944 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2) 6055 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2)
5945 : UnaExp(loc, TOKcall, sizeof(CallExp), e) 6056 : UnaExp(loc, TOKcall, sizeof(CallExp), e)
6038 * foo!(tiargs)(funcargs) 6149 * foo!(tiargs)(funcargs)
6039 */ 6150 */
6040 if (e1->op == TOKimport && !e1->type) 6151 if (e1->op == TOKimport && !e1->type)
6041 { ScopeExp *se = (ScopeExp *)e1; 6152 { ScopeExp *se = (ScopeExp *)e1;
6042 TemplateInstance *ti = se->sds->isTemplateInstance(); 6153 TemplateInstance *ti = se->sds->isTemplateInstance();
6043 if (ti && !ti->semanticdone) 6154 if (ti && !ti->semanticRun)
6044 { 6155 {
6045 /* Attempt to instantiate ti. If that works, go with it. 6156 /* Attempt to instantiate ti. If that works, go with it.
6046 * If not, go with partial explicit specialization. 6157 * If not, go with partial explicit specialization.
6047 */ 6158 */
6048 ti->semanticTiargs(sc); 6159 ti->semanticTiargs(sc);
6065 * expr.foo!(tiargs)(funcargs) 6176 * expr.foo!(tiargs)(funcargs)
6066 */ 6177 */
6067 if (e1->op == TOKdotti && !e1->type) 6178 if (e1->op == TOKdotti && !e1->type)
6068 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; 6179 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1;
6069 TemplateInstance *ti = se->ti; 6180 TemplateInstance *ti = se->ti;
6070 if (!ti->semanticdone) 6181 if (!ti->semanticRun)
6071 { 6182 {
6072 /* Attempt to instantiate ti. If that works, go with it. 6183 /* Attempt to instantiate ti. If that works, go with it.
6073 * If not, go with partial explicit specialization. 6184 * If not, go with partial explicit specialization.
6074 */ 6185 */
6075 ti->semanticTiargs(sc); 6186 ti->semanticTiargs(sc);
6161 { AggregateDeclaration *ad; 6272 { AggregateDeclaration *ad;
6162 6273
6163 if (t1->ty == Tstruct) 6274 if (t1->ty == Tstruct)
6164 { 6275 {
6165 ad = ((TypeStruct *)t1)->sym; 6276 ad = ((TypeStruct *)t1)->sym;
6277 #if DMDV2
6278 // First look for constructor
6279 if (ad->ctor && arguments && arguments->dim)
6280 {
6281 // Create variable that will get constructed
6282 Identifier *idtmp = Lexer::uniqueId("__ctmp");
6283 VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, NULL);
6284 Expression *av = new DeclarationExp(loc, tmp);
6285 av = new CommaExp(loc, av, new VarExp(loc, tmp));
6286
6287 Expression *e;
6288 CtorDeclaration *cf = ad->ctor->isCtorDeclaration();
6289 if (cf)
6290 e = new DotVarExp(loc, av, cf, 1);
6291 else
6292 { TemplateDeclaration *td = ad->ctor->isTemplateDeclaration();
6293 assert(td);
6294 e = new DotTemplateExp(loc, av, td);
6295 }
6296 e = new CallExp(loc, e, arguments);
6297 #if !STRUCTTHISREF
6298 /* Constructors return a pointer to the instance
6299 */
6300 e = new PtrExp(loc, e);
6301 #endif
6302 e = e->semantic(sc);
6303 return e;
6304 }
6305 #endif
6306 // No constructor, look for overload of opCall
6166 if (search_function(ad, Id::call)) 6307 if (search_function(ad, Id::call))
6167 goto L1; // overload of opCall, therefore it's a call 6308 goto L1; // overload of opCall, therefore it's a call
6168 6309
6169 if (e1->op != TOKtype) 6310 if (e1->op != TOKtype)
6170 error("%s %s does not overload ()", ad->kind(), ad->toChars()); 6311 error("%s %s does not overload ()", ad->kind(), ad->toChars());
6203 { // Do overload resolution 6344 { // Do overload resolution
6204 dve = (DotVarExp *)(e1); 6345 dve = (DotVarExp *)(e1);
6205 6346
6206 f = dve->var->isFuncDeclaration(); 6347 f = dve->var->isFuncDeclaration();
6207 assert(f); 6348 assert(f);
6208 f = f->overloadResolve(loc, arguments, sc->module); 6349 f = f->overloadResolve(loc, NULL, arguments, sc->module);
6209 6350
6210 ad = f->toParent()->isAggregateDeclaration(); 6351 ad = f->toParent()->isAggregateDeclaration();
6211 } 6352 }
6212 else 6353 else
6213 { dte = (DotTemplateExp *)(e1); 6354 { dte = (DotTemplateExp *)(e1);
6304 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) 6445 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
6305 error("multiple constructor calls"); 6446 error("multiple constructor calls");
6306 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 6447 sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
6307 } 6448 }
6308 6449
6309 f = f->overloadResolve(loc, arguments, sc->module); 6450 f = f->overloadResolve(loc, NULL, arguments, sc->module);
6310 checkDeprecated(sc, f); 6451 checkDeprecated(sc, f);
6311 #if DMDV2 6452 #if DMDV2
6312 checkPurity(sc, f); 6453 checkPurity(sc, f);
6313 #endif 6454 #endif
6314 e1 = new DotVarExp(e1->loc, e1, f); 6455 e1 = new DotVarExp(e1->loc, e1, f);
6344 error("multiple constructor calls"); 6485 error("multiple constructor calls");
6345 sc->callSuper |= CSXany_ctor | CSXthis_ctor; 6486 sc->callSuper |= CSXany_ctor | CSXthis_ctor;
6346 } 6487 }
6347 6488
6348 f = cd->ctor; 6489 f = cd->ctor;
6349 f = f->overloadResolve(loc, arguments, sc->module); 6490 f = f->overloadResolve(loc, NULL, arguments, sc->module);
6350 checkDeprecated(sc, f); 6491 checkDeprecated(sc, f);
6351 #if DMDV2 6492 #if DMDV2
6352 checkPurity(sc, f); 6493 checkPurity(sc, f);
6353 #endif 6494 #endif
6354 e1 = new DotVarExp(e1->loc, e1, f); 6495 e1 = new DotVarExp(e1->loc, e1, f);
6438 istemp = 1; 6579 istemp = 1;
6439 goto Lagain; 6580 goto Lagain;
6440 } 6581 }
6441 } 6582 }
6442 6583
6443 f = f->overloadResolve(loc, arguments, sc->module); 6584 f = f->overloadResolve(loc, NULL, arguments, sc->module);
6444 checkDeprecated(sc, f); 6585 checkDeprecated(sc, f);
6445 #if DMDV2 6586 #if DMDV2
6446 checkPurity(sc, f); 6587 checkPurity(sc, f);
6447 #endif 6588 #endif
6448 6589
6521 } 6662 }
6522 6663
6523 #if DMDV2 6664 #if DMDV2
6524 int CallExp::canThrow() 6665 int CallExp::canThrow()
6525 { 6666 {
6667 //printf("CallExp::canThrow() %s\n", toChars());
6526 if (e1->canThrow()) 6668 if (e1->canThrow())
6527 return 1; 6669 return 1;
6528 6670
6529 /* If any of the arguments can throw, then this expression can throw 6671 /* If any of the arguments can throw, then this expression can throw
6530 */ 6672 */
6531 for (size_t i = 0; i < arguments->dim; i++) 6673 for (size_t i = 0; i < arguments->dim; i++)
6532 { Expression *e = (Expression *)arguments->data[i]; 6674 { Expression *e = (Expression *)arguments->data[i];
6533 6675
6534 if (e->canThrow()) 6676 if (e && e->canThrow())
6535 return 1; 6677 return 1;
6536 } 6678 }
6679
6680 if (global.errors && !e1->type)
6681 return 0; // error recovery
6537 6682
6538 /* If calling a function or delegate that is typed as nothrow, 6683 /* If calling a function or delegate that is typed as nothrow,
6539 * then this expression cannot throw. 6684 * then this expression cannot throw.
6540 * Note that pure functions can throw. 6685 * Note that pure functions can throw.
6541 */ 6686 */
6550 #endif 6695 #endif
6551 6696
6552 #if DMDV2 6697 #if DMDV2
6553 int CallExp::isLvalue() 6698 int CallExp::isLvalue()
6554 { 6699 {
6555 if (type->toBasetype()->ty == Tstruct) 6700 // if (type->toBasetype()->ty == Tstruct)
6556 return 1; 6701 // return 1;
6557 Type *tb = e1->type->toBasetype(); 6702 Type *tb = e1->type->toBasetype();
6558 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) 6703 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
6559 return 1; // function returns a reference 6704 return 1; // function returns a reference
6560 return 0; 6705 return 0;
6561 } 6706 }
6562 #endif 6707 #endif
6563 6708
6564 Expression *CallExp::toLvalue(Scope *sc, Expression *e) 6709 Expression *CallExp::toLvalue(Scope *sc, Expression *e)
6565 { 6710 {
6711 #if 1
6566 if (type->toBasetype()->ty == Tstruct) 6712 if (type->toBasetype()->ty == Tstruct)
6567 return this; 6713 return this;
6568 else 6714 else
6715 #endif
6569 return Expression::toLvalue(sc, e); 6716 return Expression::toLvalue(sc, e);
6717 }
6718
6719 Expression *CallExp::modifiableLvalue(Scope *sc, Expression *e)
6720 {
6721 #if 1
6722 return Expression::modifiableLvalue(sc, e);
6723 #else
6724 /* Although function return values being usable as "ref" parameters is
6725 * unsound, disabling it breaks existing code.
6726 * Bugzilla 3167
6727 */
6728 error("cannot assign to function call");
6729 return toLvalue(sc, e);
6730 #endif
6570 } 6731 }
6571 6732
6572 void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 6733 void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
6573 { int i; 6734 { int i;
6574 6735
6598 UnaExp::semantic(sc); 6759 UnaExp::semantic(sc);
6599 e1 = e1->toLvalue(sc, NULL); 6760 e1 = e1->toLvalue(sc, NULL);
6600 if (!e1->type) 6761 if (!e1->type)
6601 { 6762 {
6602 error("cannot take address of %s", e1->toChars()); 6763 error("cannot take address of %s", e1->toChars());
6603 type = Type::tint32; 6764 return new ErrorExp();
6604 return this; 6765 }
6766 if (!e1->type->deco)
6767 {
6768 /* No deco means semantic() was not run on the type.
6769 * We have to run semantic() on the symbol to get the right type:
6770 * auto x = &bar;
6771 * pure: int bar() { return 1;}
6772 * otherwise the 'pure' is missing from the type assigned to x.
6773 */
6774
6775 error("forward reference to %s", e1->toChars());
6776 return new ErrorExp();
6605 } 6777 }
6606 type = e1->type->pointerTo(); 6778 type = e1->type->pointerTo();
6607 6779
6608 // See if this should really be a delegate 6780 // See if this should really be a delegate
6609 if (e1->op == TOKdotvar) 6781 if (e1->op == TOKdotvar)
6651 /************************************************************/ 6823 /************************************************************/
6652 6824
6653 PtrExp::PtrExp(Loc loc, Expression *e) 6825 PtrExp::PtrExp(Loc loc, Expression *e)
6654 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 6826 : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
6655 { 6827 {
6656 if (e->type) 6828 // if (e->type)
6657 type = ((TypePointer *)e->type)->next; 6829 // type = ((TypePointer *)e->type)->next;
6658 } 6830 }
6659 6831
6660 PtrExp::PtrExp(Loc loc, Expression *e, Type *t) 6832 PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
6661 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 6833 : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
6662 { 6834 {
6663 type = t; 6835 type = t;
6664 } 6836 }
6665 6837
6666 Expression *PtrExp::semantic(Scope *sc) 6838 Expression *PtrExp::semantic(Scope *sc)
6667 { Type *tb; 6839 {
6668
6669 #if LOGSEMANTIC 6840 #if LOGSEMANTIC
6670 printf("PtrExp::semantic('%s')\n", toChars()); 6841 printf("PtrExp::semantic('%s')\n", toChars());
6671 #endif 6842 #endif
6672 UnaExp::semantic(sc); 6843 if (!type)
6673 e1 = resolveProperties(sc, e1); 6844 {
6674 if (type) 6845 UnaExp::semantic(sc);
6675 return this; 6846 e1 = resolveProperties(sc, e1);
6676 if (!e1->type) 6847 if (!e1->type)
6677 printf("PtrExp::semantic('%s')\n", toChars()); 6848 printf("PtrExp::semantic('%s')\n", toChars());
6678 tb = e1->type->toBasetype(); 6849 Type *tb = e1->type->toBasetype();
6679 switch (tb->ty) 6850 switch (tb->ty)
6680 { 6851 {
6681 case Tpointer: 6852 case Tpointer:
6682 type = tb->next; 6853 type = tb->next;
6683 if (type->isbit()) 6854 break;
6684 { Expression *e; 6855
6685 6856 case Tsarray:
6686 // Rewrite *p as p[0] 6857 case Tarray:
6687 e = new IndexExp(loc, e1, new IntegerExp(0)); 6858 type = tb->next;
6688 return e->semantic(sc); 6859 e1 = e1->castTo(sc, type->pointerTo());
6689 } 6860 break;
6690 break; 6861
6691 6862 default:
6692 case Tsarray: 6863 error("can only * a pointer, not a '%s'", e1->type->toChars());
6693 case Tarray: 6864 return new ErrorExp();
6694 type = tb->next; 6865 }
6695 e1 = e1->castTo(sc, type->pointerTo()); 6866 rvalue();
6696 break; 6867 }
6697
6698 default:
6699 error("can only * a pointer, not a '%s'", e1->type->toChars());
6700 type = Type::tint32;
6701 break;
6702 }
6703 rvalue();
6704 return this; 6868 return this;
6705 } 6869 }
6706 6870
6707 #if DMDV2 6871 #if DMDV2
6708 int PtrExp::isLvalue() 6872 int PtrExp::isLvalue()
6764 e = op_overload(sc); 6928 e = op_overload(sc);
6765 if (e) 6929 if (e)
6766 return e; 6930 return e;
6767 6931
6768 e1->checkNoBool(); 6932 e1->checkNoBool();
6769 if (e1->op != TOKslice) 6933 if (!e1->isArrayOperand())
6770 e1->checkArithmetic(); 6934 e1->checkArithmetic();
6771 type = e1->type; 6935 type = e1->type;
6772 } 6936 }
6773 return this; 6937 return this;
6774 } 6938 }
6814 e = op_overload(sc); 6978 e = op_overload(sc);
6815 if (e) 6979 if (e)
6816 return e; 6980 return e;
6817 6981
6818 e1->checkNoBool(); 6982 e1->checkNoBool();
6819 if (e1->op != TOKslice) 6983 if (!e1->isArrayOperand())
6820 e1 = e1->checkIntegral(); 6984 e1 = e1->checkIntegral();
6821 type = e1->type; 6985 type = e1->type;
6822 } 6986 }
6823 return this; 6987 return this;
6824 } 6988 }
7010 if (e) 7174 if (e)
7011 { 7175 {
7012 return e->implicitCastTo(sc, to); 7176 return e->implicitCastTo(sc, to);
7013 } 7177 }
7014 7178
7179 if (e1->op == TOKtemplate)
7180 {
7181 error("cannot cast template %s to type %s", e1->toChars(), to->toChars());
7182 return new ErrorExp();
7183 }
7184
7185 Type *t1b = e1->type->toBasetype();
7015 Type *tob = to->toBasetype(); 7186 Type *tob = to->toBasetype();
7016 if (tob->ty == Tstruct && 7187 if (tob->ty == Tstruct &&
7017 !tob->equals(e1->type->toBasetype()) && 7188 !tob->equals(t1b) &&
7018 ((TypeStruct *)to)->sym->search(0, Id::call, 0) 7189 ((TypeStruct *)to)->sym->search(0, Id::call, 0)
7019 ) 7190 )
7020 { 7191 {
7021 /* Look to replace: 7192 /* Look to replace:
7022 * cast(S)t 7193 * cast(S)t
7028 e = new TypeExp(loc, to); 7199 e = new TypeExp(loc, to);
7029 e = new DotIdExp(loc, e, Id::call); 7200 e = new DotIdExp(loc, e, Id::call);
7030 e = new CallExp(loc, e, e1); 7201 e = new CallExp(loc, e, e1);
7031 e = e->semantic(sc); 7202 e = e->semantic(sc);
7032 return e; 7203 return e;
7204 }
7205
7206 // Struct casts are possible only when the sizes match
7207 if (tob->ty == Tstruct || t1b->ty == Tstruct)
7208 {
7209 size_t fromsize = t1b->size(loc);
7210 size_t tosize = tob->size(loc);
7211 if (fromsize != tosize)
7212 {
7213 error("cannot cast from %s to %s", e1->type->toChars(), to->toChars());
7214 return new ErrorExp();
7215 }
7033 } 7216 }
7034 } 7217 }
7035 e = e1->castTo(sc, to); 7218 e = e1->castTo(sc, to);
7036 return e; 7219 return e;
7037 } 7220 }
7735 buf->writestring((op == TOKplusplus) ? (char *)"++" : (char *)"--"); 7918 buf->writestring((op == TOKplusplus) ? (char *)"++" : (char *)"--");
7736 } 7919 }
7737 7920
7738 /************************************************************/ 7921 /************************************************************/
7739 7922
7740 /* Can be TOKconstruct too */ 7923 /* op can be TOKassign, TOKconstruct, or TOKblit */
7741 7924
7742 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2) 7925 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2)
7743 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2) 7926 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2)
7744 { 7927 {
7745 ismemset = 0; 7928 ismemset = 0;
7746 } 7929 }
7747 7930
7748 Expression *AssignExp::semantic(Scope *sc) 7931 Expression *AssignExp::semantic(Scope *sc)
7749 { Type *t1; 7932 {
7750 Expression *e1old = e1; 7933 Expression *e1old = e1;
7751 7934
7752 #if LOGSEMANTIC 7935 #if LOGSEMANTIC
7753 printf("AssignExp::semantic('%s')\n", toChars()); 7936 printf("AssignExp::semantic('%s')\n", toChars());
7754 #endif 7937 #endif
7755 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); 7938 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op));
7939 //printf("e2->op = %d, '%s'\n", e2->op, Token::toChars(e2->op));
7940
7941 if (type)
7942 return this;
7943
7944 if (e2->op == TOKcomma)
7945 { /* Rewrite to get rid of the comma from rvalue
7946 */
7947 AssignExp *ea = new AssignExp(loc, e1, ((CommaExp *)e2)->e2);
7948 ea->op = op;
7949 Expression *e = new CommaExp(loc, ((CommaExp *)e2)->e1, ea);
7950 return e->semantic(sc);
7951 }
7756 7952
7757 /* Look for operator overloading of a[i]=value. 7953 /* Look for operator overloading of a[i]=value.
7758 * Do it before semantic() otherwise the a[i] will have been 7954 * Do it before semantic() otherwise the a[i] will have been
7759 * converted to a.opIndex() already. 7955 * converted to a.opIndex() already.
7760 */ 7956 */
7761 if (e1->op == TOKarray) 7957 if (e1->op == TOKarray)
7762 { Type *t1; 7958 {
7763 ArrayExp *ae = (ArrayExp *)e1; 7959 ArrayExp *ae = (ArrayExp *)e1;
7764 AggregateDeclaration *ad; 7960 AggregateDeclaration *ad;
7765 Identifier *id = Id::index; 7961 Identifier *id = Id::index;
7766 7962
7767 ae->e1 = ae->e1->semantic(sc); 7963 ae->e1 = ae->e1->semantic(sc);
7768 t1 = ae->e1->type->toBasetype(); 7964 Type *t1 = ae->e1->type->toBasetype();
7769 if (t1->ty == Tstruct) 7965 if (t1->ty == Tstruct)
7770 { 7966 {
7771 ad = ((TypeStruct *)t1)->sym; 7967 ad = ((TypeStruct *)t1)->sym;
7772 goto L1; 7968 goto L1;
7773 } 7969 }
7878 e = e->semantic(sc); 8074 e = e->semantic(sc);
7879 return e; 8075 return e;
7880 } 8076 }
7881 } 8077 }
7882 8078
7883 t1 = e1->type->toBasetype(); 8079 // Determine if this is an initialization of a reference
8080 int refinit = 0;
8081 if (op == TOKconstruct && e1->op == TOKvar)
8082 { VarExp *ve = (VarExp *)e1;
8083 VarDeclaration *v = ve->var->isVarDeclaration();
8084 if (v->storage_class & (STCout | STCref))
8085 refinit = 1;
8086 }
8087
8088 Type *t1 = e1->type->toBasetype();
7884 8089
7885 if (t1->ty == Tfunction) 8090 if (t1->ty == Tfunction)
7886 { // Rewrite f=value to f(value) 8091 { // Rewrite f=value to f(value)
7887 Expression *e; 8092 Expression *e = new CallExp(loc, e1, e2);
7888
7889 e = new CallExp(loc, e1, e2);
7890 e = e->semantic(sc); 8093 e = e->semantic(sc);
7891 return e; 8094 return e;
7892 } 8095 }
7893 8096
7894 /* If it is an assignment from a 'foreign' type, 8097 /* If it is an assignment from a 'foreign' type,
7916 else if (e1->op == TOKslice) 8119 else if (e1->op == TOKslice)
7917 ; 8120 ;
7918 else 8121 else
7919 { // Try to do a decent error message with the expression 8122 { // Try to do a decent error message with the expression
7920 // before it got constant folded 8123 // before it got constant folded
7921 e1 = e1->modifiableLvalue(sc, e1old); 8124 if (op != TOKconstruct)
8125 e1 = e1->modifiableLvalue(sc, e1old);
7922 } 8126 }
7923 8127
7924 if (e1->op == TOKslice && 8128 if (e1->op == TOKslice &&
7925 t1->nextOf() && 8129 t1->nextOf() &&
7926 e2->implicitConvTo(t1->nextOf()) 8130 e2->implicitConvTo(t1->nextOf())
7928 ) 8132 )
7929 { // memset 8133 { // memset
7930 ismemset = 1; // make it easy for back end to tell what this is 8134 ismemset = 1; // make it easy for back end to tell what this is
7931 e2 = e2->implicitCastTo(sc, t1->next); 8135 e2 = e2->implicitCastTo(sc, t1->next);
7932 } 8136 }
7933 else if (t1->ty == Tsarray) 8137 else if (t1->ty == Tsarray && !refinit)
7934 { 8138 {
7935 error("cannot assign to static array %s", e1->toChars()); 8139 error("cannot assign to static array %s", e1->toChars());
7936 } 8140 }
7937 else 8141 else
7938 { 8142 {
8059 { 8263 {
8060 type = e1->type; 8264 type = e1->type;
8061 typeCombine(sc); 8265 typeCombine(sc);
8062 e1->checkArithmetic(); 8266 e1->checkArithmetic();
8063 e2->checkArithmetic(); 8267 e2->checkArithmetic();
8268 checkComplexAddAssign();
8064 if (type->isreal() || type->isimaginary()) 8269 if (type->isreal() || type->isimaginary())
8065 { 8270 {
8066 assert(global.errors || e2->type->isfloating()); 8271 assert(global.errors || e2->type->isfloating());
8067 e2 = e2->castTo(sc, e1->type); 8272 e2 = e2->castTo(sc, e1->type);
8068 } 8273 }
8109 e = scaleFactor(sc); 8314 e = scaleFactor(sc);
8110 else 8315 else
8111 { 8316 {
8112 e1 = e1->checkArithmetic(); 8317 e1 = e1->checkArithmetic();
8113 e2 = e2->checkArithmetic(); 8318 e2 = e2->checkArithmetic();
8319 checkComplexAddAssign();
8114 type = e1->type; 8320 type = e1->type;
8115 typeCombine(sc); 8321 typeCombine(sc);
8116 if (type->isreal() || type->isimaginary()) 8322 if (type->isreal() || type->isimaginary())
8117 { 8323 {
8118 assert(e2->type->isfloating()); 8324 assert(e2->type->isfloating());
8213 e1->checkNoBool(); 8419 e1->checkNoBool();
8214 type = e1->type; 8420 type = e1->type;
8215 typeCombine(sc); 8421 typeCombine(sc);
8216 e1->checkArithmetic(); 8422 e1->checkArithmetic();
8217 e2->checkArithmetic(); 8423 e2->checkArithmetic();
8424 checkComplexMulAssign();
8218 if (e2->type->isfloating()) 8425 if (e2->type->isfloating())
8219 { Type *t1; 8426 { Type *t1;
8220 Type *t2; 8427 Type *t2;
8221 8428
8222 t1 = e1->type; 8429 t1 = e1->type;
8279 e1->checkNoBool(); 8486 e1->checkNoBool();
8280 type = e1->type; 8487 type = e1->type;
8281 typeCombine(sc); 8488 typeCombine(sc);
8282 e1->checkArithmetic(); 8489 e1->checkArithmetic();
8283 e2->checkArithmetic(); 8490 e2->checkArithmetic();
8491 checkComplexMulAssign();
8284 if (e2->type->isimaginary()) 8492 if (e2->type->isimaginary())
8285 { Type *t1; 8493 { Type *t1;
8286 Type *t2; 8494 Type *t2;
8287 8495
8288 t1 = e1->type; 8496 t1 = e1->type;
8326 { 8534 {
8327 } 8535 }
8328 8536
8329 Expression *ModAssignExp::semantic(Scope *sc) 8537 Expression *ModAssignExp::semantic(Scope *sc)
8330 { 8538 {
8539 BinExp::semantic(sc);
8540 checkComplexMulAssign();
8331 return commonSemanticAssign(sc); 8541 return commonSemanticAssign(sc);
8332 } 8542 }
8333 8543
8334 /************************************************************/ 8544 /************************************************************/
8335 8545
8734 e = op_overload(sc); 8944 e = op_overload(sc);
8735 if (e) 8945 if (e)
8736 return e; 8946 return e;
8737 8947
8738 typeCombine(sc); 8948 typeCombine(sc);
8739 if (e1->op != TOKslice && e2->op != TOKslice) 8949 if (!e1->isArrayOperand())
8740 { e1->checkArithmetic(); 8950 e1->checkArithmetic();
8951 if (!e2->isArrayOperand())
8741 e2->checkArithmetic(); 8952 e2->checkArithmetic();
8742 }
8743 if (type->isfloating()) 8953 if (type->isfloating())
8744 { Type *t1 = e1->type; 8954 { Type *t1 = e1->type;
8745 Type *t2 = e2->type; 8955 Type *t2 = e2->type;
8746 8956
8747 if (t1->isreal()) 8957 if (t1->isreal())
8800 e = op_overload(sc); 9010 e = op_overload(sc);
8801 if (e) 9011 if (e)
8802 return e; 9012 return e;
8803 9013
8804 typeCombine(sc); 9014 typeCombine(sc);
8805 if (e1->op != TOKslice && e2->op != TOKslice) 9015 if (!e1->isArrayOperand())
8806 { e1->checkArithmetic(); 9016 e1->checkArithmetic();
9017 if (!e2->isArrayOperand())
8807 e2->checkArithmetic(); 9018 e2->checkArithmetic();
8808 }
8809 if (type->isfloating()) 9019 if (type->isfloating())
8810 { Type *t1 = e1->type; 9020 { Type *t1 = e1->type;
8811 Type *t2 = e2->type; 9021 Type *t2 = e2->type;
8812 9022
8813 if (t1->isreal()) 9023 if (t1->isreal())
8867 e = op_overload(sc); 9077 e = op_overload(sc);
8868 if (e) 9078 if (e)
8869 return e; 9079 return e;
8870 9080
8871 typeCombine(sc); 9081 typeCombine(sc);
8872 if (e1->op != TOKslice && e2->op != TOKslice) 9082 if (!e1->isArrayOperand())
8873 { e1->checkArithmetic(); 9083 e1->checkArithmetic();
9084 if (!e2->isArrayOperand())
8874 e2->checkArithmetic(); 9085 e2->checkArithmetic();
8875 }
8876 if (type->isfloating()) 9086 if (type->isfloating())
8877 { type = e1->type; 9087 { type = e1->type;
8878 if (e2->type->iscomplex()) 9088 if (e2->type->iscomplex())
8879 { error("cannot perform modulo complex arithmetic"); 9089 { error("cannot perform modulo complex arithmetic");
8880 return new IntegerExp(0); 9090 return new IntegerExp(0);
8981 e = this; 9191 e = this;
8982 } 9192 }
8983 else 9193 else
8984 { 9194 {
8985 typeCombine(sc); 9195 typeCombine(sc);
8986 if (e1->op != TOKslice && e2->op != TOKslice) 9196 if (!e1->isArrayOperand())
8987 { e1->checkIntegral(); 9197 e1->checkIntegral();
9198 if (!e2->isArrayOperand())
8988 e2->checkIntegral(); 9199 e2->checkIntegral();
8989 }
8990 } 9200 }
8991 } 9201 }
8992 return this; 9202 return this;
8993 } 9203 }
8994 9204
9014 e = this; 9224 e = this;
9015 } 9225 }
9016 else 9226 else
9017 { 9227 {
9018 typeCombine(sc); 9228 typeCombine(sc);
9019 if (e1->op != TOKslice && e2->op != TOKslice) 9229 if (!e1->isArrayOperand())
9020 { e1->checkIntegral(); 9230 e1->checkIntegral();
9231 if (!e2->isArrayOperand())
9021 e2->checkIntegral(); 9232 e2->checkIntegral();
9022 }
9023 } 9233 }
9024 } 9234 }
9025 return this; 9235 return this;
9026 } 9236 }
9027 9237
9047 e = this; 9257 e = this;
9048 } 9258 }
9049 else 9259 else
9050 { 9260 {
9051 typeCombine(sc); 9261 typeCombine(sc);
9052 if (e1->op != TOKslice && e2->op != TOKslice) 9262 if (!e1->isArrayOperand())
9053 { e1->checkIntegral(); 9263 e1->checkIntegral();
9264 if (!e2->isArrayOperand())
9054 e2->checkIntegral(); 9265 e2->checkIntegral();
9055 }
9056 } 9266 }
9057 } 9267 }
9058 return this; 9268 return this;
9059 } 9269 }
9060 9270
9252 { 9462 {
9253 } 9463 }
9254 9464
9255 Expression *CmpExp::semantic(Scope *sc) 9465 Expression *CmpExp::semantic(Scope *sc)
9256 { Expression *e; 9466 { Expression *e;
9257 Type *t1;
9258 Type *t2;
9259 9467
9260 #if LOGSEMANTIC 9468 #if LOGSEMANTIC
9261 printf("CmpExp::semantic('%s')\n", toChars()); 9469 printf("CmpExp::semantic('%s')\n", toChars());
9262 #endif 9470 #endif
9263 if (type) 9471 if (type)
9264 return this; 9472 return this;
9265 9473
9266 BinExp::semanticp(sc); 9474 BinExp::semanticp(sc);
9267 9475
9268 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || 9476 Type *t1 = e1->type->toBasetype();
9269 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) 9477 Type *t2 = e2->type->toBasetype();
9478 if (t1->ty == Tclass && e2->op == TOKnull ||
9479 t2->ty == Tclass && e1->op == TOKnull)
9270 { 9480 {
9271 error("do not use null when comparing class types"); 9481 error("do not use null when comparing class types");
9272 } 9482 }
9273 9483
9274 e = op_overload(sc); 9484 e = op_overload(sc);
9282 else 9492 else
9283 { e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); 9493 { e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32));
9284 e = e->semantic(sc); 9494 e = e->semantic(sc);
9285 } 9495 }
9286 return e; 9496 return e;
9497 }
9498
9499 /* Disallow comparing T[]==T and T==T[]
9500 */
9501 if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) ||
9502 e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf()))
9503 {
9504 incompatibleTypes();
9505 return new ErrorExp();
9287 } 9506 }
9288 9507
9289 typeCombine(sc); 9508 typeCombine(sc);
9290 type = Type::tboolean; 9509 type = Type::tboolean;
9291 9510
9335 assert(op == TOKequal || op == TOKnotequal); 9554 assert(op == TOKequal || op == TOKnotequal);
9336 } 9555 }
9337 9556
9338 Expression *EqualExp::semantic(Scope *sc) 9557 Expression *EqualExp::semantic(Scope *sc)
9339 { Expression *e; 9558 { Expression *e;
9340 Type *t1;
9341 Type *t2;
9342 9559
9343 //printf("EqualExp::semantic('%s')\n", toChars()); 9560 //printf("EqualExp::semantic('%s')\n", toChars());
9344 if (type) 9561 if (type)
9345 return this; 9562 return this;
9346 9563
9365 return e; 9582 return e;
9366 } 9583 }
9367 } 9584 }
9368 } 9585 }
9369 9586
9370 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || 9587 Type *t1 = e1->type->toBasetype();
9371 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) 9588 Type *t2 = e2->type->toBasetype();
9589 if (t1->ty == Tclass && e2->op == TOKnull ||
9590 t2->ty == Tclass && e1->op == TOKnull)
9372 { 9591 {
9373 error("use '%s' instead of '%s' when comparing with null", 9592 error("use '%s' instead of '%s' when comparing with null",
9374 Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity), 9593 Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity),
9375 Token::toChars(op)); 9594 Token::toChars(op));
9376 } 9595 }
9385 e = new NotExp(e->loc, e); 9604 e = new NotExp(e->loc, e);
9386 e = e->semantic(sc); 9605 e = e->semantic(sc);
9387 } 9606 }
9388 return e; 9607 return e;
9389 } 9608 }
9609 }
9610
9611 /* Disallow comparing T[]==T and T==T[]
9612 */
9613 if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) ||
9614 e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf()))
9615 {
9616 incompatibleTypes();
9617 return new ErrorExp();
9390 } 9618 }
9391 9619
9392 e = typeCombine(sc); 9620 e = typeCombine(sc);
9393 type = Type::tboolean; 9621 type = Type::tboolean;
9394 9622