Mercurial > projects > ldc
changeset 1128:83ef1e7cde70
Return null from a static class to interface cast if the class reference was
null. Fixes #237.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Fri, 20 Mar 2009 15:50:01 +0100 |
parents | 3e98925bcc39 |
children | 8403fec8c34c |
files | gen/classes.cpp |
diffstat | 1 files changed, 10 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/classes.cpp Fri Mar 20 15:47:42 2009 +0100 +++ b/gen/classes.cpp Fri Mar 20 15:50:01 2009 +0100 @@ -1067,13 +1067,21 @@ IrInterface* iri = iriter->second; // offset pointer LLValue* v = val->getRVal(); + LLValue* orig = v; v = DtoGEPi(v, 0, iri->index); + const LLType* ifType = DtoType(_to); if (Logger::enabled()) { Logger::cout() << "V = " << *v << std::endl; - Logger::cout() << "T = " << *DtoType(_to) << std::endl; + Logger::cout() << "T = " << *ifType << std::endl; } - v = DtoBitCast(v, DtoType(_to)); + v = DtoBitCast(v, ifType); + // Check whether the original value was null, and return null if so. + // Sure we could have jumped over the code above in this case, but + // it's just a GEP and (maybe) a pointer-to-pointer BitCast, so it + // should be pretty cheap and perfectly safe even if the original was null. + LLValue* isNull = gIR->ir->CreateICmpEQ(orig, LLConstant::getNullValue(orig->getType()), ".nullcheck"); + v = gIR->ir->CreateSelect(isNull, LLConstant::getNullValue(ifType), v, ".interface"); // return r-value return new DImValue(_to, v); }