comparison dmd/expression.c @ 1499:df11cdec45a2

Another shot at fixing the issues with (constant) struct literals and their addresses. See DMD2682, #218, #324. The idea is to separate the notion of const from 'this variable can always be replaced with its initializer' in the frontend. To do that, I introduced Declaration::isSameAsInitializer, which is overridden in VarDeclaration to return false for constants that have a struct literal initializer. So {{{ const S s = S(5); void foo() { auto ps = &s; } // is no longer replaced by void foo() { auto ps = &(S(5)); } }}} To make taking the address of a struct constant with a struct-initializer outside of function scope possible, I made sure that AddrExp::optimize doesn't try to run the argument's optimization with WANTinterpret - that'd again replace the constant with a struct literal temporary.
author Christian Kamm <kamm incasoftware de>
date Sun, 14 Jun 2009 19:49:58 +0200
parents 229e02867307
children 05c235309d6f
comparison
equal deleted inserted replaced
1498:899a928ac905 1499:df11cdec45a2
2111 if (!v->type) 2111 if (!v->type)
2112 { error("forward reference of %s", v->toChars()); 2112 { error("forward reference of %s", v->toChars());
2113 type = Type::terror; 2113 type = Type::terror;
2114 } 2114 }
2115 } 2115 }
2116 if (v->isConst() && type->toBasetype()->ty != Tsarray) 2116 if (v->isSameAsInitializer() && type->toBasetype()->ty != Tsarray)
2117 { 2117 {
2118 if (v->init) 2118 if (v->init)
2119 { 2119 {
2120 if (v->inuse) 2120 if (v->inuse)
2121 { 2121 {
3240 { 3240 {
3241 return 1; 3241 return 1;
3242 } 3242 }
3243 #endif 3243 #endif
3244 3244
3245 /*
3246 Removed in LDC. See declaration.
3247 Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) 3245 Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e)
3248 { 3246 {
3249 return this; 3247 return this;
3250 } 3248 }
3251 */
3252 3249
3253 3250
3254 int StructLiteralExp::checkSideEffect(int flag) 3251 int StructLiteralExp::checkSideEffect(int flag)
3255 { int f = 0; 3252 { int f = 0;
3256 3253
3947 //accessCheck(loc, sc, NULL, var); 3944 //accessCheck(loc, sc, NULL, var);
3948 3945
3949 VarDeclaration *v = var->isVarDeclaration(); 3946 VarDeclaration *v = var->isVarDeclaration();
3950 if (v) 3947 if (v)
3951 { 3948 {
3952 if (v->isConst() && type->toBasetype()->ty != Tsarray && v->init) 3949 if (v->isSameAsInitializer() && type->toBasetype()->ty != Tsarray && v->init)
3953 { 3950 {
3954 ExpInitializer *ei = v->init->isExpInitializer(); 3951 ExpInitializer *ei = v->init->isExpInitializer();
3955 if (ei) 3952 if (ei)
3956 { 3953 {
3957 //ei->exp->implicitCastTo(sc, type)->print(); 3954 //ei->exp->implicitCastTo(sc, type)->print();
5353 error("circular reference to '%s'", v->toChars()); 5350 error("circular reference to '%s'", v->toChars());
5354 type = Type::tint32; 5351 type = Type::tint32;
5355 return this; 5352 return this;
5356 } 5353 }
5357 type = v->type; 5354 type = v->type;
5358 if (v->isConst()) 5355 if (v->isSameAsInitializer())
5359 { 5356 {
5360 if (v->init) 5357 if (v->init)
5361 { 5358 {
5362 ExpInitializer *ei = v->init->isExpInitializer(); 5359 ExpInitializer *ei = v->init->isExpInitializer();
5363 if (ei) 5360 if (ei)
5612 e1 = getRightThis(loc, sc, ad, e1, var); 5609 e1 = getRightThis(loc, sc, ad, e1, var);
5613 if (!sc->noaccesscheck) 5610 if (!sc->noaccesscheck)
5614 accessCheck(loc, sc, e1, var); 5611 accessCheck(loc, sc, e1, var);
5615 5612
5616 VarDeclaration *v = var->isVarDeclaration(); 5613 VarDeclaration *v = var->isVarDeclaration();
5617 if (v && v->isConst()) 5614 if (v && v->isSameAsInitializer())
5618 { ExpInitializer *ei = v->getExpInitializer(); 5615 { ExpInitializer *ei = v->getExpInitializer();
5619 if (ei) 5616 if (ei)
5620 { Expression *e = ei->exp->copy(); 5617 { Expression *e = ei->exp->copy();
5621 e = e->semantic(sc); 5618 e = e->semantic(sc);
5622 return e; 5619 return e;