# HG changeset patch # User Frits van Bommel # Date 1237560601 -3600 # Node ID 83ef1e7cde70832133e1bf0a6b708287caadb5c6 # Parent 3e98925bcc395aabc948559363257973b2b54657 Return null from a static class to interface cast if the class reference was null. Fixes #237. diff -r 3e98925bcc39 -r 83ef1e7cde70 gen/classes.cpp --- 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); }