Mercurial > projects > ldc
comparison dmd/mtype.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 | 04177061f98d |
children | 05c235309d6f |
comparison
equal
deleted
inserted
replaced
1498:899a928ac905 | 1499:df11cdec45a2 |
---|---|
3407 if (!sm) | 3407 if (!sm) |
3408 { | 3408 { |
3409 v = s->isVarDeclaration(); | 3409 v = s->isVarDeclaration(); |
3410 if (v && id == Id::length) | 3410 if (v && id == Id::length) |
3411 { | 3411 { |
3412 if (v->isConst() && v->getExpInitializer()) | 3412 if (v->isSameAsInitializer() && v->getExpInitializer()) |
3413 { e = v->getExpInitializer()->exp; | 3413 { e = v->getExpInitializer()->exp; |
3414 } | 3414 } |
3415 else | 3415 else |
3416 e = new VarExp(loc, v); | 3416 e = new VarExp(loc, v); |
3417 t = e->type; | 3417 t = e->type; |
3454 | 3454 |
3455 v = s->isVarDeclaration(); | 3455 v = s->isVarDeclaration(); |
3456 if (v) | 3456 if (v) |
3457 { | 3457 { |
3458 // It's not a type, it's an expression | 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 ExpInitializer *ei = v->getExpInitializer(); | 3461 ExpInitializer *ei = v->getExpInitializer(); |
3462 assert(ei); | 3462 assert(ei); |
3463 *pe = ei->exp->copy(); // make copy so we can change loc | 3463 *pe = ei->exp->copy(); // make copy so we can change loc |
3464 (*pe)->loc = loc; | 3464 (*pe)->loc = loc; |
4518 if (!s->isFuncDeclaration()) // because of overloading | 4518 if (!s->isFuncDeclaration()) // because of overloading |
4519 s->checkDeprecated(e->loc, sc); | 4519 s->checkDeprecated(e->loc, sc); |
4520 s = s->toAlias(); | 4520 s = s->toAlias(); |
4521 | 4521 |
4522 v = s->isVarDeclaration(); | 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 { ExpInitializer *ei = v->getExpInitializer(); | 4524 { ExpInitializer *ei = v->getExpInitializer(); |
4525 | 4525 |
4526 if (ei) | 4526 if (ei) |
4527 { e = ei->exp->copy(); // need to copy it if it's a StringExp | 4527 { e = ei->exp->copy(); // need to copy it if it's a StringExp |
4528 e = e->semantic(sc); | 4528 e = e->semantic(sc); |
4930 } | 4930 } |
4931 if (!s->isFuncDeclaration()) // because of overloading | 4931 if (!s->isFuncDeclaration()) // because of overloading |
4932 s->checkDeprecated(e->loc, sc); | 4932 s->checkDeprecated(e->loc, sc); |
4933 s = s->toAlias(); | 4933 s = s->toAlias(); |
4934 v = s->isVarDeclaration(); | 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 { ExpInitializer *ei = v->getExpInitializer(); | 4936 { ExpInitializer *ei = v->getExpInitializer(); |
4937 | 4937 |
4938 if (ei) | 4938 if (ei) |
4939 { e = ei->exp->copy(); // need to copy it if it's a StringExp | 4939 { e = ei->exp->copy(); // need to copy it if it's a StringExp |
4940 e = e->semantic(sc); | 4940 e = e->semantic(sc); |