From: Fariborz Jahanian Date: Tue, 17 May 2011 22:21:16 +0000 (+0000) Subject: Patch to fix IR-gen crash generating structure ABI which implements X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6f40e2244b0590f144c5ceee07981a962fbbc72e;p=clang Patch to fix IR-gen crash generating structure ABI which implements user specified string class via -fconstant-string-class option. pr9914. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131496 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index c4dc4c41da..7cf4f0bbc9 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -484,6 +484,10 @@ public: const CGBlockInfo &blockInfo) { return NULLPtr; } + + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { + return 0; + } }; /// Class representing the legacy GCC Objective-C ABI. This is the default when /// -fobjc-nonfragile-abi is not specified. diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 50f2c78b52..99d464f884 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1048,6 +1048,13 @@ public: virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); + + /// GetClassGlobal - Return the global variable for the Objective-C + /// class of the given name. + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { + assert(false && "CGObjCMac::GetClassGlobal"); + return 0; + } }; class CGObjCNonFragileABIMac : public CGObjCCommonMac { @@ -1142,11 +1149,11 @@ private: bool IsSuper, const CallArgList &CallArgs, const ObjCMethodDecl *Method); - + /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. llvm::GlobalVariable *GetClassGlobal(const std::string &Name); - + /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, /// for the given class reference. llvm::Value *EmitClassRef(CGBuilderTy &Builder, diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 0cc2d824d4..fdb58d91e9 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -243,6 +243,7 @@ public: llvm::Value *Size) = 0; virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo) = 0; + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0; }; /// Creates an instance of an Objective-C runtime class. diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 84fa4af669..7f2e3f593e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1768,24 +1768,31 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { if (!ConstantStringClassRef) { std::string StringClass(getLangOptions().ObjCConstantStringClass); const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); - Ty = llvm::ArrayType::get(Ty, 0); llvm::Constant *GV; - if (StringClass.empty()) - GV = CreateRuntimeVariable(Ty, - Features.ObjCNonFragileABI ? - "OBJC_CLASS_$_NSConstantString" : - "_NSConstantStringClassReference"); - else { + if (Features.ObjCNonFragileABI) { std::string str; - if (Features.ObjCNonFragileABI) + if (StringClass.empty()) + str = "OBJC_CLASS_$_NSConstantString"; + else { str = "OBJC_CLASS_$_" + StringClass; - else - str = "_" + StringClass + "ClassReference"; - GV = CreateRuntimeVariable(Ty, str); + } + GV = getObjCRuntime().GetClassGlobal(str); + // Make sure the result is of the correct type. + const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); + ConstantStringClassRef = + llvm::ConstantExpr::getBitCast(GV, PTy); + } else { + Ty = llvm::ArrayType::get(Ty, 0); + if (StringClass.empty()) + GV = CreateRuntimeVariable(Ty, "_NSConstantStringClassReference"); + else { + std::string str = "_" + StringClass + "ClassReference"; + GV = CreateRuntimeVariable(Ty, str); + } + // Decay array -> ptr + ConstantStringClassRef = + llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); } - // Decay array -> ptr - ConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); } QualType NSTy = getContext().getNSConstantStringType(); diff --git a/test/CodeGenObjC/constant-string-class-1.m b/test/CodeGenObjC/constant-string-class-1.m new file mode 100644 index 0000000000..8ff605ec69 --- /dev/null +++ b/test/CodeGenObjC/constant-string-class-1.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fno-constant-cfstrings -fconstant-string-class OFConstantString -emit-llvm -o %t %s +// pr9914 + +@interface OFConstantString ++ class; +@end + +@interface OFString +- (void)XMLElementBySerializing; +@end + +@implementation OFString + +- (void)XMLElementBySerializing +{ + id str = @"object"; + + [OFConstantString class]; +} + +@end + +// CHECK: @"OBJC_CLASS_$_OFConstantString" = external global diff --git a/test/CodeGenObjC/constant-string-class.m b/test/CodeGenObjC/constant-string-class.m index 12253d6c70..489f511e78 100644 --- a/test/CodeGenObjC/constant-string-class.m +++ b/test/CodeGenObjC/constant-string-class.m @@ -32,4 +32,4 @@ int main () { // CHECK-FRAGILE: @_FooClassReference = common global // CHECK-NONFRAGILE: @"OBJC_CLASS_$_Object" = external global -// CHECK-NONFRAGILE: "OBJC_CLASS_$_Foo" = unnamed_addr global +// CHECK-NONFRAGILE: "OBJC_CLASS_$_Foo" = global