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 {