]> granicus.if.org Git - clang/commitdiff
Patch to fix IR-gen crash generating structure ABI which implements
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 17 May 2011 22:21:16 +0000 (22:21 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 17 May 2011 22:21:16 +0000 (22:21 +0000)
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

lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/CodeGen/CodeGenModule.cpp
test/CodeGenObjC/constant-string-class-1.m [new file with mode: 0644]
test/CodeGenObjC/constant-string-class.m

index c4dc4c41da6dad38593f98286c6d819d9d7cae0a..7cf4f0bbc9e33466c42b4fc7e98daaf93a6b4f51 100644 (file)
@@ -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.
index 50f2c78b5248a395f6cbef3a279a299032f29c62..99d464f8846e6d39c4d76e03e00843e41435615e 100644 (file)
@@ -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,
index 0cc2d824d401a0334b4f7e135163091dc7c9a112..fdb58d91e99d88d944a319d9095a6ce1e6aabe59 100644 (file)
@@ -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.
index 84fa4af669e6309b2867e926bad9266e853dc4ad..7f2e3f593ef044a71ceb05f115a1ab7278a6f5a0 100644 (file)
@@ -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 (file)
index 0000000..8ff605e
--- /dev/null
@@ -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
index 12253d6c70f35c2d8a57185d17d6e82df802c4ea..489f511e78138fb69fcc503a2ecfe3829e8cc734 100644 (file)
@@ -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