# HG changeset patch # User Tomas Lindquist Olsen # Date 1228176442 -3600 # Node ID 446263a8a30dfa486754a6e0d9cdc7df6e0009da # Parent e8f8cafcaa620551816dfa159b4a279047656159 Fixed taking address of global static array element as constant expression. diff -r e8f8cafcaa62 -r 446263a8a30d gen/toir.cpp --- a/gen/toir.cpp Mon Dec 01 20:26:32 2008 +0100 +++ b/gen/toir.cpp Tue Dec 02 01:07:22 2008 +0100 @@ -896,32 +896,71 @@ LLConstant* AddrExp::toConstElem(IRState* p) { - assert(e1->op == TOKvar); - VarExp* vexp = (VarExp*)e1; - - if (vexp->var->needThis()) + // FIXME: this should probably be generalized more so we don't + // need to have a case for each thing we can take the address of + + // address of global variable + if (e1->op == TOKvar) { - error("need 'this' to access %s", vexp->var->toChars()); - fatal(); + VarExp* vexp = (VarExp*)e1; + + // make sure 'this' isn't needed + if (vexp->var->needThis()) + { + error("need 'this' to access %s", vexp->var->toChars()); + fatal(); + } + + // global variable + if (VarDeclaration* vd = vexp->var->isVarDeclaration()) + { + LLConstant* llc = llvm::dyn_cast(vd->ir.getIrValue()); + assert(llc); + return llc; + } + // static function + else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) + { + IrFunction* irfunc = fd->ir.irFunc; + assert(irfunc); + return irfunc->func; + } + // something else + else + { + // fail + goto Lerr; + } } - - // global variable - if (VarDeclaration* vd = vexp->var->isVarDeclaration()) + // address of indexExp + else if (e1->op == TOKindex) { - LLConstant* llc = llvm::dyn_cast(vd->ir.getIrValue()); - assert(llc); - return llc; - } - // static function - else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) - { - IrFunction* irfunc = fd->ir.irFunc; - assert(irfunc); - return irfunc->func; + IndexExp* iexp = (IndexExp*)e1; + + // indexee must be global static array var + assert(iexp->e1->op == TOKvar); + VarExp* vexp = (VarExp*)iexp->e1; + VarDeclaration* vd = vexp->var->isVarDeclaration(); + assert(vd); + assert(vd->type->toBasetype()->ty == Tsarray); + assert(vd->ir.irGlobal); + + // get index + LLConstant* index = iexp->e2->toConstElem(p); + assert(index->getType() == DtoSize_t()); + + // gep + LLConstant* idxs[2] = { DtoConstSize_t(0), index }; + LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(isaConstant(vd->ir.irGlobal->value), idxs, 2); + + // bitcast to requested type + assert(type->toBasetype()->ty == Tpointer); + return DtoBitCast(gep, DtoType(type)); } // not yet supported else { + Lerr: error("constant expression '%s' not yet implemented", toChars()); fatal(); } diff -r e8f8cafcaa62 -r 446263a8a30d tests/mini/const2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/const2.d Tue Dec 02 01:07:22 2008 +0100 @@ -0,0 +1,7 @@ +int[10] test; +int* t = &test[3]; + +void main() +{ + assert(t is &test[3]); +}