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);