Changeset 1499:df11cdec45a2
- Timestamp:
- 06/14/09 13:49:58
(3 years ago)
- Author:
- Christian Kamm <kamm incasoftware de>
- branch:
- default
- Message:
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.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r1482 |
r1499 |
|
| 1214 | 1214 | } |
|---|
| 1215 | 1215 | |
|---|
| | 1216 | int VarDeclaration::isSameAsInitializer() |
|---|
| | 1217 | { |
|---|
| | 1218 | if (init && init->isExpInitializer() && |
|---|
| | 1219 | init->isExpInitializer()->exp->op == TOKstructliteral) |
|---|
| | 1220 | return 0; |
|---|
| | 1221 | return isConst(); |
|---|
| | 1222 | } |
|---|
| | 1223 | |
|---|
| 1216 | 1224 | /****************************************** |
|---|
| 1217 | 1225 | * If a variable has an auto destructor call, return call for it. |
|---|
| r1482 |
r1499 |
|
| 136 | 136 | int isDeprecated() { return storage_class & STCdeprecated; } |
|---|
| 137 | 137 | int isOverride() { return storage_class & STCoverride; } |
|---|
| | 138 | |
|---|
| | 139 | virtual int isSameAsInitializer() { return isConst(); }; |
|---|
| 138 | 140 | |
|---|
| 139 | 141 | int isIn() { return storage_class & STCin; } |
|---|
| … | … | |
| 283 | 285 | void checkNestedReference(Scope *sc, Loc loc); |
|---|
| 284 | 286 | Dsymbol *toAlias(); |
|---|
| | 287 | |
|---|
| | 288 | virtual int isSameAsInitializer(); |
|---|
| 285 | 289 | |
|---|
| 286 | 290 | #if IN_DMD |
|---|
| r1372 |
r1499 |
|
| 2114 | 2114 | } |
|---|
| 2115 | 2115 | } |
|---|
| 2116 | | if (v->isConst() && type->toBasetype()->ty != Tsarray) |
|---|
| | 2116 | if (v->isSameAsInitializer() && type->toBasetype()->ty != Tsarray) |
|---|
| 2117 | 2117 | { |
|---|
| 2118 | 2118 | if (v->init) |
|---|
| … | … | |
| 3243 | 3243 | #endif |
|---|
| 3244 | 3244 | |
|---|
| 3245 | | /* |
|---|
| 3246 | | Removed in LDC. See declaration. |
|---|
| 3247 | 3245 | Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) |
|---|
| 3248 | 3246 | { |
|---|
| 3249 | 3247 | return this; |
|---|
| 3250 | 3248 | } |
|---|
| 3251 | | */ |
|---|
| 3252 | 3249 | |
|---|
| 3253 | 3250 | |
|---|
| … | … | |
| 3950 | 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 | 3951 | ExpInitializer *ei = v->init->isExpInitializer(); |
|---|
| … | … | |
| 5356 | 5353 | } |
|---|
| 5357 | 5354 | type = v->type; |
|---|
| 5358 | | if (v->isConst()) |
|---|
| | 5355 | if (v->isSameAsInitializer()) |
|---|
| 5359 | 5356 | { |
|---|
| 5360 | 5357 | if (v->init) |
|---|
| … | … | |
| 5615 | 5612 | |
|---|
| 5616 | 5613 | VarDeclaration *v = var->isVarDeclaration(); |
|---|
| 5617 | | if (v && v->isConst()) |
|---|
| | 5614 | if (v && v->isSameAsInitializer()) |
|---|
| 5618 | 5615 | { ExpInitializer *ei = v->getExpInitializer(); |
|---|
| 5619 | 5616 | if (ei) |
|---|
| r1372 |
r1499 |
|
| 510 | 510 | Expression *optimize(int result); |
|---|
| 511 | 511 | Expression *interpret(InterState *istate); |
|---|
| 512 | | // LDC: struct literals aren't lvalues! Taking their address can lead to |
|---|
| 513 | | // incorrect behavior, see LDC#218, DMD#2682 |
|---|
| 514 | | // Expression *toLvalue(Scope *sc, Expression *e); |
|---|
| | 512 | Expression *toLvalue(Scope *sc, Expression *e); |
|---|
| 515 | 513 | |
|---|
| 516 | 514 | int inlineCost(InlineCostState *ics); |
|---|
| r1393 |
r1499 |
|
| 3410 | 3410 | if (v && id == Id::length) |
|---|
| 3411 | 3411 | { |
|---|
| 3412 | | if (v->isConst() && v->getExpInitializer()) |
|---|
| | 3412 | if (v->isSameAsInitializer() && v->getExpInitializer()) |
|---|
| 3413 | 3413 | { e = v->getExpInitializer()->exp; |
|---|
| 3414 | 3414 | } |
|---|
| … | … | |
| 3457 | 3457 | { |
|---|
| 3458 | 3458 | // It's not a type, it's an expression |
|---|
| 3459 | | if (v->isConst() && v->getExpInitializer()) |
|---|
| | 3459 | if (v->isSameAsInitializer() && v->getExpInitializer()) |
|---|
| 3460 | 3460 | { |
|---|
| 3461 | 3461 | ExpInitializer *ei = v->getExpInitializer(); |
|---|
| … | … | |
| 4521 | 4521 | |
|---|
| 4522 | 4522 | v = s->isVarDeclaration(); |
|---|
| 4523 | | if (v && v->isConst() && v->type->toBasetype()->ty != Tsarray) |
|---|
| | 4523 | if (v && v->isSameAsInitializer() && v->type->toBasetype()->ty != Tsarray) |
|---|
| 4524 | 4524 | { ExpInitializer *ei = v->getExpInitializer(); |
|---|
| 4525 | 4525 | |
|---|
| … | … | |
| 4933 | 4933 | s = s->toAlias(); |
|---|
| 4934 | 4934 | v = s->isVarDeclaration(); |
|---|
| 4935 | | if (v && v->isConst() && v->type->toBasetype()->ty != Tsarray) |
|---|
| | 4935 | if (v && v->isSameAsInitializer() && v->type->toBasetype()->ty != Tsarray) |
|---|
| 4936 | 4936 | { ExpInitializer *ei = v->getExpInitializer(); |
|---|
| 4937 | 4937 | |
|---|
| r1367 |
r1499 |
|
| 195 | 195 | |
|---|
| 196 | 196 | //printf("AddrExp::optimize(result = %d) %s\n", result, toChars()); |
|---|
| 197 | | e1 = e1->optimize(result); |
|---|
| | 197 | // never try to interpret: it could change the semantics by turning |
|---|
| | 198 | // const p = &s; into an something like const p = &(Struct()); |
|---|
| | 199 | e1 = e1->optimize(result & ~WANTinterpret); |
|---|
| 198 | 200 | // Convert &*ex to ex |
|---|
| 199 | 201 | if (e1->op == TOKstar) |
|---|