On Apr 15, 2013, at 1:56 PM, John McCall <[email protected]> wrote:

On Apr 15, 2013, at 1:38 PM, jahanian <[email protected]> wrote:
Here is the patch.

I think you can just change the cache to an llvm::WeakVH.

This patch is the new patch. Please review.

Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp       (revision 179530)
+++ lib/CodeGen/CodeGenModule.cpp       (working copy)
@@ -2279,7 +2279,8 @@
 
   llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty);
   llvm::Constant *Zeros[] = { Zero, Zero };
-
+  llvm::Value *V;
+  
   // If we don't already have it, get __CFConstantStringClassReference.
   if (!CFConstantStringClassRef) {
     llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
@@ -2287,9 +2288,11 @@
     llvm::Constant *GV = CreateRuntimeVariable(Ty,
                                            "__CFConstantStringClassReference");
     // Decay array -> ptr
-    CFConstantStringClassRef =
-      llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
+    V = llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
+    CFConstantStringClassRef = V;
   }
+  else
+    V = CFConstantStringClassRef;
 
   QualType CFTy = getContext().getCFConstantStringType();
 
@@ -2299,7 +2302,7 @@
   llvm::Constant *Fields[4];
 
   // Class pointer.
-  Fields[0] = CFConstantStringClassRef;
+  Fields[0] = cast<llvm::ConstantExpr>(V);
 
   // Flags.
   llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h (revision 179530)
+++ lib/CodeGen/CodeGenModule.h (working copy)
@@ -346,7 +346,7 @@
 
   /// CFConstantStringClassRef - Cached reference to the class for constant
   /// strings. This value has type int * but is actually an Obj-C class 
pointer.
-  llvm::Constant *CFConstantStringClassRef;
+  llvm::WeakVH CFConstantStringClassRef;
 
   /// ConstantStringClassRef - Cached reference to the class for constant
   /// strings. This value has type int * but is actually an Obj-C class 
pointer.
Index: test/CodeGenObjC/tentative-cfconstantstring.m
===================================================================
--- test/CodeGenObjC/tentative-cfconstantstring.m       (revision 0)
+++ test/CodeGenObjC/tentative-cfconstantstring.m       (working copy)
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | 
FileCheck %s
+// rdar://13598026
+
+@interface NSObject @end
+
+@class NSString;
+
+int __CFConstantStringClassReference[24];
+
+@interface Bar : NSObject
++(void)format:(NSString *)format,...;
+@end
+
+@interface Foo : NSObject
+@end
+
+
+static inline void _inlineFunction() {
+    [Bar format:@" "];
+}
+
+@implementation Foo
+
+
++(NSString *)someMethod {
+   return @"";
+}
+
+-(void)someMethod {
+   _inlineFunction();
+}
+@end
+
+// CHECK: @__CFConstantStringClassReference = common global [24 x i32] 
zeroinitializer, align 16
+// CHECK: @_unnamed_cfstring_{{.*}} = private constant 
%struct.NSConstantString { i32* getelementptr inbounds ([24 x i32]* 
@__CFConstantStringClassReference, i32 0, i32 0)
+
+// CHECK: define internal void @_inlineFunction()
+// CHECK-NEXT: entry:
+// CHECK-NEXT:  [[ZERO:%.*]] = load %struct._class_t** 
@"\01L_OBJC_CLASSLIST_REFERENCES_
+// CHECK-NEXT:   [[ONE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_"
+// CHECK-NEXT:   [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
+// CHECK-NEXT:   call{{.*}}@objc_msgSend{{.*}}(i8* [[TWO]], i8* [[ONE]], 
[[ZERO]]* bitcast (%struct.NSConstantString* @_unnamed_cfstring_{{.*}}
+// CHECK-NEXT:   ret void
+

- Fariborz


John.

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to