aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-07-10 05:39:13 +0000
committerChris Lattner <sabre@nondot.org>2011-07-10 05:39:13 +0000
commit57eb23f34ed2586069273c66f1a9994fe2b42967 (patch)
treec4754d8350e0aebce950aeab9696a70f8e71a89d
parent74339dfbfe3fa9c1839ce02e3427e4dc5478a3ae (diff)
keep track of whether being in a RS_StructPointer state
caused us to skip layout out a function accurately. If so, flush the type cache for both the function and struct case to ensure that any pointers to the functions get recomputed. This is overconservative, but with this patch clang can build itself again. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134863 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp9
-rw-r--r--lib/CodeGen/CodeGenTypes.h6
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp2
-rw-r--r--test/CodeGenObjC/arc-foreach.m4
-rw-r--r--test/CodeGenObjC/arc.m8
5 files changed, 20 insertions, 9 deletions
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 59c632f0d7..16946b64b3 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -32,6 +32,7 @@ CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
: Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD),
TheABIInfo(Info), TheCXXABI(CXXABI), CodeGenOpts(CGO) {
RecursionState = RS_Normal;
+ SkippedLayout = false;
}
CodeGenTypes::~CodeGenTypes() {
@@ -345,6 +346,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// This function's type depends on an incomplete tag type.
// Return a placeholder type.
ResultType = llvm::StructType::get(getLLVMContext());
+
+ SkippedLayout |= RecursionState == RS_StructPointer;
break;
}
@@ -373,6 +376,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// Restore our recursion state.
RecursionState = SavedRecursionState;
+
+ if (SkippedLayout)
+ TypeCache.clear();
if (RecursionState == RS_Normal)
while (!DeferredRecords.empty())
@@ -487,7 +493,8 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
// If this struct blocked a FunctionType conversion, then recompute whatever
// was derived from that.
// FIXME: This is hugely overconservative.
- TypeCache.clear();
+ if (SkippedLayout)
+ TypeCache.clear();
// Restore our recursion state. If we're done converting the outer-most
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 98786007d7..4229c59b83 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -86,7 +86,11 @@ class CodeGenTypes {
RS_Struct, // Recursively inside a struct conversion.
RS_StructPointer // Recursively inside a pointer in a struct.
} RecursionState;
-
+
+ /// SkippedLayout - True if we didn't layout a function bit due to a
+ /// RS_StructPointer RecursionState.
+ bool SkippedLayout;
+
llvm::SmallVector<const RecordDecl *, 8> DeferredRecords;
struct RecursionStatePointerRAII {
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 1d514fb09e..f626a01d53 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -86,7 +86,7 @@ namespace test3 {
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
- // CHECK-NEXT: store {{.*}}* null, {{.*}}** [[CALLBACK]]
+ // CHECK: store {{.*}}* null, {{.*}}** [[CALLBACK]]
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index ccf655b137..f9d7782fbe 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -34,7 +34,7 @@ void test0(NSArray *array) {
// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-LP64-NEXT: store i8* [[T2]], i8** [[T0]]
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]]
-// CHECK-LP64-NEXT: call void @use_block({{.*}}* [[T1]])
+// CHECK-LP64: call void @use_block(
// CHECK-LP64-NEXT: [[T1:%.*]] = load i8** [[T0]]
// CHECK-LP64-NEXT: call void @objc_release(i8* [[T1]])
@@ -67,6 +67,6 @@ void test1(NSArray *array) {
// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[X]])
// CHECK-LP64-NEXT: call i8* @objc_initWeak(i8** [[T0]], i8* [[T1]])
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
-// CHECK-LP64-NEXT: call void @use_block({{.*}} [[T1]])
+// CHECK-LP64: call void @use_block
// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[T0]])
// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[X]])
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index dbfd9d335c..6beac19632 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -1216,7 +1216,7 @@ void test39(void) {
// CHECK: define void @test39()
// CHECK: [[VAR:%.*]] = alloca i8*
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
- // CHECK-NEXT: [[T0:%.*]] = call i8* @test39_source()
+ // CHECK: [[T0:%.*]] = call i8* @test39_source()
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
// CHECK-NEXT: call void @objc_release(i8* [[T1]])
@@ -1226,7 +1226,7 @@ void test39(void) {
// CHECK-NEXT: [[T0:%.*]] = load i8** [[VAR]]
// CHECK-NEXT: store i8* [[T0]], i8** [[CAPTURE]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
- // CHECK-NEXT: call void @test39_helper({{.*}} [[T0]])
+ // CHECK: call void @test39_helper
// CHECK-NEXT: ret void
}
@@ -1330,7 +1330,7 @@ void test41(void) {
// CHECK: [[SELF:%.*]] = alloca [[TEST42:%.*]]*,
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-// CHECK-NEXT: store
+// CHECK: store
// CHECK-NEXT: store
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: [[T1:%.*]] = load [[TEST42]]** [[SELF]],
@@ -1339,7 +1339,7 @@ void test41(void) {
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST42]]*
// CHECK-NEXT: store [[TEST42]]* [[T4]], [[TEST42]]** [[T0]]
// CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to
-// CHECK-NEXT: call void @test42_helper(
+// CHECK: call void @test42_helper(
// CHECK-NEXT: [[T1:%.*]] = load [[TEST42]]** [[T0]]
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST42]]* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])