Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp (revision 179530)
+++ lib/CodeGen/CodeGenModule.cpp (working copy)
@@ -80,7 +80,7 @@
TBAA(0),
VTables(*this), ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0),
DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0),
- RRData(0), CFConstantStringClassRef(0),
+ RRData(0),
ConstantStringClassRef(0), NSConstantStringType(0),
VMContext(M.getContext()),
NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
@@ -2279,17 +2279,14 @@
llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty);
llvm::Constant *Zeros[] = { Zero, Zero };
-
- // If we don't already have it, get __CFConstantStringClassReference.
- if (!CFConstantStringClassRef) {
- llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
- Ty = llvm::ArrayType::get(Ty, 0);
- llvm::Constant *GV = CreateRuntimeVariable(Ty,
+
+ llvm::Type *ITy = getTypes().ConvertType(getContext().IntTy);
+ ITy = llvm::ArrayType::get(ITy, 0);
+ llvm::Constant *CFGV = CreateRuntimeVariable(ITy,
"__CFConstantStringClassReference");
- // Decay array -> ptr
- CFConstantStringClassRef =
- llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
- }
+ // Decay array -> ptr
+ llvm::Constant *CFConstantStringClassRef =
+ llvm::ConstantExpr::getGetElementPtr(CFGV, Zeros);
QualType CFTy = getContext().getCFConstantStringType();
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h (revision 179530)
+++ lib/CodeGen/CodeGenModule.h (working copy)
@@ -344,10 +344,6 @@
/// @name Cache for Objective-C runtime types
/// @{
- /// 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;
-
/// ConstantStringClassRef - Cached reference to the class for constant
/// strings. This value has type int * but is actually an Obj-C class
pointer.
llvm::Constant *ConstantStringClassRef;
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 unnamed_addr 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
+
This is // rdar://13598026We cache uses of __CFConstantStringClassReference external symbol when generating the API for cfstring. This, however, causes a crash in extreme rare case where user has chosen to provide a tentative definition of __CFConstantStringClassReference followed by build of a cfstring followed by delayed generation of another cfstring. This sequence of events causes the 2nd access to this cached symbol to be a dangling reference because in the course of completing the tentative definition, the cached __CFConstantStringClassReference has been erased. I fix this by removing caching of __CFConstantStringClassReference altogether. This is because all global symbols are cached in llvm’s global symbol table which is tightly managed. There is no need to have our own cache of this symbol. Please review. - Fariborz
|
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits