Mercurial > projects > ldc
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; |