Mercurial > projects > ldc
comparison gen/classes.cpp @ 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 | 6bb04dbee21f |
children | dbe4af57b240 |
comparison
equal
deleted
inserted
replaced
1127:3e98925bcc39 | 1128:83ef1e7cde70 |
---|---|
1065 IrStruct::InterfaceMapIter iriter = irstruct->interfaceMap.find(it); | 1065 IrStruct::InterfaceMapIter iriter = irstruct->interfaceMap.find(it); |
1066 assert(iriter != irstruct->interfaceMap.end()); | 1066 assert(iriter != irstruct->interfaceMap.end()); |
1067 IrInterface* iri = iriter->second; | 1067 IrInterface* iri = iriter->second; |
1068 // offset pointer | 1068 // offset pointer |
1069 LLValue* v = val->getRVal(); | 1069 LLValue* v = val->getRVal(); |
1070 LLValue* orig = v; | |
1070 v = DtoGEPi(v, 0, iri->index); | 1071 v = DtoGEPi(v, 0, iri->index); |
1072 const LLType* ifType = DtoType(_to); | |
1071 if (Logger::enabled()) | 1073 if (Logger::enabled()) |
1072 { | 1074 { |
1073 Logger::cout() << "V = " << *v << std::endl; | 1075 Logger::cout() << "V = " << *v << std::endl; |
1074 Logger::cout() << "T = " << *DtoType(_to) << std::endl; | 1076 Logger::cout() << "T = " << *ifType << std::endl; |
1075 } | 1077 } |
1076 v = DtoBitCast(v, DtoType(_to)); | 1078 v = DtoBitCast(v, ifType); |
1079 // Check whether the original value was null, and return null if so. | |
1080 // Sure we could have jumped over the code above in this case, but | |
1081 // it's just a GEP and (maybe) a pointer-to-pointer BitCast, so it | |
1082 // should be pretty cheap and perfectly safe even if the original was null. | |
1083 LLValue* isNull = gIR->ir->CreateICmpEQ(orig, LLConstant::getNullValue(orig->getType()), ".nullcheck"); | |
1084 v = gIR->ir->CreateSelect(isNull, LLConstant::getNullValue(ifType), v, ".interface"); | |
1077 // return r-value | 1085 // return r-value |
1078 return new DImValue(_to, v); | 1086 return new DImValue(_to, v); |
1079 } | 1087 } |
1080 // class -> interface | 1088 // class -> interface |
1081 else { | 1089 else { |