slavapestov created this revision. slavapestov added a reviewer: cfe-commits. slavapestov set the repository for this revision to rL LLVM.
This patch fixes an issue that can come up when Swift and Clang are emitting declarations into the same LLVM module. Objective-C class literals result in the emission of a global variable named OBJC_CLASS_$_<ClassName>. Clang and Swift emit this variable with different types, resulting in an LLVM assertion firing. This patch changes Clang to be more resilient in the case where the global has already been emitted, wrapping it in a cast constexpr instead of crashing. Repository: rL LLVM http://reviews.llvm.org/D13954 Files: lib/CodeGen/CGObjCGNU.cpp lib/CodeGen/CGObjCMac.cpp lib/CodeGen/CGObjCRuntime.h lib/CodeGen/CodeGenModule.cpp
Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2739,7 +2739,9 @@ std::string str = StringClass.empty() ? "OBJC_CLASS_$_NSConstantString" : "OBJC_CLASS_$_" + StringClass; - GV = getObjCRuntime().GetClassGlobal(str); + GV = getObjCRuntime().GetClassGlobal(str, + /*ForDefinition=*/false, + /*Weak=*/false); // Make sure the result is of the correct type. llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); V = llvm::ConstantExpr::getBitCast(GV, PTy); Index: lib/CodeGen/CGObjCRuntime.h =================================================================== --- lib/CodeGen/CGObjCRuntime.h +++ lib/CodeGen/CGObjCRuntime.h @@ -268,8 +268,9 @@ const CodeGen::CGBlockInfo &blockInfo) = 0; virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T) = 0; - virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) = 0; + virtual llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) = 0; struct MessageSendInfo { const CGFunctionInfo &CallInfo; Index: lib/CodeGen/CGObjCMac.cpp =================================================================== --- lib/CodeGen/CGObjCMac.cpp +++ lib/CodeGen/CGObjCMac.cpp @@ -1260,8 +1260,9 @@ /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) override { + llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) override { llvm_unreachable("CGObjCMac::GetClassGlobal"); } }; @@ -1362,8 +1363,9 @@ /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) override; + llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) override; /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, /// for the given class reference. @@ -5686,7 +5688,12 @@ llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy)); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, Values); - llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak); + llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>( + GetClassGlobal(ClassName, + /*ForDefinition=*/true, + Weak)); + if (Init->getType() != GV->getValueType()) + Init = llvm::ConstantExpr::getBitCast(Init, GV->getValueType()); GV->setInitializer(Init); GV->setSection("__DATA, __objc_data"); GV->setAlignment( @@ -5755,7 +5762,7 @@ llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix()); llvm::SmallString<64> TClassName; - llvm::GlobalVariable *SuperClassGV, *IsAGV; + llvm::Constant *SuperClassGV, *IsAGV; // Build the flags for the metaclass. bool classIsHidden = @@ -5777,10 +5784,12 @@ TClassName = ObjCClassName; TClassName += ClassName; SuperClassGV = GetClassGlobal(TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->isWeakImported()); TClassName = ObjCMetaClassName; TClassName += ClassName; IsAGV = GetClassGlobal(TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->isWeakImported()); } else { // Has a root. Current class is not a root. @@ -5790,13 +5799,15 @@ TClassName = ObjCMetaClassName ; TClassName += Root->getObjCRuntimeNameAsString(); IsAGV = GetClassGlobal(TClassName.str(), + /*ForDefinition=*/false, Root->isWeakImported()); // work on super class metadata symbol. TClassName = ObjCMetaClassName; TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString(); SuperClassGV = GetClassGlobal( TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->getSuperClass()->isWeakImported()); } llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, @@ -5839,6 +5850,7 @@ TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString(); SuperClassGV = GetClassGlobal( TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->getSuperClass()->isWeakImported()); } GetClassSizeInfo(ID, InstanceStart, InstanceSize); @@ -5928,8 +5940,9 @@ llvm::Constant *Values[6]; Values[0] = GetClassName(OCD->getIdentifier()->getName()); // meta-class entry symbol - llvm::GlobalVariable *ClassGV = - GetClassGlobal(ExtClassName.str(), Interface->isWeakImported()); + llvm::Constant *ClassGV = GetClassGlobal(ExtClassName.str(), + /*ForDefinition=*/false, + Interface->isWeakImported()); Values[1] = ClassGV; std::vector<llvm::Constant*> Methods; @@ -6598,8 +6611,10 @@ false, CallArgs, Method, ObjCTypes); } -llvm::GlobalVariable * -CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, bool Weak) { +llvm::Constant * +CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) { llvm::GlobalValue::LinkageTypes L = Weak ? llvm::GlobalValue::ExternalWeakLinkage : llvm::GlobalValue::ExternalLinkage; @@ -6611,7 +6626,12 @@ false, L, nullptr, Name); assert(GV->getLinkage() == L); - return GV; + + if (ForDefinition || + GV->getValueType() == ObjCTypes.ClassnfABITy) + return GV; + + return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ClassnfABIPtrTy); } llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, @@ -6624,7 +6644,9 @@ std::string ClassName( getClassSymbolPrefix() + (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str()); - llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak); + llvm::Constant *ClassGV = GetClassGlobal(ClassName, + /*ForDefinition=*/false, + Weak); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, ClassGV, "OBJC_CLASSLIST_REFERENCES_$_"); @@ -6656,8 +6678,9 @@ if (!Entry) { llvm::SmallString<64> ClassName(getClassSymbolPrefix()); ClassName += ID->getObjCRuntimeNameAsString(); - llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), - ID->isWeakImported()); + llvm::Constant *ClassGV = GetClassGlobal(ClassName.str(), + /*ForDefinition=*/false, + ID->isWeakImported()); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_"); @@ -6680,8 +6703,9 @@ if (!Entry) { llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix()); MetaClassName += ID->getObjCRuntimeNameAsString(); - llvm::GlobalVariable *MetaClassGV = - GetClassGlobal(MetaClassName.str(), Weak); + llvm::Constant *MetaClassGV = GetClassGlobal(MetaClassName.str(), + /*ForDefinition=*/false, + Weak); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, @@ -6703,7 +6727,10 @@ if (ID->isWeakImported()) { llvm::SmallString<64> ClassName(getClassSymbolPrefix()); ClassName += ID->getObjCRuntimeNameAsString(); - llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true); + llvm::GlobalVariable *ClassGV = cast<llvm::GlobalVariable>( + GetClassGlobal(ClassName.str(), + /*ForDefinition=*/true, + /*Weak=*/true)); (void)ClassGV; assert(ClassGV->hasExternalWeakLinkage()); } @@ -6998,11 +7025,15 @@ llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); + llvm::Constant *ClassGV = GetClassGlobal(ClassName.str(), + /*ForDefinition=*/false, + /*Weak=*/false); + llvm::Constant *Values[] = { llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV, VTableIdx), GetClassName(ID->getObjCRuntimeNameAsString()), - GetClassGlobal(ClassName.str())}; + ClassGV}; llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); Index: lib/CodeGen/CGObjCGNU.cpp =================================================================== --- lib/CodeGen/CGObjCGNU.cpp +++ lib/CodeGen/CGObjCGNU.cpp @@ -560,8 +560,9 @@ return NULLPtr; } - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) override { + llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) override { return nullptr; } };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits