summaryrefslogtreecommitdiffstats
path: root/test/CodeGenObjC
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenObjC')
-rw-r--r--test/CodeGenObjC/arc-arm.m4
-rw-r--r--test/CodeGenObjC/arc-block-copy-escape.m6
-rw-r--r--test/CodeGenObjC/arc-blocks.m63
-rw-r--r--test/CodeGenObjC/arc-captured-32bit-block-var-layout-2.m50
-rw-r--r--test/CodeGenObjC/arc-captured-32bit-block-var-layout.m59
-rw-r--r--test/CodeGenObjC/arc-captured-block-var-inlined-layout.m68
-rw-r--r--test/CodeGenObjC/arc-captured-block-var-layout.m66
-rw-r--r--test/CodeGenObjC/arc-exceptions.m14
-rw-r--r--test/CodeGenObjC/arc-foreach.m16
-rw-r--r--test/CodeGenObjC/arc-literals.m91
-rw-r--r--test/CodeGenObjC/arc-loadweakretained-release.m77
-rw-r--r--test/CodeGenObjC/arc-no-arc-exceptions.m6
-rw-r--r--test/CodeGenObjC/arc-precise-lifetime.m120
-rw-r--r--test/CodeGenObjC/arc-property.m55
-rw-r--r--test/CodeGenObjC/arc-related-result-type.m4
-rw-r--r--test/CodeGenObjC/arc-ternary-op.m138
-rw-r--r--test/CodeGenObjC/arc-unopt.m4
-rw-r--r--test/CodeGenObjC/arc-unoptimized-byref-var.m16
-rw-r--r--test/CodeGenObjC/arc-weak-property.m2
-rw-r--r--test/CodeGenObjC/arc-with-atthrow.m4
-rw-r--r--test/CodeGenObjC/arc.m307
-rw-r--r--test/CodeGenObjC/attr-exception.m27
-rw-r--r--test/CodeGenObjC/bitfield-access.m16
-rw-r--r--test/CodeGenObjC/bitfield-ivar-offsets.m1
-rw-r--r--test/CodeGenObjC/block-byref-variable-layout.m49
-rw-r--r--test/CodeGenObjC/block-var-layout.m20
-rw-r--r--test/CodeGenObjC/blocks.m39
-rw-r--r--test/CodeGenObjC/boxing.m12
-rw-r--r--test/CodeGenObjC/catch-lexical-block.m3
-rw-r--r--test/CodeGenObjC/complex-double-abi.m9
-rw-r--r--test/CodeGenObjC/debug-info-block-captured-self.m70
-rw-r--r--test/CodeGenObjC/debug-info-block-helper.m2
-rw-r--r--test/CodeGenObjC/debug-info-block-line.m89
-rw-r--r--test/CodeGenObjC/debug-info-blocks.m20
-rw-r--r--test/CodeGenObjC/debug-info-fwddecl.m2
-rw-r--r--test/CodeGenObjC/debug-info-id-with-protocol.m41
-rw-r--r--test/CodeGenObjC/debug-info-impl.m2
-rw-r--r--test/CodeGenObjC/debug-info-ivars-extension.m33
-rw-r--r--test/CodeGenObjC/debug-info-ivars-indirect.m32
-rw-r--r--test/CodeGenObjC/debug-info-ivars-private.m36
-rw-r--r--test/CodeGenObjC/debug-info-ivars.m14
-rw-r--r--test/CodeGenObjC/debug-info-property3.m2
-rw-r--r--test/CodeGenObjC/debug-info-pubtypes.m2
-rw-r--r--test/CodeGenObjC/debug-info-self.m13
-rw-r--r--test/CodeGenObjC/debug-info-static-var.m10
-rw-r--r--test/CodeGenObjC/debug-info-synthesis.m4
-rw-r--r--test/CodeGenObjC/encode-test-6.m18
-rw-r--r--test/CodeGenObjC/encode-test.m4
-rw-r--r--test/CodeGenObjC/exceptions.m4
-rw-r--r--test/CodeGenObjC/extended-block-signature-encode.m15
-rw-r--r--test/CodeGenObjC/externally-initialized-selectors.m8
-rw-r--r--test/CodeGenObjC/gc.m4
-rw-r--r--test/CodeGenObjC/gnu-exceptions.m7
-rw-r--r--test/CodeGenObjC/interface-layout-64.m1
-rw-r--r--test/CodeGenObjC/ivar-invariant.m68
-rw-r--r--test/CodeGenObjC/metadata-symbols-32.m3
-rw-r--r--test/CodeGenObjC/metadata-symbols-64.m3
-rw-r--r--test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m36
-rw-r--r--test/CodeGenObjC/non-lazy-classes.m1
-rw-r--r--test/CodeGenObjC/nonlazy-msgSend.m6
-rw-r--r--test/CodeGenObjC/ns_consume_null_check.m79
-rw-r--r--test/CodeGenObjC/objc-align.m1
-rw-r--r--test/CodeGenObjC/objc-arc-container-subscripting.m5
-rw-r--r--test/CodeGenObjC/objc-literal-debugger-test.m4
-rw-r--r--test/CodeGenObjC/objc-literal-tests.m4
-rw-r--r--test/CodeGenObjC/optimized-setter.m1
-rw-r--r--test/CodeGenObjC/property.m3
-rw-r--r--test/CodeGenObjC/protocols-lazy.m1
-rw-r--r--test/CodeGenObjC/reorder-synthesized-ivars.m58
69 files changed, 1527 insertions, 525 deletions
diff --git a/test/CodeGenObjC/arc-arm.m b/test/CodeGenObjC/arc-arm.m
index 2ab8cb6..3989f56 100644
--- a/test/CodeGenObjC/arc-arm.m
+++ b/test/CodeGenObjC/arc-arm.m
@@ -11,9 +11,9 @@ void test1(void) {
extern id test1_helper(void);
// CHECK: [[T0:%.*]] = call arm_aapcscc i8* @test1_helper()
// CHECK-NEXT: call void asm sideeffect "mov\09r7, r7
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = call arm_aapcscc i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]],
- // CHECK-NEXT: call void @objc_storeStrong(
+ // CHECK-NEXT: call arm_aapcscc void @objc_storeStrong(
// CHECK-NEXT: ret void
id x = test1_helper();
}
diff --git a/test/CodeGenObjC/arc-block-copy-escape.m b/test/CodeGenObjC/arc-block-copy-escape.m
index 15c0d1d..3ba7426 100644
--- a/test/CodeGenObjC/arc-block-copy-escape.m
+++ b/test/CodeGenObjC/arc-block-copy-escape.m
@@ -9,14 +9,16 @@ void use_int(int);
void test0(int i) {
block_t block = ^{ use_int(i); };
// CHECK: define void @test0(
- // CHECK: call i8* @objc_retainBlock(i8* {{%.*}}) nounwind, !clang.arc.copy_on_escape
+ // CHECK: call i8* @objc_retainBlock(i8* {{%.*}}) [[NUW:#[0-9]+]], !clang.arc.copy_on_escape
// CHECK: ret void
}
void test1(int i) {
id block = ^{ use_int(i); };
// CHECK: define void @test1(
- // CHECK: call i8* @objc_retainBlock(i8* {{%.*}}) nounwind
+ // CHECK: call i8* @objc_retainBlock(i8* {{%.*}}) [[NUW]]
// CHECK-NOT: !clang.arc.copy_on_escape
// CHECK: ret void
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index e776517..3281b2a 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -13,10 +13,10 @@ int (^test1(int x))(void) {
// CHECK-NEXT: store i32 {{%.*}}, i32* [[X]]
// CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to i32 ()*
// CHECK-NEXT: [[T1:%.*]] = bitcast i32 ()* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) nounwind
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i32 ()*
// CHECK-NEXT: [[T4:%.*]] = bitcast i32 ()* [[T3]] to i8*
- // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T4]]) nounwind
+ // CHECK-NEXT: [[T5:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T4]]) [[NUW]]
// CHECK-NEXT: [[T6:%.*]] = bitcast i8* [[T5]] to i32 ()*
// CHECK-NEXT: ret i32 ()* [[T6]]
return ^{ return x; };
@@ -36,9 +36,9 @@ void test2(id x) {
// CHECK-NEXT: bitcast
// CHECK-NEXT: call void @test2_helper(
// CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOTREL]]
-// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
+// CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
-// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
+// CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: ret void
extern void test2_helper(id (^)(void));
test2_helper(^{ return x; });
@@ -50,7 +50,7 @@ void test2(id x) {
// CHECK-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[SRC]], i32 0, i32 5
// CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
-// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]
// CHECK-NEXT: ret void
// CHECK: define internal void @__destroy_helper_block_
@@ -80,13 +80,14 @@ void test3(void (^sink)(id*)) {
// CHECK-NEXT: bitcast
// CHECK-NEXT: getelementptr
// CHECK-NEXT: [[BLOCK:%.*]] = bitcast
- // CHECK-NEXT: [[T0:%.*]] = load i8** [[STRONG]]
- // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]
+ // CHECK-NEXT: [[V:%.*]] = load i8** [[STRONG]]
+ // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]]
// CHECK-NEXT: [[F0:%.*]] = load i8**
// CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)*
// CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]])
// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V]]) [[NUW]]
// CHECK-NEXT: [[T2:%.*]] = load i8** [[STRONG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
@@ -111,8 +112,8 @@ void test4(void) {
// CHECK: [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 2
- // 0x02000000 - has copy/dispose helpers
- // CHECK-NEXT: store i32 33554432, i32* [[T0]]
+ // 0x02000000 - has copy/dispose helpers strong
+ // CHECK-NEXT: store i32 838860800, i32* [[T0]]
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source()
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
@@ -127,7 +128,7 @@ void test4(void) {
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
// CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]]
// CHECK-NEXT: call void @objc_release(i8* [[T0]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__Block_byref_object_copy_
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
@@ -190,8 +191,8 @@ void test6(void) {
// CHECK: [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 2
- // 0x02000000 - has copy/dispose helpers
- // CHECK-NEXT: store i32 33554432, i32* [[T0]]
+ // 0x02000000 - has copy/dispose helpers weak
+ // CHECK-NEXT: store i32 1107296256, i32* [[T0]]
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source()
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
@@ -206,7 +207,7 @@ void test6(void) {
// CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
// CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__Block_byref_object_copy_
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
@@ -250,18 +251,19 @@ void test7(void) {
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
// CHECK: store i32 -1040187392,
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
- // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[VAR]])
+ // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[VAR]])
// CHECK-NEXT: call i8* @objc_initWeak(i8** [[SLOT]], i8* [[T0]])
// CHECK: call void @test7_helper(
// CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}})
// CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
// CHECK: define internal void @__test7_block_invoke
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* {{%.*}}, i32 0, i32 5
- // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[SLOT]])
+ // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[SLOT]])
// CHECK-NEXT: call void @test7_consume(i8* [[T0]])
- // CHECK-NEXT: ret void
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+ // CHECK: ret void
// CHECK: define internal void @__copy_helper_block_
// CHECK: getelementptr
@@ -294,7 +296,7 @@ void test7(void) {
// CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]** [[D0]]
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST8]]* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
-// CHECK-NEXT: ret void
+// CHECK: ret void
extern void test8_helper(void (^)(void));
test8_helper(^{ (void) self; });
@@ -313,7 +315,7 @@ id test9(void) {
// CHECK: load i8** getelementptr
// CHECK-NEXT: bitcast i8*
// CHECK-NEXT: call i8*
-// CHECK-NEXT: call i8* @objc_autoreleaseReturnValue
+// CHECK-NEXT: tail call i8* @objc_autoreleaseReturnValue
// CHECK-NEXT: ret i8*
// CHECK: call i8* @test9_produce()
@@ -352,7 +354,7 @@ void test10a(void) {
// CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
// CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// <rdar://problem/10402698>: do this copy and dispose with
@@ -372,7 +374,7 @@ void test10a(void) {
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
// CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8
-// CHECK-NEXT: ret void
+// CHECK: ret void
// CHECK: define internal void @__Block_byref_object_dispose
// CHECK: [[T0:%.*]] = load i8** {{%.*}}
@@ -416,7 +418,7 @@ void test10b(void) {
// CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
// CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// rdar://problem/10088932
@@ -436,7 +438,7 @@ void test11a(void) {
// CHECK-NEXT: call void @test11_helper(i8* [[T4]])
// CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
void test11b(void) {
int x;
@@ -454,7 +456,7 @@ void test11b(void) {
// CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8
// CHECK-NEXT: [[T5:%.*]] = load i8** [[B]]
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// rdar://problem/9979150
@@ -613,8 +615,8 @@ void test18(id x) {
// CHECK-UNOPT: define void @test18(
// CHECK-UNOPT: [[X:%.*]] = alloca i8*,
// CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-// CHECK-UNOPT-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}})
-// CHECK-UNOPT-NEXT: store i8* [[PARM]], i8** [[X]]
+// CHECK-UNOPT-NEXT: store i8* null, i8** [[X]]
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]],
// CHECK-UNOPT-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-UNOPT: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8** [[X]],
@@ -622,8 +624,8 @@ void test18(id x) {
// CHECK-UNOPT-NEXT: store i8* [[T1]], i8** [[SLOT]],
// CHECK-UNOPT-NEXT: bitcast
// CHECK-UNOPT-NEXT: call void @test18_helper(
-// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[SLOTREL]], i8* null) nounwind
-// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) nounwind
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[SLOTREL]], i8* null) [[NUW:#[0-9]+]]
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) [[NUW]]
// CHECK-UNOPT-NEXT: ret void
extern void test18_helper(id (^)(void));
test18_helper(^{ return x; });
@@ -637,7 +639,7 @@ void test18(id x) {
// CHECK-UNOPT-NEXT: [[T1:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[DST]], i32 0, i32 5
// CHECK-UNOPT-NEXT: [[T2:%.*]] = load i8** [[T0]]
// CHECK-UNOPT-NEXT: store i8* null, i8** [[T1]]
-// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T1]], i8* [[T2]]) nounwind
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T1]], i8* [[T2]]) [[NUW]]
// CHECK-UNOPT-NEXT: ret void
// CHECK-UNOPT: define internal void @__destroy_helper_block_
@@ -647,3 +649,6 @@ void test18(id x) {
// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null)
// CHECK-UNOPT-NEXT: ret void
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
+// CHECK-UNOPT: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-captured-32bit-block-var-layout-2.m b/test/CodeGenObjC/arc-captured-32bit-block-var-layout-2.m
new file mode 100644
index 0000000..3072316
--- /dev/null
+++ b/test/CodeGenObjC/arc-captured-32bit-block-var-layout-2.m
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
+// RUN: FileCheck --input-file=%t-32.layout %s
+// rdar://12184410
+// rdar://12752901
+
+@class NSString;
+extern void NSLog(NSString *format, ...);
+extern int printf(const char *, ...);
+
+int main() {
+ NSString *strong;
+ unsigned long long eightByte = 0x8001800181818181ull;
+ // Test1
+// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
+ void (^block1)() = ^{ printf("%#llx", eightByte); NSLog(@"%@", strong); };
+
+ // Test2
+ int i = 1;
+// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
+ void (^block2)() = ^{ printf("%#llx, %d", eightByte, i); NSLog(@"%@", strong); };
+
+ // Test3
+ char ch = 'a';
+// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
+ void (^block3)() = ^{ printf("%c %#llx", ch, eightByte); NSLog(@"%@", strong); };
+
+ // Test4
+ unsigned long fourByte = 0x8001ul;
+// block variable layout: BL_NON_OBJECT_WORD:1, BL_STRONG:1, BL_OPERATOR:0
+// CHECK: Inline instruction for block variable layout: 0x0100
+ void (^block4)() = ^{ printf("%c %#lx", ch, fourByte); NSLog(@"%@", strong); };
+
+ // Test5
+// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
+ void (^block5)() = ^{ NSLog(@"%@", strong); printf("%c %#llx", ch, eightByte); };
+
+ // Test6
+// CHECK: block variable layout: BL_OPERATOR:0
+ void (^block6)() = ^{ printf("%#llx", eightByte); };
+}
+
+/**
+struct __block_literal_generic { // 32bytes (64bit) and 20 bytes (32bit).
+0 void *__isa;
+4 int __flags;
+8 int __reserved;
+12 void (*__invoke)(void *);
+16 struct __block_descriptor *__descriptor;
+};
+*/
diff --git a/test/CodeGenObjC/arc-captured-32bit-block-var-layout.m b/test/CodeGenObjC/arc-captured-32bit-block-var-layout.m
index 6c72138..7ecdb4b 100644
--- a/test/CodeGenObjC/arc-captured-32bit-block-var-layout.m
+++ b/test/CodeGenObjC/arc-captured-32bit-block-var-layout.m
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o %t-64.s
-// RUN: FileCheck --input-file=%t-64.s %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
+// RUN: FileCheck --input-file=%t-32.layout %s
// rdar://12184410
+// rdar://12752901
void x(id y) {}
void y(int a) {}
@@ -32,8 +33,7 @@ void f() {
// and a descriptor pointer).
// Test 1
-// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
+// CHECK: Inline instruction for block variable layout: 0x0320
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -44,8 +44,7 @@ void f() {
b();
// Test 2
-// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
+// CHECK: Inline instruction for block variable layout: 0x0331
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -66,8 +65,7 @@ void g() {
unsigned int i;
NSString *y;
NSString *z;
-// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"!1P1\00"
+// CHECK: Inline instruction for block variable layout: 0x0401
void (^c)() = ^{
int j = i + bletch;
x(foo);
@@ -112,7 +110,7 @@ void h() {
block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
*/
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
+// CHECK: block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@@ -127,8 +125,7 @@ void arr1() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
-// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
+// CHECK: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@@ -143,8 +140,7 @@ void arr2() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
-// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
+// CHECK: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@@ -159,8 +155,7 @@ void arr3() {
__unsafe_unretained id unsafe_unretained_var[0];
} imported_s;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
void (^c)() = ^{
int i = imported_s.a;
};
@@ -186,15 +181,7 @@ void arr4() {
} f4[2][2];
} captured_s;
-/**
-block variable layout: BL_UNRETAINE:3,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_OPERATOR:0
-*/
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
+// CHECK: block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
id i = captured_s.f0.s_f1;
};
@@ -212,8 +199,7 @@ void bf1() {
int flag4: 24;
} s;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@@ -226,8 +212,7 @@ void bf2() {
int flag : 1;
} s;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@@ -258,8 +243,7 @@ void bf3() {
unsigned int _filler : 32;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@@ -294,8 +278,7 @@ void bf4() {
unsigned int _filler : 32;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@@ -313,8 +296,7 @@ void bf5() {
unsigned char flag1 : 1;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@@ -331,8 +313,7 @@ void bf6() {
unsigned char flag1 : 1;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@@ -348,8 +329,7 @@ void Test7() {
__weak id wid9, wid10, wid11, wid12;
__weak id wid13, wid14, wid15, wid16;
const id bar = (id) opaque_id();
-//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
+// CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);
@@ -384,8 +364,7 @@ __weak id wid;
__weak id w9, w10, w11, w12;
__weak id w13, w14, w15, w16;
const id bar = (id) opaque_id();
-// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
+// CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);
diff --git a/test/CodeGenObjC/arc-captured-block-var-inlined-layout.m b/test/CodeGenObjC/arc-captured-block-var-inlined-layout.m
index b930737..28c5bb4 100644
--- a/test/CodeGenObjC/arc-captured-block-var-inlined-layout.m
+++ b/test/CodeGenObjC/arc-captured-block-var-inlined-layout.m
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-i386 %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
+// RUN: FileCheck --input-file=%t-64.layout %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
+// RUN: FileCheck -check-prefix=CHECK-i386 --input-file=%t-32.layout %s
// rdar://12184410
void x(id y) {}
@@ -15,25 +17,22 @@ void f() {
__block id byref_bab = (id)0;
__block id bl_var1;
-// Inline instruction for block variable layout: 0x0100
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 256 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 256 }
+// CHECK: Inline instruction for block variable layout: 0x0100
+// CHECK-i386: Inline instruction for block variable layout: 0x0100
void (^b)() = ^{
x(bar);
};
-// Inline instruction for block variable layout: 0x0210
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 528 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 528 }
+// CHECK: Inline instruction for block variable layout: 0x0210
+// CHECK-i386: Inline instruction for block variable layout: 0x0210
void (^c)() = ^{
x(bar);
x(baz);
byref_int = 1;
};
-// Inline instruction for block variable layout: 0x0230
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 560 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 560 }
+// CHECK: Inline instruction for block variable layout: 0x0230
+// CHECK-i386: Inline instruction for block variable layout: 0x0230
void (^d)() = ^{
x(bar);
x(baz);
@@ -42,9 +41,8 @@ void f() {
byref_bab = 0;
};
-// Inline instruction for block variable layout: 0x0231
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 561 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 561 }
+// CHECK: Inline instruction for block variable layout: 0x0231
+// CHECK-i386: Inline instruction for block variable layout: 0x0231
__weak id wid;
id (^e)() = ^{
x(bar);
@@ -55,9 +53,8 @@ void f() {
return wid;
};
-// Inline instruction for block variable layout: 0x0235
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 565 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 565 }
+// CHECK: Inline instruction for block variable layout: 0x0235
+// CHECK-i386: Inline instruction for block variable layout: 0x0235
__weak id wid1, wid2, wid3, wid4;
id (^f)() = ^{
x(bar);
@@ -72,9 +69,8 @@ void f() {
return wid;
};
-// Inline instruction for block variable layout: 0x035
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 53 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 53 }
+// CHECK: Inline instruction for block variable layout: 0x035
+// CHECK-i386: Inline instruction for block variable layout: 0x035
id (^g)() = ^{
byref_int = 1;
bl_var1 = 0;
@@ -86,27 +82,41 @@ void f() {
return wid;
};
-// Inline instruction for block variable layout: 0x01
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 1 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 1 }
+// CHECK: Inline instruction for block variable layout: 0x01
+// CHECK-i386: Inline instruction for block variable layout: 0x01
id (^h)() = ^{
return wid;
};
-// Inline instruction for block variable layout: 0x020
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 32 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 32 }
+// CHECK: Inline instruction for block variable layout: 0x020
+// CHECK-i386: Inline instruction for block variable layout: 0x020
void (^ii)() = ^{
byref_int = 1;
byref_bab = 0;
};
-// Inline instruction for block variable layout: 0x0102
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 258 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 258 }
+// CHECK: Inline instruction for block variable layout: 0x0102
+// CHECK-i386: Inline instruction for block variable layout: 0x0102
void (^jj)() = ^{
x(bar);
x(wid1);
x(wid2);
};
}
+
+// rdar://12752901
+@class NSString;
+extern void NSLog(NSString *format, ...);
+typedef void (^dispatch_block_t)(void);
+int main() {
+ __strong NSString *s1 = 0;
+ __strong NSString *s2 = 0;
+ __weak NSString *w1 = 0;
+
+
+// CHECK: Inline instruction for block variable layout: 0x0201
+// CHECK-i386: Inline instruction for block variable layout: 0x0201
+ dispatch_block_t block2 = ^{
+ NSLog(@"%@, %@, %@", s1, w1, s2);
+ };
+}
diff --git a/test/CodeGenObjC/arc-captured-block-var-layout.m b/test/CodeGenObjC/arc-captured-block-var-layout.m
index 77f042e..bc20307 100644
--- a/test/CodeGenObjC/arc-captured-block-var-layout.m
+++ b/test/CodeGenObjC/arc-captured-block-var-layout.m
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o %t-64.s
-// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.layout %s
// rdar://12184410
+// rdar://12752901
void x(id y) {}
void y(int a) {}
@@ -32,8 +33,8 @@ void f() {
// and a descriptor pointer).
// Test 1
-// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
+// Inline instruction for block variable layout: 0x0320 (3 strong 2 byref)
+// CHECK-LP64: Inline instruction for block variable layout: 0x0320
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -44,8 +45,8 @@ void f() {
b();
// Test 2
-// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
+// Inline instruction for block variable layout: 0x0331 (3 strong 3 byref 1 weak)
+// CHECK-LP64: Inline instruction for block variable layout: 0x0331
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -66,8 +67,8 @@ void g() {
unsigned int i;
NSString *y;
NSString *z;
-// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"1P1\00"
+// Inline instruction for block variable layout: 0x0401 (4 strong 0 byref 1 weak)
+// CHECK-LP64: Inline instruction for block variable layout: 0x0401
void (^c)() = ^{
int j = i + bletch;
x(foo);
@@ -108,11 +109,7 @@ void h() {
union U u2;
__block id block_id;
-/**
-block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
- BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
-*/
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
+// CHECK-LP64: block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@@ -127,8 +124,7 @@ void arr1() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
-// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
+// CHECK-LP64: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@@ -143,8 +139,7 @@ void arr2() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
-// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
+// CHECK-LP64: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@@ -159,8 +154,7 @@ void arr3() {
__unsafe_unretained id unsafe_unretained_var[0];
} imported_s;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
void (^c)() = ^{
int i = imported_s.a;
};
@@ -186,15 +180,7 @@ void arr4() {
} f4[2][2];
} captured_s;
-/**
-block variable layout: BL_UNRETAINE:3,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
- BL_OPERATOR:0
-*/
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
+// CHECK-LP64: block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
id i = captured_s.f0.s_f1;
};
@@ -212,8 +198,7 @@ void bf1() {
int flag4: 24;
} s;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@@ -226,8 +211,7 @@ void bf2() {
int flag : 1;
} s;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@@ -258,8 +242,7 @@ void bf3() {
unsigned int _filler : 32;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@@ -294,8 +277,7 @@ void bf4() {
unsigned int _filler : 32;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@@ -313,8 +295,7 @@ void bf5() {
unsigned char flag1 : 1;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@@ -331,8 +312,7 @@ void bf6() {
unsigned char flag1 : 1;
} _flags;
-// block variable layout: BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
+// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@@ -348,8 +328,7 @@ void Test7() {
__weak id wid9, wid10, wid11, wid12;
__weak id wid13, wid14, wid15, wid16;
const id bar = (id) opaque_id();
-//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
+// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);
@@ -384,8 +363,7 @@ __weak id wid;
__weak id w9, w10, w11, w12;
__weak id w13, w14, w15, w16;
const id bar = (id) opaque_id();
-// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
+// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);
diff --git a/test/CodeGenObjC/arc-exceptions.m b/test/CodeGenObjC/arc-exceptions.m
index 63945e3..aa3d2f3 100644
--- a/test/CodeGenObjC/arc-exceptions.m
+++ b/test/CodeGenObjC/arc-exceptions.m
@@ -17,12 +17,12 @@ void test0(void) {
// CHECK: [[T0:%.*]] = call i8* @objc_begin_catch(
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
+// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) nounwind
-// CHECK-NEXT: call void @objc_end_catch() nounwind
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
+// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
void test1_helper(void);
void test1(void) {
@@ -38,7 +38,9 @@ void test1(void) {
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) nounwind
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) nounwind
-// CHECK-NEXT: call void @objc_end_catch() nounwind
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
+// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index b8d2d30..176b28d 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -30,10 +30,10 @@ void test0(NSArray *array) {
// CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// Initialize 'array'.
-// CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[ARRAY_T:%.*]]* {{%.*}} to i8*
-// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
-// CHECK-LP64-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[ARRAY_T]]*
-// CHECK-LP64-NEXT: store [[ARRAY_T]]* [[T2]], [[ARRAY_T]]** [[ARRAY]], align 8
+// CHECK-LP64-NEXT: store [[ARRAY_T]]* null, [[ARRAY_T]]** [[ARRAY]]
+// CHECK-LP64-NEXT: [[ZERO:%.*]] = bitcast [[ARRAY_T]]** [[ARRAY]] to i8**
+// CHECK-LP64-NEXT: [[ONE:%.*]] = bitcast [[ARRAY_T]]* {{%.*}} to i8*
+// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[ZERO]], i8* [[ONE]]) [[NUW:#[0-9]+]]
// Initialize the fast enumaration state.
// CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[STATE_T]]* [[STATE]] to i8*
@@ -84,7 +84,8 @@ void test0(NSArray *array) {
// CHECK-LP64: define internal void @__test0_block_invoke
// CHECK-LP64: [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
-// CHECK-LP64-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-LP64-NOT: ret
+// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-LP64-NEXT: [[T2:%.*]] = load i8** [[T0]], align 8
// CHECK-LP64-NEXT: call void @use(i8* [[T2]])
@@ -109,8 +110,9 @@ void test1(NSArray *array) {
// CHECK-LP64: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[X]])
+// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_loadWeakRetained(i8** [[X]])
// CHECK-LP64-NEXT: call i8* @objc_initWeak(i8** [[T0]], i8* [[T1]])
+// CHECK-LP64-NEXT: call void @objc_release(i8* [[T1]])
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
// CHECK-LP64: call void @use_block
// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[D0]])
@@ -169,3 +171,5 @@ void test3(NSArray *array) {
// CHECK-LP64-NEXT: call void @use(i8* [[T0]])
// CHECK-LP64-NEXT: br label [[L]]
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m
index 203c2ad..78c5d9d 100644
--- a/test/CodeGenObjC/arc-literals.m
+++ b/test/CodeGenObjC/arc-literals.m
@@ -35,18 +35,28 @@ void test_numeric() {
// CHECK: define void @test_array
void test_array(id a, id b) {
+ // CHECK: [[A:%.*]] = alloca i8*,
+ // CHECK: [[B:%.*]] = alloca i8*,
+
// Retaining parameters
// CHECK: call i8* @objc_retain(i8*
// CHECK: call i8* @objc_retain(i8*
// Constructing the array
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
- // CHECK: store i8*
-
- // CHECK: {{call i8*.*objc_msgSend.*i64 2}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
+ // CHECK-NEXT: [[V0:%.*]] = load i8** [[A]],
+ // CHECK-NEXT: store i8* [[V0]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+ // CHECK-NEXT: [[V1:%.*]] = load i8** [[B]],
+ // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
+
+ // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST
+ // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2)
+ // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]])
id arr = @[a, b];
// CHECK: call void @objc_release
@@ -57,6 +67,11 @@ void test_array(id a, id b) {
// CHECK: define void @test_dictionary
void test_dictionary(id k1, id o1, id k2, id o2) {
+ // CHECK: [[K1:%.*]] = alloca i8*,
+ // CHECK: [[O1:%.*]] = alloca i8*,
+ // CHECK: [[K2:%.*]] = alloca i8*,
+ // CHECK: [[O2:%.*]] = alloca i8*,
+
// Retaining parameters
// CHECK: call i8* @objc_retain(i8*
// CHECK: call i8* @objc_retain(i8*
@@ -64,18 +79,29 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
// CHECK: call i8* @objc_retain(i8*
// Constructing the arrays
- // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1
- // CHECK: store i8*
- // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
- // CHECK: store i8*
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0
+ // CHECK-NEXT: [[V0:%.*]] = load i8** [[K1]],
+ // CHECK-NEXT: store i8* [[V0]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
+ // CHECK-NEXT: [[V1:%.*]] = load i8** [[O1]],
+ // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1
+ // CHECK-NEXT: [[V2:%.*]] = load i8** [[K2]],
+ // CHECK-NEXT: store i8* [[V2]], i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+ // CHECK-NEXT: [[V3:%.*]] = load i8** [[O2]],
+ // CHECK-NEXT: store i8* [[V3]], i8** [[T0]]
// Constructing the dictionary
- // CHECK: {{call i8.*@objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST
+ // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
+ // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2)
+ // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]])
+
id dict = @{ k1 : o1, k2 : o2 };
// CHECK: call void @objc_release
@@ -98,19 +124,36 @@ void test_property(B *b) {
// Retain parameter
// CHECK: call i8* @objc_retain
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*]* [[OBJECTS:%.*]], i32 0, i32 0
+
// Invoke 'prop'
- // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
- // CHECK: {{call.*@objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast
+ // CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8*
+ // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]*
+ // CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*
+
+ // Store to array.
+ // CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
// Invoke arrayWithObjects:count:
- // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
- // CHECK: {{call.*objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T]]** @"\01L_OBJC_CLASSLIST
+ // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1)
+ // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V1]])
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: store
id arr = @[ b.prop ];
// Release b.prop
- // CHECK: call void @objc_release
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[V0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
// Destroy arr
// CHECK: call void @objc_release
diff --git a/test/CodeGenObjC/arc-loadweakretained-release.m b/test/CodeGenObjC/arc-loadweakretained-release.m
new file mode 100644
index 0000000..00d25fa
--- /dev/null
+++ b/test/CodeGenObjC/arc-loadweakretained-release.m
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s
+// rdar://10849570
+
+@interface NSObject @end
+
+@interface SomeClass : NSObject
+- (id) init;
+@end
+
+@implementation SomeClass
+- (void)foo {
+}
+- (id) init {
+ return 0;
+}
++ alloc { return 0; }
+@end
+
+int main (int argc, const char * argv[]) {
+ @autoreleasepool {
+ SomeClass *objPtr1 = [[SomeClass alloc] init];
+ __weak SomeClass *weakRef = objPtr1;
+
+ [weakRef foo];
+
+ objPtr1 = (void *)0;
+ return 0;
+ }
+}
+
+// CHECK: [[SIXTEEN:%.*]] = call i8* @objc_loadWeakRetained(i8** {{%.*}})
+// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast i8* [[SIXTEEN]] to {{%.*}}
+// CHECK-NEXT: [[EIGHTEEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_6"
+// CHECK-NEXT: [[NINETEEN:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
+// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK-NEXT: [[TWENTY:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
+// CHECK-NEXT: call void @objc_release(i8* [[TWENTY]])
+
+void test1(int cond) {
+ extern void test34_sink(id *);
+ __weak id weak;
+ test34_sink(cond ? &weak : 0);
+}
+
+// CHECK: define void @test1(
+// CHECK: [[CONDADDR:%.*]] = alloca i32
+// CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
+// CHECK-NEXT: [[INCRTEMP:%.*]] = alloca i8*
+// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*
+// CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1
+// CHECK-NEXT: store i32
+// CHECK-NEXT: store i8* null, i8** [[WEAK]]
+// CHECK: [[COND1:%.*]] = phi i8**
+// CHECK-NEXT: [[ICRISNULL:%.*]] = icmp eq i8** [[COND1]], null
+// CHECK-NEXT: [[ICRARGUMENT:%.*]] = select i1 [[ICRISNULL]], i8** null, i8** [[INCRTEMP]]
+// CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]]
+// CHECK-NEXT: br i1 [[ICRISNULL]], label [[ICRCONT:%.*]], label [[ICRCOPY:%.*]]
+// CHECK: [[ONE:%.*]] = call i8* @objc_loadWeakRetained(
+// CHECK-NEXT: store i8* [[ONE]], i8** [[CONDCLEANUPSAVE]]
+// CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]]
+// CHECK-NEXT: store i8* [[ONE]], i8** [[INCRTEMP]]
+// CHECK-NEXT: br label
+
+// CHECK: call void @test34_sink(
+// CHECK-NEXT: [[ICRISNULL1:%.*]] = icmp eq i8** [[COND1]], null
+// CHECK-NEXT: br i1 [[ICRISNULL1]], label [[ICRDONE:%.*]], label [[ICRWRITEBACK:%.*]]
+// CHECK: [[TWO:%.*]] = load i8** [[INCRTEMP]]
+// CHECK-NEXT: [[THREE:%.*]] = call i8* @objc_storeWeak(
+// CHECK-NEXT br label [[ICRDONE]]
+// CHECK: [[CLEANUPISACTIVE:%.*]] = load i1* [[CONDCLEANUP]]
+// CHECK-NEXT: br i1 [[CLEANUPISACTIVE]], label [[CLEASNUPACTION:%.*]], label [[CLEANUPDONE:%.*]]
+
+// CHECK: [[FOUR:%.*]] = load i8** [[CONDCLEANUPSAVE]]
+// CHECK-NEXT: call void @objc_release(i8* [[FOUR]])
+// CHECK-NEXT: br label
+// CHECK: call void @objc_destroyWeak(i8** [[WEAK]])
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenObjC/arc-no-arc-exceptions.m b/test/CodeGenObjC/arc-no-arc-exceptions.m
index 7ae061f..008c848 100644
--- a/test/CodeGenObjC/arc-no-arc-exceptions.m
+++ b/test/CodeGenObjC/arc-no-arc-exceptions.m
@@ -10,7 +10,7 @@ void not(void) __attribute__((nothrow));
// CHECK: define void @test0(
// CHECK: call void @thrower(), !clang.arc.no_objc_arc_exceptions !
-// CHECK: call void @not() nounwind, !clang.arc.no_objc_arc_exceptions !
+// CHECK: call void @not() [[NUW:#[0-9]+]], !clang.arc.no_objc_arc_exceptions !
// NO-METADATA: define void @test0(
// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
// NO-METADATA: }
@@ -21,7 +21,7 @@ void test0(void) {
// CHECK: define void @test1(
// CHECK: call void @thrower(), !clang.arc.no_objc_arc_exceptions !
-// CHECK: call void @not() nounwind, !clang.arc.no_objc_arc_exceptions !
+// CHECK: call void @not() [[NUW]], !clang.arc.no_objc_arc_exceptions !
// NO-METADATA: define void @test1(
// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
// NO-METADATA: }
@@ -76,3 +76,5 @@ void test4(void) {
b();
}
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-precise-lifetime.m b/test/CodeGenObjC/arc-precise-lifetime.m
new file mode 100644
index 0000000..595a4f9
--- /dev/null
+++ b/test/CodeGenObjC/arc-precise-lifetime.m
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+#define PRECISE_LIFETIME __attribute__((objc_precise_lifetime))
+
+id test0_helper(void) __attribute__((ns_returns_retained));
+void test0() {
+ PRECISE_LIFETIME id x = test0_helper();
+ x = 0;
+ // CHECK: [[X:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper()
+ // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
+
+ // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: store i8* null, i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
+ // CHECK-NOT: clang.imprecise_release
+
+ // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
+ // CHECK-NOT: clang.imprecise_release
+
+ // CHECK-NEXT: ret void
+}
+
+// rdar://problem/9821110
+@interface Test1
+- (char*) interior __attribute__((objc_returns_inner_pointer));
+// Should we allow this on properties?
+@end
+extern Test1 *test1_helper(void);
+
+// CHECK: define void @test1a()
+void test1a(void) {
+ // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
+ // CHECK-NEXT: store [[TEST1]]* [[T3]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
+ // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
+ // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
+ // CHECK-NEXT: store i8* [[T6]], i8**
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+ // CHECK-NEXT: ret void
+ Test1 *ptr = test1_helper();
+ char *c = [(ptr) interior];
+}
+
+// CHECK: define void @test1b()
+void test1b(void) {
+ // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
+ // CHECK-NEXT: store [[TEST1]]* [[T3]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
+ // CHECK-NEXT: store i8* [[T3]], i8**
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
+ // CHECK-NOT: clang.imprecise_release
+ // CHECK-NEXT: ret void
+ __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper();
+ char *c = [ptr interior];
+}
+
+@interface Test2 {
+@public
+ id ivar;
+}
+@end
+// CHECK: define void @test2(
+void test2(Test2 *x) {
+ x->ivar = 0;
+ // CHECK: [[X:%.*]] = alloca [[TEST2:%.*]]*
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8*
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]]
+ // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]*
+ // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]],
+
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[X]],
+ // CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2.ivar"
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8* [[T1]], i64 [[OFFSET]]
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
+ // CHECK-NEXT: [[T4:%.*]] = load i8** [[T3]],
+ // CHECK-NEXT: store i8* null, i8** [[T3]],
+ // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]]
+ // CHECK-NOT: imprecise
+
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[X]]
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
+
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @test3(i8*
+void test3(PRECISE_LIFETIME id x) {
+ // CHECK: [[X:%.*]] = alloca i8*,
+ // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) [[NUW]]
+ // CHECK-NEXT: store i8* [[T0]], i8** [[X]],
+
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
+ // CHECK-NOT: imprecise_release
+
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m
index db00e36..dde02d7 100644
--- a/test/CodeGenObjC/arc-property.m
+++ b/test/CodeGenObjC/arc-property.m
@@ -8,8 +8,8 @@ void test0(Test0 *t0, id value) {
t0.value = value;
}
// CHECK: define void @test0(
-// CHECK: call i8* @objc_retain(
-// CHECK: call i8* @objc_retain(
+// CHECK: call void @objc_storeStrong
+// CHECK: call void @objc_storeStrong
// CHECK: @objc_msgSend
// CHECK: call void @objc_storeStrong(
// CHECK: call void @objc_storeStrong(
@@ -62,7 +62,7 @@ static Class theGlobalClass;
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST2]]* [[T1]] to i8*
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[OFFSET]]
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
-// CHECK-NEXT: call void @objc_storeStrong(i8** [[T4]], i8* [[T0]]) nounwind
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T4]], i8* [[T0]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: ret void
// CHECK: define internal i8* @"\01-[Test2 theClass]"(
@@ -83,5 +83,52 @@ static Class theGlobalClass;
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8* [[T1]], i64 [[OFFSET]]
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
-// CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) nounwind
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) [[NUW]]
// CHECK-NEXT: ret void
+
+// rdar://13115896
+@interface Test3
+@property id copyMachine;
+@end
+
+void test3(Test3 *t) {
+ id x = t.copyMachine;
+ x = [t copyMachine];
+}
+// CHECK: define void @test3([[TEST3:%.*]]*
+// Prologue.
+// CHECK: [[T:%.*]] = alloca [[TEST3]]*,
+// CHECK-NEXT: [[X:%.*]] = alloca i8*,
+// Property access.
+// CHECK: [[T0:%.*]] = load [[TEST3]]** [[T]],
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
+// Message send.
+// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[T]],
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+// CHECK-NEXT: [[T3:%.*]] = load i8** [[X]],
+// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
+// CHECK-NEXT: call void @objc_release(i8* [[T3]])
+// Epilogue.
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST3]]** [[T]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: ret void
+
+@implementation Test3
+- (id) copyMachine {
+ extern id test3_helper(void);
+ return test3_helper();
+}
+// CHECK: define internal i8* @"\01-[Test3 copyMachine]"(
+// CHECK: [[T0:%.*]] = call i8* @test3_helper()
+// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: ret i8* [[T1]]
+- (void) setCopyMachine: (id) x {}
+@end
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-related-result-type.m b/test/CodeGenObjC/arc-related-result-type.m
index ee0a41d..e8b9701 100644
--- a/test/CodeGenObjC/arc-related-result-type.m
+++ b/test/CodeGenObjC/arc-related-result-type.m
@@ -9,10 +9,10 @@ void test0(Test0 *val) {
// CHECK: define void @test0(
// CHECK: [[VAL:%.*]] = alloca [[TEST0:%.*]]*
// CHECK-NEXT: [[X:%.*]] = alloca [[TEST0]]*
+// CHECK-NEXT: store [[TEST0]]* null
// CHECK-NEXT: bitcast
-// CHECK-NEXT: call i8* @objc_retain(
// CHECK-NEXT: bitcast
-// CHECK-NEXT: store
+// CHECK-NEXT: call void @objc_storeStrong(
// CHECK-NEXT: load [[TEST0]]** [[VAL]],
// CHECK-NEXT: load
// CHECK-NEXT: bitcast
diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m
new file mode 100644
index 0000000..f70e886
--- /dev/null
+++ b/test/CodeGenObjC/arc-ternary-op.m
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+void test0(_Bool cond) {
+ id test0_helper(void) __attribute__((ns_returns_retained));
+
+ // CHECK: define void @test0(
+ // CHECK: [[COND:%.*]] = alloca i8,
+ // CHECK-NEXT: [[X:%.*]] = alloca i8*,
+ // CHECK-NEXT: [[RELVAL:%.*]] = alloca i8*
+ // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1
+ // CHECK-NEXT: zext
+ // CHECK-NEXT: store
+ // CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]]
+ // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
+ // CHECK-NEXT: store i1 false, i1* [[RELCOND]]
+ // CHECK-NEXT: br i1 [[T1]],
+ // CHECK: br label
+ // CHECK: [[CALL:%.*]] = call i8* @test0_helper()
+ // CHECK-NEXT: store i8* [[CALL]], i8** [[RELVAL]]
+ // CHECK-NEXT: store i1 true, i1* [[RELCOND]]
+ // CHECK-NEXT: br label
+ // CHECK: [[T0:%.*]] = phi i8* [ null, {{%.*}} ], [ [[CALL]], {{%.*}} ]
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW:#[0-9]+]]
+ // CHECK-NEXT: store i8* [[T1]], i8** [[X]],
+ // CHECK-NEXT: [[REL:%.*]] = load i1* [[RELCOND]]
+ // CHECK-NEXT: br i1 [[REL]],
+ // CHECK: [[T0:%.*]] = load i8** [[RELVAL]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
+ // CHECK-NEXT: br label
+ // CHECK: [[T0:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
+ // CHECK-NEXT: ret void
+ id x = (cond ? 0 : test0_helper());
+}
+
+void test1(int cond) {
+ __strong id strong;
+ __weak id weak;
+ extern void test1_sink(id *);
+ test1_sink(cond ? &strong : 0);
+ test1_sink(cond ? &weak : 0);
+
+ // CHECK: define void @test1(
+ // CHECK: [[COND:%.*]] = alloca i32
+ // CHECK-NEXT: [[STRONG:%.*]] = alloca i8*
+ // CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
+ // CHECK-NEXT: [[TEMP1:%.*]] = alloca i8*
+ // CHECK-NEXT: [[TEMP2:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: store i8* null, i8** [[STRONG]]
+ // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null)
+
+ // CHECK-NEXT: [[T0:%.*]] = load i32* [[COND]]
+ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
+ // CHECK: [[ARG:%.*]] = phi i8**
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP1]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[ARG]]
+ // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
+ // CHECK-NEXT: br label
+ // CHECK: [[W:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
+ // CHECK-NEXT: call void @test1_sink(i8** [[T1]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W]]) [[NUW]]
+ // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
+ // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T2]])
+ // CHECK-NEXT: br label
+
+ // CHECK: [[T0:%.*]] = load i32* [[COND]]
+ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
+ // CHECK: [[ARG:%.*]] = phi i8**
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]]
+ // CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[ARG]])
+ // CHECK-NEXT: store i8* [[T0]], i8** [[CONDCLEANUPSAVE]]
+ // CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]]
+ // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]]
+ // CHECK-NEXT: br label
+ // CHECK: call void @test1_sink(i8** [[T1]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[TEMP2]]
+ // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]])
+ // CHECK-NEXT: br label
+
+ // CHECK: call void @objc_destroyWeak(i8** [[WEAK]])
+ // CHECK: ret void
+}
+
+// rdar://13113981
+// Test that, when emitting an expression at +1 that we can't peephole,
+// we emit the retain inside the full-expression. If we ever peephole
+// +1s of conditional expressions (which we probably ought to), we'll
+// need to find another example of something we need to do this for.
+void test2(int cond) {
+ extern id test2_producer(void);
+ for (id obj in cond ? test2_producer() : (void*) 0) {
+ }
+
+ // CHECK: define void @test2(
+ // CHECK: [[COND:%.*]] = alloca i32,
+ // CHECK: alloca i8*
+ // CHECK: [[CLEANUP_SAVE:%.*]] = alloca i8*
+ // CHECK: [[RUN_CLEANUP:%.*]] = alloca i1
+ // Evaluate condition; cleanup disabled by default.
+ // CHECK: [[T0:%.*]] = load i32* [[COND]],
+ // CHECK-NEXT: icmp ne i32 [[T0]], 0
+ // CHECK-NEXT: store i1 false, i1* [[RUN_CLEANUP]]
+ // CHECK-NEXT: br i1
+ // Within true branch, cleanup enabled.
+ // CHECK: [[T0:%.*]] = call i8* @test2_producer()
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_SAVE]]
+ // CHECK-NEXT: store i1 true, i1* [[RUN_CLEANUP]]
+ // CHECK-NEXT: br label
+ // Join point for conditional operator; retain immediately.
+ // CHECK: [[T0:%.*]] = phi i8* [ [[T1]], {{%.*}} ], [ null, {{%.*}} ]
+ // CHECK-NEXT: [[RESULT:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // Leaving full-expression; run conditional cleanup.
+ // CHECK-NEXT: [[T0:%.*]] = load i1* [[RUN_CLEANUP]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: [[T0:%.*]] = load i8** [[CLEANUP_SAVE]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+ // CHECK-NEXT: br label
+ // And way down at the end of the loop:
+ // CHECK: call void @objc_release(i8* [[RESULT]])
+}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-unopt.m b/test/CodeGenObjC/arc-unopt.m
index c319bf2..84f5d34 100644
--- a/test/CodeGenObjC/arc-unopt.m
+++ b/test/CodeGenObjC/arc-unopt.m
@@ -9,7 +9,7 @@ Test0 *test0(void) {
// CHECK: [[LD:%.*]] = load [[TEST0:%.*]]** @test0_helper
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]* [[LD]] to i8*
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleaseReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]*
// CHECK-NEXT: ret [[TEST0]]* [[T2]]
}
@@ -19,7 +19,7 @@ id test1(void) {
return test1_helper;
// CHECK: [[LD:%.*]] = load i8** @test1_helper
- // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleaseReturnValue(i8* [[LD]])
+ // CHECK-NEXT: [[T0:%.*]] = tail call i8* @objc_retainAutoreleaseReturnValue(i8* [[LD]])
// CHECK-NEXT: ret i8* [[T0]]
}
diff --git a/test/CodeGenObjC/arc-unoptimized-byref-var.m b/test/CodeGenObjC/arc-unoptimized-byref-var.m
new file mode 100644
index 0000000..d3189e1
--- /dev/null
+++ b/test/CodeGenObjC/arc-unoptimized-byref-var.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT %s
+// rdar://12530881
+
+void test19() {
+ __block id x;
+// CHECK-UNOPT: define internal void @__Block_byref_object_copy
+// CHECK-UNOPT: [[X:%.*]] = getelementptr inbounds [[BYREF_T:%.*]]* [[VAR:%.*]], i32 0, i32 6
+// CHECK-UNOPT: [[X2:%.*]] = getelementptr inbounds [[BYREF_T:%.*]]* [[VAR1:%.*]], i32 0, i32 6
+// CHECK-UNOPT-NEXT: [[SIX:%.*]] = load i8** [[X2]], align 8
+// CHECK-UNOPT-NEXT: store i8* null, i8** [[X]], align 8
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* [[SIX]]) [[NUW:#[0-9]+]]
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X2]], i8* null) [[NUW]]
+// CHECK-UNOPT-NEXT: ret void
+}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-weak-property.m b/test/CodeGenObjC/arc-weak-property.m
index 0a6b2a6..e8d57bc 100644
--- a/test/CodeGenObjC/arc-weak-property.m
+++ b/test/CodeGenObjC/arc-weak-property.m
@@ -22,7 +22,7 @@
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]]
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]])
-// CHECK-NEXT: [[T6:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T5]])
+// CHECK-NEXT: [[T6:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T5]])
// CHECK-NEXT: ret i8* [[T6]]
// CHECK: define internal void @"\01-[WeakPropertyTest setPROP:]"
diff --git a/test/CodeGenObjC/arc-with-atthrow.m b/test/CodeGenObjC/arc-with-atthrow.m
index 213b05b..2570376 100644
--- a/test/CodeGenObjC/arc-with-atthrow.m
+++ b/test/CodeGenObjC/arc-with-atthrow.m
@@ -13,5 +13,7 @@ void test() {
// CHECK: [[T0:%.*]] = call i8* @make()
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_autorelease(i8* [[T1]])
-// CHECK-NEXT: call void @objc_exception_throw(i8* [[T2]]) noreturn
+// CHECK-NEXT: call void @objc_exception_throw(i8* [[T2]]) [[NR:#[0-9]+]]
// CHECK-NEXT: unreachable
+
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index 8e38019..7262dc8 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -1,6 +1,37 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-GLOBALS %s
+// rdar://13129783. Check both native/non-native arc platforms. Here we check
+// that they treat nonlazybind differently.
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
+
+// ARC-ALIEN: declare extern_weak void @objc_storeStrong(i8**, i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8*)
+// ARC-ALIEN: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
+// ARC-ALIEN: declare extern_weak void @objc_release(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retainAutoreleasedReturnValue(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_initWeak(i8**, i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_storeWeak(i8**, i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_loadWeakRetained(i8**)
+// ARC-ALIEN: declare extern_weak void @objc_destroyWeak(i8**)
+// ARC-ALIEN: declare extern_weak i8* @objc_autorelease(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8*)
+
+// ARC-NATIVE: declare void @objc_storeStrong(i8**, i8*)
+// ARC-NATIVE: declare i8* @objc_retain(i8*) [[NLB:#[0-9]+]]
+// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8*)
+// ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB]]
+// ARC-NATIVE: declare void @objc_release(i8*) [[NLB]]
+// ARC-NATIVE: declare i8* @objc_retainAutoreleasedReturnValue(i8*)
+// ARC-NATIVE: declare i8* @objc_initWeak(i8**, i8*)
+// ARC-NATIVE: declare i8* @objc_storeWeak(i8**, i8*)
+// ARC-NATIVE: declare i8* @objc_loadWeakRetained(i8**)
+// ARC-NATIVE: declare void @objc_destroyWeak(i8**)
+// ARC-NATIVE: declare i8* @objc_autorelease(i8*)
+// ARC-NATIVE: declare i8* @objc_retainAutorelease(i8*)
+
// CHECK: define void @test0
void test0(id x) {
// CHECK: [[X:%.*]] = alloca i8*
@@ -9,9 +40,6 @@ void test0(id x) {
// CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]]
// CHECK-NEXT: call void @objc_release(i8* [[TMP]])
// CHECK-NEXT: ret void
-// rdar://12040837
- // CHECK: declare extern_weak i8* @objc_retain(i8*) nonlazybind
- // CHECK: declare extern_weak void @objc_release(i8*) nonlazybind
}
// CHECK: define i8* @test1(i8*
@@ -29,7 +57,7 @@ id test1(id x) {
// CHECK-NEXT: call void @objc_release(i8* [[T0]])
// CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
// CHECK-NEXT: call void @objc_release(i8* [[T1]])
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[RET]])
+ // CHECK-NEXT: [[T1:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[RET]])
// CHECK-NEXT: ret i8* [[T1]]
id y;
return y;
@@ -88,12 +116,12 @@ void test3_unelided() {
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
// CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* [[T1]],
- // CHECK-NEXT: call void @objc_release(i8* [[COPY]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[COPY]]) [[NUW:#[0-9]+]]
[x copy];
// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[X]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
// CHECK-NEXT: ret void
}
@@ -127,13 +155,13 @@ void test3() {
// Assignment to x.
// CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]]
// CHECK-NEXT: store i8* [[COPY]], i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]]
x = [x copy];
// Cleanup for x.
// CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]]
// CHECK-NEXT: ret void
}
@@ -156,7 +184,7 @@ id test4() {
// Retain/release elided.
// CHECK-NEXT: bitcast
// CHECK-NEXT: [[INIT:%.*]] = bitcast
- // CHECK-NEXT: [[RET:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[INIT]])
+ // CHECK-NEXT: [[RET:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[INIT]])
// CHECK-NEXT: ret i8* [[RET]]
@@ -188,7 +216,7 @@ void test5(Test5 *x, id y) {
// CHECK-NEXT: [[VAR:%.*]] = bitcast
// CHECK-NEXT: [[TMP:%.*]] = load i8** [[VAR]]
// CHECK-NEXT: store i8* null, i8** [[VAR]]
- // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]]
x->var = 0;
// CHECK-NEXT: [[YVAL:%.*]] = load i8** [[Y]]
@@ -197,18 +225,18 @@ void test5(Test5 *x, id y) {
// CHECK-NEXT: bitcast
// CHECK-NEXT: getelementptr
// CHECK-NEXT: [[VAR:%.*]] = bitcast
- // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[YVAL]]) nounwind
+ // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[YVAL]]) [[NUW]]
// CHECK-NEXT: [[TMP:%.*]] = load i8** [[VAR]]
// CHECK-NEXT: store i8* [[T0]], i8** [[VAR]]
- // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]]
x->var = y;
// Epilogue.
// CHECK-NEXT: [[TMP:%.*]] = load i8** [[Y]]
- // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]]
// CHECK-NEXT: [[T0:%.*]] = load [[TEST5]]** [[X]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST5]]* [[T0]] to i8*
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
// CHECK-NEXT: ret void
}
@@ -219,7 +247,7 @@ void test6() {
// CHECK-NEXT: [[CALL:%.*]] = call i8* @test6_helper()
// CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
// CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: ret void
id x = test6_helper();
}
@@ -230,10 +258,10 @@ void test7() {
// CHECK: [[X:%.*]] = alloca i8*
// CHECK-NEXT: store i8* null, i8** [[X]]
// CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) nounwind
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]]
// CHECK-NEXT: call void @test7_helper(i8* [[T1]])
// CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: ret void
id x;
test7_helper(x);
@@ -245,27 +273,7 @@ void test8() {
// CHECK: [[X:%.*]] = alloca i8*
// CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper()
// CHECK-NEXT: store i8* [[T0]], i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind
- // CHECK-NOT: imprecise_release
- // CHECK-NEXT: ret void
-}
-
-id test9_helper(void) __attribute__((ns_returns_retained));
-void test9() {
- id x __attribute__((objc_precise_lifetime)) = test9_helper();
- x = 0;
- // CHECK: [[X:%.*]] = alloca i8*
- // CHECK-NEXT: [[CALL:%.*]] = call i8* @test9_helper()
- // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
-
- // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
- // CHECK-NEXT: store i8* null, i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
-
- // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
- // CHECK-NOT: clang.imprecise_release
-
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: ret void
}
@@ -314,7 +322,7 @@ void test11(id (*f)(void) __attribute__((ns_returns_retained))) {
// CHECK-NEXT: [[T1:%.*]] = call i8* [[T0]]()
// CHECK-NEXT: store i8* [[T1]], i8** [[X]], align
// CHECK-NEXT: [[T3:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T3]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T3]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: ret void
id x = f();
}
@@ -343,9 +351,9 @@ void test12(void) {
// CHECK-NEXT: store i8* [[T2]], i8** [[Y]], align
// CHECK-NEXT: [[T4:%.*]] = load i8** [[Y]]
- // CHECK-NEXT: call void @objc_release(i8* [[T4]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]])
- // CHECK-NEXT: ret void
+ // CHECK: ret void
}
// Indirect consuming calls.
@@ -359,7 +367,7 @@ void test13(void) {
extern fnty *test13_func;
// CHECK-NEXT: [[FN:%.*]] = load void (i8*)** @test13_func, align
// CHECK-NEXT: [[X_VAL:%.*]] = load i8** [[X]], align
- // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) nounwind
+ // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) [[NUW]]
// CHECK-NEXT: call void [[FN]](i8* [[X_TMP]])
test13_func(x);
@@ -369,14 +377,14 @@ void test13(void) {
// CHECK-NEXT: [[BLOCK_FN_PTR:%.*]] = getelementptr inbounds [[BLOCKTY]]* [[BLOCK]], i32 0, i32 3
// CHECK-NEXT: [[BLOCK_OPAQUE:%.*]] = bitcast [[BLOCKTY]]* [[BLOCK]] to i8*
// CHECK-NEXT: [[X_VAL:%.*]] = load i8** [[X]], align
- // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) nounwind
+ // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) [[NUW]]
// CHECK-NEXT: [[BLOCK_FN_TMP:%.*]] = load i8** [[BLOCK_FN_PTR]]
// CHECK-NEXT: [[BLOCK_FN:%.*]] = bitcast i8* [[BLOCK_FN_TMP]] to void (i8*, i8*)*
// CHECK-NEXT: call void [[BLOCK_FN]](i8* [[BLOCK_OPAQUE]], i8* [[X_TMP]])
test13_block(x);
// CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
// CHECK-NEXT: ret void
}
@@ -426,14 +434,14 @@ void test13(void) {
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8*
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[Y_OFF]]
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8**
- // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) nounwind
+ // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) [[NUW]]
// Destroy z.
// CHECK-NEXT: [[Z_OFF:%.*]] = load i64* @"OBJC_IVAR_$_Test16.z"
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8*
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[Z_OFF]]
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8**
- // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) nounwind
+ // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) [[NUW]]
// CHECK-NEXT: ret void
@@ -452,19 +460,20 @@ void test13(void) {
void test19() {
// CHECK: define void @test19()
// CHECK: [[X:%.*]] = alloca [5 x i8*], align 16
+ // CHECK: call void @llvm.lifetime.start
// CHECK-NEXT: [[T0:%.*]] = bitcast [5 x i8*]* [[X]] to i8*
- // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false)
+ // CHECK: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false)
id x[5];
extern id test19_helper(void);
x[2] = test19_helper();
// CHECK-NEXT: [[CALL:%.*]] = call i8* @test19_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) nounwind
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*]* [[X]], i32 0, i64 2
// CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]]
// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x i8*]* [[X]], i32 0, i32 0
// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 5
@@ -473,7 +482,7 @@ void test19() {
// CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
// CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1
// CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
// CHECK-NEXT: br i1 [[EQ]],
@@ -512,7 +521,7 @@ void test20(unsigned n) {
// CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
// CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1
// CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[VLA]]
// CHECK-NEXT: br i1 [[EQ]],
@@ -558,7 +567,7 @@ void test21(unsigned n) {
// CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
// CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1
// CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
// CHECK-NEXT: br i1 [[EQ]],
@@ -567,39 +576,6 @@ void test21(unsigned n) {
// CHECK-NEXT: ret void
}
-void test22(_Bool cond) {
- id test22_helper(void) __attribute__((ns_returns_retained));
-
- // CHECK: define void @test22(
- // CHECK: [[COND:%.*]] = alloca i8,
- // CHECK-NEXT: [[X:%.*]] = alloca i8*,
- // CHECK-NEXT: [[RELVAL:%.*]] = alloca i8*
- // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1
- // CHECK-NEXT: zext
- // CHECK-NEXT: store
- // CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]]
- // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
- // CHECK-NEXT: store i1 false, i1* [[RELCOND]]
- // CHECK-NEXT: br i1 [[T1]],
- // CHECK: br label
- // CHECK: [[CALL:%.*]] = call i8* @test22_helper()
- // CHECK-NEXT: store i8* [[CALL]], i8** [[RELVAL]]
- // CHECK-NEXT: store i1 true, i1* [[RELCOND]]
- // CHECK-NEXT: br label
- // CHECK: [[T0:%.*]] = phi i8* [ null, {{%.*}} ], [ [[CALL]], {{%.*}} ]
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) nounwind
- // CHECK-NEXT: store i8* [[T1]], i8** [[X]],
- // CHECK-NEXT: [[REL:%.*]] = load i1* [[RELCOND]]
- // CHECK-NEXT: br i1 [[REL]],
- // CHECK: [[T0:%.*]] = load i8** [[RELVAL]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind
- // CHECK-NEXT: br label
- // CHECK: [[T0:%.*]] = load i8** [[X]]
- // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind
- // CHECK-NEXT: ret void
- id x = (cond ? 0 : test22_helper());
-}
-
// rdar://problem/8922540
// Note that we no longer emit .release_ivars flags.
// rdar://problem/12492434
@@ -646,7 +622,9 @@ void test22(_Bool cond) {
// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST27]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST27]]* [[T3]] to i8*
// CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]]
// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
@@ -681,7 +659,7 @@ void test22(_Bool cond) {
@implementation Test29
static id _test29_allocator = 0;
- (id) init {
-// CHECK: define internal i8* @"\01-[Test29 init]"([[TEST29:%.*]]* {{%.*}},
+// CHECK: define internal i8* @"\01-[Test29 init]"([[TEST29:%[^*]*]]* {{%.*}},
// CHECK: [[SELF:%.*]] = alloca [[TEST29]]*, align 8
// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8
// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32
@@ -710,13 +688,15 @@ static id _test29_allocator = 0;
// Return statement.
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]]
// CHECK-NEXT: [[CALL:%.*]] = bitcast
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*
// CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
// Cleanup.
// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
+// CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
// Return.
// CHECK-NEXT: ret i8* [[RET]]
@@ -754,7 +734,7 @@ static id _test29_allocator = 0;
// Assignment.
// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]*
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST29]]*
// CHECK-NEXT: [[T4:%.*]] = load [[TEST29]]** [[SELF]], align
// CHECK-NEXT: store [[TEST29]]* [[T3]], [[TEST29]]** [[SELF]], align
@@ -764,16 +744,18 @@ static id _test29_allocator = 0;
// Return statement.
// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*
// CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
// Cleanup.
// CHECK-NEXT: [[T0:%.*]] = load i8** [[ALLOCATOR]]
-// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
+// CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
+// CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
// Return.
// CHECK-NEXT: ret i8* [[RET]]
@@ -791,7 +773,7 @@ typedef struct Test30_helper Test30_helper;
char *helper;
}
- (id) init {
-// CHECK: define internal i8* @"\01-[Test30 init]"([[TEST30:%.*]]* {{%.*}},
+// CHECK: define internal i8* @"\01-[Test30 init]"([[TEST30:%[^*]*]]* {{%.*}},
// CHECK: [[RET:%.*]] = alloca [[TEST30]]*
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: alloca i32
@@ -819,7 +801,9 @@ char *helper;
// Return.
// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]]
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
-// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST30]]*
+// CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST30]]* [[T1]] to i8*
// CHECK-NEXT: store i32 1
// Cleanup.
@@ -882,8 +866,8 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]]
// CHECK-NEXT: load [[TEST33]]** [[PTR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]]
- // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP0]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]]
+ // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP0]]
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: bitcast
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]])
@@ -891,14 +875,15 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]]
// CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
// CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T5]])
// CHECK-NEXT: load [[TEST33]]** [[PTR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]]
- // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP1]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[A_T]]** [[A]]
+ // CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP1]]
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: bitcast
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]])
@@ -906,6 +891,7 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use([[A_T]]* [[W0]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]]
// CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]]
// CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8*
@@ -945,61 +931,6 @@ void test33(Test33 *ptr) {
// CHECK-NEXT: ret void
}
-void test34(int cond) {
- __strong id strong;
- __weak id weak;
- extern void test34_sink(id *);
- test34_sink(cond ? &strong : 0);
- test34_sink(cond ? &weak : 0);
-
- // CHECK: define void @test34(
- // CHECK: [[COND:%.*]] = alloca i32
- // CHECK-NEXT: [[STRONG:%.*]] = alloca i8*
- // CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
- // CHECK-NEXT: [[TEMP1:%.*]] = alloca i8*
- // CHECK-NEXT: [[TEMP2:%.*]] = alloca i8*
- // CHECK-NEXT: store i32
- // CHECK-NEXT: store i8* null, i8** [[STRONG]]
- // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null)
-
- // CHECK-NEXT: [[T0:%.*]] = load i32* [[COND]]
- // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
- // CHECK: [[ARG:%.*]] = phi i8**
- // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
- // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP1]]
- // CHECK-NEXT: br i1 [[T0]],
- // CHECK: [[T0:%.*]] = load i8** [[ARG]]
- // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
- // CHECK-NEXT: br label
- // CHECK: call void @test34_sink(i8** [[T1]])
- // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
- // CHECK-NEXT: br i1 [[T0]],
- // CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
- // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
- // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
- // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
- // CHECK-NEXT: call void @objc_release(i8* [[T2]])
- // CHECK-NEXT: br label
-
- // CHECK: [[T0:%.*]] = load i32* [[COND]]
- // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
- // CHECK: [[ARG:%.*]] = phi i8**
- // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
- // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]]
- // CHECK-NEXT: br i1 [[T0]],
- // CHECK: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[ARG]])
- // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]]
- // CHECK-NEXT: br label
- // CHECK: call void @test34_sink(i8** [[T1]])
- // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
- // CHECK-NEXT: br i1 [[T0]],
- // CHECK: [[T0:%.*]] = load i8** [[TEMP2]]
- // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]])
- // CHECK-NEXT: br label
-
- // CHECK: call void @objc_destroyWeak(i8** [[WEAK]])
- // CHECK: ret void
-}
// CHECK: define void @test36
void test36(id x) {
@@ -1034,15 +965,16 @@ void test37(void) {
// CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
// CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]]
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8*
- // CHECK-NEXT: store i8* [[T1]], i8** [[TEMP]]
+ // CHECK-NEXT: [[W0:%.*]] = load [[TEST37]]** [[VAR]]
+ // CHECK-NEXT: [[W1:%.*]] = bitcast [[TEST37]]* [[W0]] to i8*
+ // CHECK-NEXT: store i8* [[W1]], i8** [[TEMP]]
// CHECK-NEXT: call void @test37_helper(i8** [[TEMP]])
// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8*
// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]])
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]*
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[W1]]) [[NUW]]
// CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]** [[VAR]]
// CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]]
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8*
@@ -1186,7 +1118,7 @@ id test52(void) {
// CHECK-NEXT: store i32 5, i32* [[X]],
// CHECK-NEXT: [[T0:%.*]] = load i32* [[X]],
// CHECK-NEXT: [[T1:%.*]] = call i8* @test52_helper(i32 [[T0]])
-// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T1]])
// CHECK-NEXT: ret i8* [[T2]]
}
@@ -1287,7 +1219,7 @@ void test56_test(void) {
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]]
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]])
-// CHECK-NEXT: [[T6:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T5]])
+// CHECK-NEXT: [[T6:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T5]])
// CHECK-NEXT: ret i8* [[T6]]
// CHECK: define internal i8* @"\01-[Test57 unsafe]"(
@@ -1299,57 +1231,6 @@ void test56_test(void) {
// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]]
// CHECK-NEXT: ret i8* [[T5]]
-// rdar://problem/9821110
-@interface Test58
-- (char*) interior __attribute__((objc_returns_inner_pointer));
-// Should we allow this on properties?
-@end
-extern Test58 *test58_helper(void);
-
-// CHECK: define void @test58a()
-void test58a(void) {
- // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper()
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
- // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
- // CHECK-NEXT: store [[TEST58]]* [[T3]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
- // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
- // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
- // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST58]]* [[T3]] to i8*
- // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
- // CHECK-NEXT: store i8* [[T6]], i8**
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
- // CHECK-NEXT: ret void
- Test58 *ptr = test58_helper();
- char *c = [(ptr) interior];
-}
-
-// CHECK: define void @test58b()
-void test58b(void) {
- // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper()
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
- // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
- // CHECK-NEXT: store [[TEST58]]* [[T3]]
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
- // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
- // CHECK-NEXT: store i8* [[T3]], i8**
- // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
- // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
- // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
- // CHECK-NOT: clang.imprecise_release
- // CHECK-NEXT: ret void
- __attribute__((objc_precise_lifetime)) Test58 *ptr = test58_helper();
- char *c = [ptr interior];
-}
-
// rdar://problem/9842343
void test59(void) {
extern id test59_getlock(void);
@@ -1491,7 +1372,7 @@ void test66(void) {
// CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label [[CALL:%.*]]
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T5]])
// CHECK-NEXT: br label [[CONT:%.*]]
-// CHECK: call void @objc_release(i8* [[T5]]) nounwind
+// CHECK: call void @objc_release(i8* [[T5]]) [[NUW]]
// CHECK-NEXT: br label [[CONT:%.*]]
// CHECK: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T8]])
@@ -1543,3 +1424,7 @@ void test70(id i) {
[2] = i
};
}
+
+// ARC-ALIEN: attributes [[NLB]] = { nonlazybind }
+// ARC-NATIVE: attributes [[NLB]] = { nonlazybind }
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/attr-exception.m b/test/CodeGenObjC/attr-exception.m
new file mode 100644
index 0000000..4d8c425
--- /dev/null
+++ b/test/CodeGenObjC/attr-exception.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -fvisibility hidden -o - %s | FileCheck -check-prefix=CHECK-HIDDEN %s
+
+__attribute__((objc_root_class))
+@interface Root {
+ Class isa;
+}
+@end
+
+__attribute__((objc_exception))
+@interface A : Root
+@end
+
+@implementation A
+@end
+// CHECK: @"OBJC_EHTYPE_$_A" = global {{%.*}} { i8** getelementptr (i8** @objc_ehtype_vtable, i32 2)
+// CHECK-HIDDEN: @"OBJC_EHTYPE_$_A" = hidden global {{%.*}} { i8** getelementptr (i8** @objc_ehtype_vtable, i32 2)
+
+__attribute__((objc_exception))
+__attribute__((visibility("default")))
+@interface B : Root
+@end
+
+@implementation B
+@end
+// CHECK: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr (i8** @objc_ehtype_vtable, i32 2)
+// CHECK-HIDDEN: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr (i8** @objc_ehtype_vtable, i32 2)
diff --git a/test/CodeGenObjC/bitfield-access.m b/test/CodeGenObjC/bitfield-access.m
index 6d4c82a..597fe35 100644
--- a/test/CodeGenObjC/bitfield-access.m
+++ b/test/CodeGenObjC/bitfield-access.m
@@ -15,8 +15,8 @@
// end of the structure.
//
// CHECK-I386: define i32 @f0(
-// CHECK-I386: [[t0_0:%.*]] = load i16* {{.*}}, align 1
-// CHECK-I386: lshr i16 [[t0_0]], 7
+// CHECK-I386: [[t0_0:%.*]] = load i8* {{.*}}, align 1
+// CHECK-I386: lshr i8 [[t0_0]], 7
// CHECK-I386: }
int f0(I0 *a) {
return a->y;
@@ -26,13 +26,11 @@ int f0(I0 *a) {
//
// CHECK-ARM: define i32 @f1(
// CHECK-ARM: [[t1_ptr:%.*]] = getelementptr
-// CHECK-ARM: [[t1_base:%.*]] = bitcast i8* [[t1_ptr]] to i32*
-// CHECK-ARM: [[t1_0:%.*]] = load i32* [[t1_base]], align 1
-// CHECK-ARM: lshr i32 [[t1_0]], 1
-// CHECK-ARM: [[t1_base_2_cast:%.*]] = bitcast i32* %{{.*}} to i8*
-// CHECK-ARM: [[t1_base_2:%.*]] = getelementptr i8* [[t1_base_2_cast]]
-// CHECK-ARM: [[t1_1:%.*]] = load i8* [[t1_base_2]], align 1
-// CHECK-ARM: and i8 [[t1_1:%.*]], 1
+// CHECK-ARM: [[t1_base:%.*]] = bitcast i8* [[t1_ptr]] to i40*
+// CHECK-ARM: [[t1_0:%.*]] = load i40* [[t1_base]], align 1
+// CHECK-ARM: [[t1_1:%.*]] = lshr i40 [[t1_0]], 1
+// CHECK-ARM: [[t1_2:%.*]] = and i40 [[t1_1]],
+// CHECK-ARM: trunc i40 [[t1_2]] to i32
// CHECK-ARM: }
@interface I1 {
@public
diff --git a/test/CodeGenObjC/bitfield-ivar-offsets.m b/test/CodeGenObjC/bitfield-ivar-offsets.m
index b0c848f..7a07f27 100644
--- a/test/CodeGenObjC/bitfield-ivar-offsets.m
+++ b/test/CodeGenObjC/bitfield-ivar-offsets.m
@@ -1,4 +1,3 @@
-// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
// RUN: grep -F '@"OBJC_IVAR_$_I0._b0" = global i64 0, section "__DATA, __objc_ivar", align 8' %t
// RUN: grep -F '@"OBJC_IVAR_$_I0._b1" = global i64 0, section "__DATA, __objc_ivar", align 8' %t
diff --git a/test/CodeGenObjC/block-byref-variable-layout.m b/test/CodeGenObjC/block-byref-variable-layout.m
new file mode 100644
index 0000000..9c8f674
--- /dev/null
+++ b/test/CodeGenObjC/block-byref-variable-layout.m
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
+
+// rdar://12759433
+@class NSString;
+
+void Test12759433() {
+ __block __unsafe_unretained NSString *uuByref = (__bridge NSString *)(void*)0x102030405060708;
+ void (^block)() = ^{ uuByref = 0; };
+ block();
+}
+// CHECK: %struct.__block_byref_uuByref = type { i8*, %struct.__block_byref_uuByref*, i32, i32, [[ZERO:%.*]]* }
+int main() {
+ __block __weak id wid;
+ __block long XXX;
+ __block id ID;
+ __block struct S {
+ int iS;
+ double iD;
+ void *pv;
+ __unsafe_unretained id unsunr;
+ } import;
+ void (^c)() = ^{
+// Inline flag for BYREF variable layout (1107296256): BLOCK_BYREF_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_WEAK
+// CHECK: store i32 1107296256, i32* [[T0:%.*]]
+ wid = 0;
+
+// Inline flag for BYREF variable layout (536870912): BLOCK_BYREF_LAYOUT_NON_OBJECT
+// CHECK: store i32 536870912, i32* [[T1:%.*]]
+ XXX = 12345;
+
+// Inline flag for BYREF variable layout (838860800): BLOCK_BYREF_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_STRONG
+// CHECK: store i32 838860800, i32* [[T2:%.*]]
+ ID = 0;
+
+// Inline flag for BYREF variable layout (268435456): BLOCK_BYREF_LAYOUT_EXTENDED
+// BYREF variable layout: BL_NON_OBJECT_WORD:3, BL_UNRETAINED:1, BL_OPERATOR:0
+// CHECK: store i32 268435456, i32* [[T3:%.*]]
+ import.iD = 3.14;
+
+ };
+ c();
+}
+
+// rdar://12787751
+typedef char mds_path_t[1024];
+void directVolumePerfWaitForStoreState()
+{
+ __block mds_path_t path;
+}
diff --git a/test/CodeGenObjC/block-var-layout.m b/test/CodeGenObjC/block-var-layout.m
index 71b14da..ab95231 100644
--- a/test/CodeGenObjC/block-var-layout.m
+++ b/test/CodeGenObjC/block-var-layout.m
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -emit-llvm %s -o %t-64.s
-// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.layout %s
+// rdar://12752901
struct S {
int i1;
@@ -46,8 +47,7 @@ void f() {
// Test 1
// byref int, short, char, char, char, id, id, strong void*, byref id
-// 01 35 10 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x10, 0x00
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -60,7 +60,7 @@ void f() {
// Test 2
// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
// 01 36 10 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x36, 0x10, 0x00
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -76,7 +76,7 @@ void f() {
// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
// 01 34 11 30 00
// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x30, 0x00
void (^d)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -91,7 +91,7 @@ void f() {
// Test 4
// struct S (int, id, int, id, int, id)
// 01 41 11 11 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
struct S s2;
void (^e)() = ^{
x(s2.o1);
@@ -129,7 +129,7 @@ void Test5() {
// struct s2 (int, id, int, id, int, id?), union u2 (id?)
// 01 41 11 12 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\12\00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@@ -146,7 +146,7 @@ void notifyBlock(id dependentBlock) {
// id, id, void(^)()
// 01 33 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x33, 0x00
void (^wrapperBlock)() = ^() {
CFRelease(singleObservationToken);
CFRelease(singleObservationToken);
@@ -159,7 +159,7 @@ void notifyBlock(id dependentBlock) {
void test_empty_block() {
// 01 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
+// CHECK-LP64: block variable layout for block: 0x01, 0x00
void (^wrapperBlock)() = ^() {
};
wrapperBlock();
diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
index 6c85da9..3718ad5 100644
--- a/test/CodeGenObjC/blocks.m
+++ b/test/CodeGenObjC/blocks.m
@@ -57,9 +57,9 @@ void test2(Test2 *x) {
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 1
// CHECK-NEXT: store [[WEAK_T]]* [[WEAKX]], [[WEAK_T]]** [[T1]]
- // Flags. This is just BLOCK_HAS_COPY_DISPOSE.
+ // Flags. This is just BLOCK_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_UNRETAINED
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 2
- // CHECK-NEXT: store i32 33554432, i32* [[T2]]
+ // CHECK-NEXT: store i32 1375731712, i32* [[T2]]
// Size.
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 3
@@ -93,10 +93,43 @@ void test2(Test2 *x) {
// doesn't require a read barrier.
// CHECK: define internal void @__test2_block_invoke
// CHECK: [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-NOT: bitcast
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[WEAK_T]]{{.*}}*
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}* [[T2]], i32 0, i32 1
// CHECK-NEXT: [[T4:%.*]] = load [[WEAK_T]]{{.*}}** [[T3]]
// CHECK-NEXT: [[WEAKX:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}* [[T4]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]** [[WEAKX]], align 4
+
+// rdar://problem/12722954
+// Make sure that ... is appropriately positioned in a block call.
+void test3(void (^block)(int, ...)) {
+ block(0, 1, 2, 3);
+}
+// CHECK: define void @test3(
+// CHECK: [[BLOCK:%.*]] = alloca void (i32, ...)*, align 4
+// CHECK-NEXT: store void (i32, ...)*
+// CHECK-NEXT: [[T0:%.*]] = load void (i32, ...)** [[BLOCK]], align 4
+// CHECK-NEXT: [[T1:%.*]] = bitcast void (i32, ...)* [[T0]] to [[BLOCK_T:%.*]]*
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[T1]], i32 0, i32 3
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8*
+// CHECK-NEXT: [[T4:%.*]] = load i8** [[T2]]
+// CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, ...)*
+// CHECK-NEXT: call void (i8*, i32, ...)* [[T5]](i8* [[T3]], i32 0, i32 1, i32 2, i32 3)
+// CHECK-NEXT: ret void
+
+void test4(void (^block)()) {
+ block(0, 1, 2, 3);
+}
+// CHECK: define void @test4(
+// CHECK: [[BLOCK:%.*]] = alloca void (...)*, align 4
+// CHECK-NEXT: store void (...)*
+// CHECK-NEXT: [[T0:%.*]] = load void (...)** [[BLOCK]], align 4
+// CHECK-NEXT: [[T1:%.*]] = bitcast void (...)* [[T0]] to [[BLOCK_T:%.*]]*
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[T1]], i32 0, i32 3
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8*
+// CHECK-NEXT: [[T4:%.*]] = load i8** [[T2]]
+// CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, i32, i32, i32)*
+// CHECK-NEXT: call void [[T5]](i8* [[T3]], i32 0, i32 1, i32 2, i32 3)
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenObjC/boxing.m b/test/CodeGenObjC/boxing.m
index 9664298..87ff0e7 100644
--- a/test/CodeGenObjC/boxing.m
+++ b/test/CodeGenObjC/boxing.m
@@ -54,17 +54,17 @@ typedef signed char BOOL;
@end
// CHECK: [[WithIntMeth:@".*"]] = internal global [15 x i8] c"numberWithInt:\00"
-// CHECK: [[WithIntSEL:@".*"]] = internal global i8* getelementptr inbounds ([15 x i8]* [[WithIntMeth]]
+// CHECK: [[WithIntSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([15 x i8]* [[WithIntMeth]]
// CHECK: [[WithCharMeth:@".*"]] = internal global [16 x i8] c"numberWithChar:\00"
-// CHECK: [[WithCharSEL:@".*"]] = internal global i8* getelementptr inbounds ([16 x i8]* [[WithCharMeth]]
+// CHECK: [[WithCharSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([16 x i8]* [[WithCharMeth]]
// CHECK: [[WithBoolMeth:@".*"]] = internal global [16 x i8] c"numberWithBool:\00"
-// CHECK: [[WithBoolSEL:@".*"]] = internal global i8* getelementptr inbounds ([16 x i8]* [[WithBoolMeth]]
+// CHECK: [[WithBoolSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([16 x i8]* [[WithBoolMeth]]
// CHECK: [[WithIntegerMeth:@".*"]] = internal global [19 x i8] c"numberWithInteger:\00"
-// CHECK: [[WithIntegerSEL:@".*"]] = internal global i8* getelementptr inbounds ([19 x i8]* [[WithIntegerMeth]]
+// CHECK: [[WithIntegerSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([19 x i8]* [[WithIntegerMeth]]
// CHECK: [[WithUnsignedIntegerMeth:@".*"]] = internal global [27 x i8] c"numberWithUnsignedInteger:\00"
-// CHECK: [[WithUnsignedIntegerSEL:@".*"]] = internal global i8* getelementptr inbounds ([27 x i8]* [[WithUnsignedIntegerMeth]]
+// CHECK: [[WithUnsignedIntegerSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([27 x i8]* [[WithUnsignedIntegerMeth]]
// CHECK: [[stringWithUTF8StringMeth:@".*"]] = internal global [22 x i8] c"stringWithUTF8String:\00"
-// CHECK: [[stringWithUTF8StringSEL:@".*"]] = internal global i8* getelementptr inbounds ([22 x i8]* [[stringWithUTF8StringMeth]]
+// CHECK: [[stringWithUTF8StringSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([22 x i8]* [[stringWithUTF8StringMeth]]
int main() {
// CHECK: load i8** [[WithIntSEL]]
diff --git a/test/CodeGenObjC/catch-lexical-block.m b/test/CodeGenObjC/catch-lexical-block.m
index f4a6a22..618d3a2 100644
--- a/test/CodeGenObjC/catch-lexical-block.m
+++ b/test/CodeGenObjC/catch-lexical-block.m
@@ -7,10 +7,9 @@ void f0() {
}
}
-// We should have 4 lexical blocks here at the moment, including one
+// We should have 3 lexical blocks here at the moment, including one
// for the catch block.
// CHECK: lexical_block
// CHECK: lexical_block
-// CHECK: lexical_block
// CHECK: auto_variable
// CHECK: lexical_block
diff --git a/test/CodeGenObjC/complex-double-abi.m b/test/CodeGenObjC/complex-double-abi.m
index 08246d5..6353520 100644
--- a/test/CodeGenObjC/complex-double-abi.m
+++ b/test/CodeGenObjC/complex-double-abi.m
@@ -9,8 +9,7 @@ double _Complex foo(CNumber *x) {
return [x sum];
}
-// CHECK: [[T4:%.*]] = phi double [ 0.000000e+00, [[NULLINIT:%.*]] ], [ [[R1:%.*]], [[MSGCALL:%.*]] ]
-// CHECK: [[T5:%.*]] = phi double [ 0.000000e+00, [[NULLINIT:%.*]] ], [ [[I1:%.*]], [[MSGCALL:%.*]] ]
-
-// CHECK: store double [[T4]]
-// CHECK: store double [[T5]]
+// CHECK: [[R:%.*]] = phi double [ [[R1:%.*]], [[MSGCALL:%.*]] ], [ 0.000000e+00, [[NULLINIT:%.*]] ]
+// CHECK-NEXT: [[I:%.*]] = phi double [ [[I1:%.*]], [[MSGCALL]] ], [ 0.000000e+00, [[NULLINIT]] ]
+// CHECK: store double [[R]]
+// CHECK: store double [[I]]
diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m
new file mode 100644
index 0000000..0316013
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-block-captured-self.m
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fblocks -g -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
+//
+// Test that debug location is generated for a captured "self" inside
+// a block.
+//
+// This test is split into two parts, this one for the frontend, and
+// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to
+// ensure that DW_AT_location is generated for the captured self.
+@class T;
+@interface S
+@end
+@interface Mode
+-(int) count;
+@end
+@interface Context
+@end
+@interface ViewController
+@property (nonatomic, readwrite, strong) Context *context;
+@end
+typedef enum {
+ Unknown = 0,
+} State;
+@interface Main : ViewController
+{
+ T * t1;
+ T * t2;
+}
+@property(readwrite, nonatomic) State state;
+@end
+@implementation Main
+- (id) initWithContext:(Context *) context
+{
+ t1 = [self.context withBlock:^(id obj){
+ id *mode1;
+ t2 = [mode1 withBlock:^(id object){
+ Mode *mode2 = object;
+ if ([mode2 count] != 0) {
+ self.state = 0;
+ }
+ }];
+ }];
+}
+@end
+// The important part of this test is that there is a dbg.value
+// intrinsic associated with the implicit .block_descriptor argument
+// of the block. We also test that this value gets alloca'd, so the
+// register llocator won't accidentally kill it.
+
+// outer block:
+// CHECK: define internal void {{.*}}_block_invoke{{.*}}
+
+// inner block:
+// CHECK: define internal void {{.*}}_block_invoke{{.*}}
+// CHECK: %[[MEM1:.*]] = alloca i8*, align 8
+// CHECK-NEXT: %[[MEM2:.*]] = alloca i8*, align 8
+// CHECK: store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8
+// CHECK: %[[TMP0:.*]] = load i8** %[[MEM1]]
+// CHECK: call void @llvm.dbg.value(metadata !{i8* %[[TMP0]]}, i64 0, metadata ![[BDMD:[0-9]+]])
+// CHECK: call void @llvm.dbg.declare(metadata !{i8* [[BLOCK_DESC]]}, metadata ![[BDMD:[0-9]+]])
+// CHECK: %[[TMP1:.*]] = bitcast
+// CHECK-NEXT: store
+// CHECK-NEXT: %[[TMP2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[TMP1]]
+// CHECK: call void @llvm.dbg.declare(metadata !{<{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** {{.*}}}, metadata ![[SELF:.*]])
+// make sure we are still in the same function
+// CHECK: define {{.*}}__copy_helper_block_
+// Metadata
+// CHECK: ![[MAIN:.*]] = {{.*}}!"Main"{{.*}}DW_TAG_structure_type{{.*}}line 23
+// CHECK: ![[PMAIN:.*]] = {{.*}}![[MAIN]]} ; [ DW_TAG_pointer_type ]{{.*}}from Main
+// CHECK: ![[BDMD]] = metadata {{.*}}.block_descriptor
+// CHECK: ![[SELF]] = {{.*}}![[PMAIN]]{{.*}}[ DW_TAG_auto_variable ] [self] [line 40]
diff --git a/test/CodeGenObjC/debug-info-block-helper.m b/test/CodeGenObjC/debug-info-block-helper.m
index cf8c2a2..49c8c5d 100644
--- a/test/CodeGenObjC/debug-info-block-helper.m
+++ b/test/CodeGenObjC/debug-info-block-helper.m
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s -o - | FileCheck %s
extern void foo(void(^)(void));
-// CHECK: metadata !{i32 786478, i32 0, metadata !27, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !27, i32 24, metadata !37, i1 true, i1 true, i32 0, i32 0, null, i32 0, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !5, i32 24} ; [ DW_TAG_subprogram ]
+// CHECK: [ DW_TAG_subprogram ] {{.*}} [__destroy_helper_block_]
@interface NSObject {
struct objc_object *isa;
diff --git a/test/CodeGenObjC/debug-info-block-line.m b/test/CodeGenObjC/debug-info-block-line.m
new file mode 100644
index 0000000..c913a97
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-block-line.m
@@ -0,0 +1,89 @@
+// REQUIRES: x86-64-registered-target
+// RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-default-synthesize-properties -fobjc-arc -O0 -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+// rdar://11562117
+typedef unsigned int NSUInteger;
+typedef long NSInteger;
+typedef signed char BOOL;
+
+#define nil ((void*) 0)
+#define YES ((BOOL)1)
+#define NO ((BOOL)0)
+
+@interface NSObject
+- (id)init;
+@end
+
+@interface NSError : NSObject
+@end
+
+@interface NSString : NSObject
+@end
+
+@interface NSString (NSStringExtensionMethods)
+- (void)enumerateLinesUsingBlock:(void (^)(NSString *line, BOOL *stop))block;
+@end
+
+@interface NSData : NSObject
+@end
+
+@interface NSData (ASBase64)
+- (NSString *)encodedString:(NSInteger)position;
+- (NSData *)compressedData;
+@end
+
+typedef void (^TDataCompletionBlock)(NSData *data, NSError *error);
+@interface TMap : NSObject
+- (NSString *)identifier;
+- (NSString *)name;
++ (TMap *)mapForID:(NSString *)identifier;
+- (void)dataWithCompletionBlock:(TDataCompletionBlock)block;
+@end
+
+typedef enum : NSUInteger {
+ TOK = 100,
+ TError = 125,
+} TResponseCode;
+
+@interface TConnection : NSObject
+- (void)sendString:(NSString *)string;
+- (void)sendFormat:(NSString *)format, ...;
+- (void)sendResponseCode:(TResponseCode)responseCode dataFollows:(BOOL)flag
+ format:(NSString *)format, ...;
+@end
+
+@interface TServer : NSObject
+@end
+
+@implementation TServer
+- (void)serverConnection:(TConnection *)connection getCommand:(NSString *)str
+{
+ NSString *mapID = nil;
+ TMap *map = [TMap mapForID:mapID];
+// Make sure we do not map code generated for the block to the above line.
+// CHECK: define internal void @"__39-[TServer serverConnection:getCommand:]_block_invoke"
+// CHECK: call void @objc_storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) [[NUW:#[0-9]+]]
+// CHECK: call void @objc_storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) [[NUW]]
+// CHECK: bitcast %5** [[TMP:%.*]] to i8**
+// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) [[NUW]], !dbg ![[MD1:.*]]
+// CHECK: bitcast %4** [[TMP:%.*]] to i8**
+// CHECK: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) [[NUW]], !dbg ![[MD1]]
+// CHECK-NEXT: ret
+// CHECK: attributes [[NUW]] = { nounwind }
+// CHECK: ![[MD1]] = metadata !{i32 87
+ [map dataWithCompletionBlock:^(NSData *data, NSError *error) {
+ if (data) {
+ NSString *encoded = [[data compressedData] encodedString:18];
+ [connection sendResponseCode:TOK dataFollows:YES
+ format:@"Sending \"%@\" (%@)", [map name], [map identifier]];
+ [encoded enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
+ [connection sendFormat:@"%@\r\n", line];
+ }];
+ [connection sendString:@".\r\n"];
+ } else {
+ [connection sendResponseCode:TError dataFollows:NO
+ format:@"Failed \"%@\" (%@)", [map name], [map identifier]];
+ }
+ }];
+}
+@end
diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m
index 71ae8a6..f50ddf0 100644
--- a/test/CodeGenObjC/debug-info-blocks.m
+++ b/test/CodeGenObjC/debug-info-blocks.m
@@ -1,9 +1,17 @@
-// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 -masm-verbose -S -fblocks -g -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed %s -o - | FileCheck %s
-
-//Radar 9279956
-//CHECK: ## DW_OP_deref
-//CHECK-NEXT: ## DW_OP_plus_uconst
+// RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed %s -o - | FileCheck %s
+
+// rdar://problem/9279956
+// Test that we generate the proper debug location for a captured self.
+// The second half of this patch is in llvm/tests/DebugInfo/debug-info-blocks.ll
+
+// CHECK: define {{.*}}_block_invoke
+// CHECK: %[[BLOCK:.*]] = bitcast i8* %.block_descriptor to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>*, !dbg
+// CHECK-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA:.*]], align
+// CHECK-NEXT: getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], i32 0, i32 5
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata !{<{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]]}, metadata ![[SELF:[0-9]+]])
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata !{%1** %d}, metadata ![[D:[0-9]+]])
+// CHECK: ![[SELF]] = {{.*}} [ DW_TAG_auto_variable ] [self] [line 52]
+// CHECK: ![[D]] = {{.*}} [d] [line 50]
typedef unsigned int NSUInteger;
diff --git a/test/CodeGenObjC/debug-info-fwddecl.m b/test/CodeGenObjC/debug-info-fwddecl.m
index 8f2860c..b41c485 100644
--- a/test/CodeGenObjC/debug-info-fwddecl.m
+++ b/test/CodeGenObjC/debug-info-fwddecl.m
@@ -2,4 +2,4 @@
@class ForwardObjcClass;
ForwardObjcClass *ptr = 0;
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"ForwardObjcClass", metadata !{{.*}}, i32 2, i64 0, i64 0, i32 0, i32 4, null, null, i32 16} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [ForwardObjcClass] [line 2, size 0, align 0, offset 0] [fwd]
diff --git a/test/CodeGenObjC/debug-info-id-with-protocol.m b/test/CodeGenObjC/debug-info-id-with-protocol.m
new file mode 100644
index 0000000..db1a3ef
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-id-with-protocol.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-default-synthesize-properties -emit-llvm -g %s -o - | FileCheck %s
+__attribute((objc_root_class)) @interface NSObject {
+ id isa;
+}
++ (id)alloc;
+- (id)init;
+- (id)retain;
+@end
+
+void NSLog(id, ...);
+
+@protocol MyProtocol
+
+-(const char *)hello;
+
+@end
+
+@interface MyClass : NSObject {
+}
+
+@property (nonatomic, assign) id <MyProtocol> bad_carrier;
+@property (nonatomic, assign) id good_carrier;
+
+@end
+
+@implementation MyClass
+@end
+
+int main()
+{
+ @autoreleasepool
+ {
+ MyClass *my_class = [MyClass alloc];
+ NSLog(@"%p\n", my_class.bad_carrier);
+ NSLog(@"%p\n", my_class.good_carrier);
+ }
+}
+// Verify that the debug type for both variables is 'id'.
+// CHECK: metadata !{i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata !"bad_carrier", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata ![[IDTYPE:[0-9]+]], i32 0, i32 0} ; [ DW_TAG_arg_variable ] [bad_carrier] [line 21]
+// CHECK: metadata !{i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata !"good_carrier", metadata !{{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{.*}}[[IDTYPE]], i32 0, i32 0} ; [ DW_TAG_arg_variable ] [good_carrier] [line 22]
+// CHECK !{{.*}}[[IDTYPE]] = metadata !{i32 {{[0-9]+}}, null, metadata !"id", metadata !{{[0-9]+}}, i32 !{{[0-9]+}}, i64 0, i64 0, i64 0, i32 0, metadata !{{[0-9]+}}} ; [ DW_TAG_typedef ] [id]
diff --git a/test/CodeGenObjC/debug-info-impl.m b/test/CodeGenObjC/debug-info-impl.m
index a8450dd..8991a88 100644
--- a/test/CodeGenObjC/debug-info-impl.m
+++ b/test/CodeGenObjC/debug-info-impl.m
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -S -emit-llvm %s -o - | FileCheck %s
-// CHECK: metadata !{i32 {{.*}}, metadata {{.*}}, metadata !"Circle", metadata {{.*}}, i32 11, i64 64, i64 64, i32 0, i32 512, null, metadata {{.*}}, i32 16, i32 0, i32 0} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [Circle] [line 11,
@interface NSObject {
struct objc_object *isa;
}
diff --git a/test/CodeGenObjC/debug-info-ivars-extension.m b/test/CodeGenObjC/debug-info-ivars-extension.m
new file mode 100644
index 0000000..e43b598
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-ivars-extension.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
+
+// Make sure we generate debug symbols for ivars added by a class extension.
+
+@interface I
+{
+ @public int a;
+}
+@end
+
+void foo(I* pi) {
+ // poking into pi for primary class ivars.
+ int _a = pi->a;
+}
+
+@interface I()
+{
+ @public int b;
+}
+@end
+
+void gorf (I* pg) {
+ // poking into pg for ivars for class extension
+ int _b = pg->b;
+}
+
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [I]
+// Check for "a".
+// CHECK: {{.*}} [ DW_TAG_member ] [a] [line 7, size 32, align 32, offset 0] [from int]
+// Make sure we don't output the same type twice.
+// CHECK-NOT: {{.*}} [ DW_TAG_structure_type ] [I]
+// Check for "b".
+// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 18, size 32, align 32, offset 0] [from int]
diff --git a/test/CodeGenObjC/debug-info-ivars-indirect.m b/test/CodeGenObjC/debug-info-ivars-indirect.m
new file mode 100644
index 0000000..1548ddd
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-ivars-indirect.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
+
+// Make sure we generate debug symbols for an indirectly referenced
+// extension to an interface.
+
+@interface I
+{
+ @public int a;
+}
+@end
+
+void foo(I* pi) {
+ int _a = pi->a;
+}
+
+// another layer of indirection
+struct S
+{
+ I* i;
+};
+
+@interface I()
+{
+ @public int b;
+}
+@end
+
+void gorf (struct S* s) {
+ int _b = s->i->b;
+}
+
+// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 24, size 32, align 32, offset 0] [from int]
diff --git a/test/CodeGenObjC/debug-info-ivars-private.m b/test/CodeGenObjC/debug-info-ivars-private.m
new file mode 100644
index 0000000..8505da1
--- /dev/null
+++ b/test/CodeGenObjC/debug-info-ivars-private.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
+
+// Debug symbols for private ivars. This test ensures that we are
+// generating debug info for ivars added by the implementation.
+__attribute((objc_root_class)) @interface NSObject {
+ id isa;
+}
+@end
+
+@protocol Protocol
+@end
+
+@interface Delegate : NSObject<Protocol> {
+ @protected int foo;
+}
+@end
+
+@interface Delegate(NSObject)
+- (void)f;
+@end
+
+@implementation Delegate(NSObject)
+- (void)f { return; }
+@end
+
+@implementation Delegate {
+ int bar;
+}
+
+- (void)g:(NSObject*) anObject {
+ bar = foo;
+}
+@end
+
+// CHECK: {{.*}} [ DW_TAG_member ] [foo] [line 14, size 32, align 32, offset 0] [protected] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [bar] [line 27, size 32, align 32, offset 0] [private] [from int]
diff --git a/test/CodeGenObjC/debug-info-ivars.m b/test/CodeGenObjC/debug-info-ivars.m
index 24705e1a..a0f2963 100644
--- a/test/CodeGenObjC/debug-info-ivars.m
+++ b/test/CodeGenObjC/debug-info-ivars.m
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
__attribute((objc_root_class)) @interface NSObject {
- id isa;
+ id isa;
}
@end
@@ -10,15 +10,15 @@ __attribute((objc_root_class)) @interface NSObject {
int i;
unsigned flag_1 : 9;
unsigned flag_2 : 9;
- unsigned : 1;
- unsigned flag_3 : 9;
+ unsigned : 1;
+ unsigned flag_3 : 9;
}
@end
@implementation BaseClass
@end
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"i", metadata !{{[0-9]*}}, i32 10, i64 32, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [i] [line 10, size 32, align 32, offset 0] [protected] [from int]
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_1", metadata !{{[0-9]*}}, i32 11, i64 9, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_1] [line 11, size 9, align 32, offset 0] [protected] [from unsigned int]
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_2", metadata !{{[0-9]*}}, i32 12, i64 9, i64 32, i64 1, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_2] [line 12, size 9, align 32, offset 1] [protected] [from unsigned int]
-// CHECK: metadata !{i32 786445, metadata !{{[0-9]*}}, metadata !"flag_3", metadata !{{[0-9]*}}, i32 14, i64 9, i64 32, i64 3, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [flag_3] [line 14, size 9, align 32, offset 3] [protected] [from unsigned int] \ No newline at end of file
+// CHECK: {{.*}} [ DW_TAG_member ] [i] [line 10, size 32, align 32, offset 0] [protected] [from int]
+// CHECK: {{.*}} [ DW_TAG_member ] [flag_1] [line 11, size 9, align 32, offset 0] [protected] [from unsigned int]
+// CHECK: {{.*}} [ DW_TAG_member ] [flag_2] [line 12, size 9, align 32, offset 1] [protected] [from unsigned int]
+// CHECK: {{.*}} [ DW_TAG_member ] [flag_3] [line 14, size 9, align 32, offset 3] [protected] [from unsigned int]
diff --git a/test/CodeGenObjC/debug-info-property3.m b/test/CodeGenObjC/debug-info-property3.m
index f96ec44..f63e744 100644
--- a/test/CodeGenObjC/debug-info-property3.m
+++ b/test/CodeGenObjC/debug-info-property3.m
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -S -emit-llvm -g %s -o - | FileCheck %s
-// CHECK: metadata !"p1", metadata !6, i32 5, metadata !"", metadata !"", i32 2316, metadata !9} ; [ DW_TAG_APPLE_property ]
+// CHECK: metadata !"p1", metadata !{{.*}}, i32 5, metadata !"", metadata !"", i32 2316, metadata !{{.*}}} ; [ DW_TAG_APPLE_property ]
@interface I1
@property int p1;
@end
diff --git a/test/CodeGenObjC/debug-info-pubtypes.m b/test/CodeGenObjC/debug-info-pubtypes.m
index 91d9cd1..8b7dfad 100644
--- a/test/CodeGenObjC/debug-info-pubtypes.m
+++ b/test/CodeGenObjC/debug-info-pubtypes.m
@@ -1,7 +1,7 @@
// REQUIRES: x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -emit-llvm %s -o - | FileCheck %s
-// CHECK: !5 = metadata !{i32 {{.*}}, metadata !6, metadata !"H", metadata !6, i32 6, i64 0, i64 8, i32 0, i32 512, null, metadata !2, i32 16, i32 0, i32 0} ; [ DW_TAG_structure_type ]
+// CHECK: {{.*}} [ DW_TAG_structure_type ] [H] [line 6,
@interface H
-(void) foo;
diff --git a/test/CodeGenObjC/debug-info-self.m b/test/CodeGenObjC/debug-info-self.m
index 9f23435..7803467 100644
--- a/test/CodeGenObjC/debug-info-self.m
+++ b/test/CodeGenObjC/debug-info-self.m
@@ -2,11 +2,6 @@
// self and _cmd are marked as DW_AT_artificial.
// myarg is not marked as DW_AT_artificial.
-// CHECK: metadata !{i32 {{.*}}, metadata !9, metadata !"self", metadata !15, i32 16777232, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [self] [line 16]
-// CHECK: metadata !{i32 {{.*}}, metadata !9, metadata !"_cmd", metadata !15, i32 33554448, metadata !33, i32 64, i32 0} ; [ DW_TAG_arg_variable ] [_cmd] [line 16]
-// CHECK: metadata !{i32 {{.*}}, metadata !9, metadata !"myarg", metadata !6, i32 50331664, metadata !24, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [myarg] [line 16]
-
-
@interface MyClass {
}
- (id)init:(int) myarg;
@@ -18,3 +13,11 @@
return self;
}
@end
+
+// It's weird that the first two parameters are recorded as being in a
+// different, ("<unknown>") file compared to the third parameter which is 'in'
+// the actual source file. (see the metadata node after the arg name in each
+// line)
+// CHECK: metadata !{i32 {{.*}}, metadata ![[CTOR:.*]], metadata !"self", metadata ![[UNKFILE:.*]], i32 16777227, metadata !{{.*}}, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [self] [line 11]
+// CHECK: metadata !{i32 {{.*}}, metadata ![[CTOR]], metadata !"_cmd", metadata ![[UNKFILE]], i32 33554443, metadata !{{.*}}, i32 64, i32 0} ; [ DW_TAG_arg_variable ] [_cmd] [line 11]
+// CHECK: metadata !{i32 {{.*}}, metadata ![[CTOR]], metadata !"myarg", metadata !{{.*}}, i32 50331659, metadata !{{.*}}, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [myarg] [line 11]
diff --git a/test/CodeGenObjC/debug-info-static-var.m b/test/CodeGenObjC/debug-info-static-var.m
index 8602ffb..2c10d59 100644
--- a/test/CodeGenObjC/debug-info-static-var.m
+++ b/test/CodeGenObjC/debug-info-static-var.m
@@ -1,14 +1,8 @@
-// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 -g -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -S -masm-verbose -o - %s | FileCheck %s
+// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s
// Radar 8801045
// Do not emit AT_MIPS_linkage_name for static variable i
-// CHECK: Lset6 = Lstring3-Lsection_str ## DW_AT_name
-// CHECK-NEXT: .long Lset6
-// CHECK-NEXT: DW_AT_type
-// CHECK-NEXT: DW_AT_decl_file
-// CHECK-NEXT: DW_AT_decl_line
-// CHECK-NEXT: DW_AT_location
+// CHECK: metadata !"i", metadata !"i", metadata !""
@interface A {
}
diff --git a/test/CodeGenObjC/debug-info-synthesis.m b/test/CodeGenObjC/debug-info-synthesis.m
index bf8e6d1..1bf7576 100644
--- a/test/CodeGenObjC/debug-info-synthesis.m
+++ b/test/CodeGenObjC/debug-info-synthesis.m
@@ -30,5 +30,5 @@ int main(int argc, char *argv[]) {
}
}
-// CHECK: !7 = metadata !{i32 {{.*}}, metadata !"./foo.h"
-// CHECK: !29 = metadata !{i32 {{.*}}, i32 0, metadata !7, metadata !"-[Foo dict]", metadata !"-[Foo dict]", metadata !"", metadata !7, i32 8, metadata !30, i1 true, i1 true, i32 0, i32 0, null, i32 320, i1 false, %1* (%0*, i8*)* @"\01-[Foo dict]", null, null, metadata !1, i32 8} ; [ DW_TAG_subprogram ]
+// CHECK: ![[FILE:.*]] = {{.*}}[ DW_TAG_file_type ] [{{.*}}/foo.h]
+// CHECK: metadata ![[FILE]], {{.*}} ; [ DW_TAG_subprogram ] [line 8] [local] [def] [-[Foo dict]]
diff --git a/test/CodeGenObjC/encode-test-6.m b/test/CodeGenObjC/encode-test-6.m
index 10681db..b7feb14 100644
--- a/test/CodeGenObjC/encode-test-6.m
+++ b/test/CodeGenObjC/encode-test-6.m
@@ -17,3 +17,21 @@ typedef struct {} Z;
// CHECK: internal global [14 x i8] c"v16@0:8{?=}16
// CHECK: internal global [26 x i8] c"v32@0:8{?=}16*16{?=}24d24
+
+// rdar://13190095
+@interface NSObject @end
+
+@class BABugExample;
+typedef BABugExample BABugExampleRedefinition;
+
+@interface BABugExample : NSObject {
+ BABugExampleRedefinition *_property; // .asciz "^{BABugExample=^{BABugExample}}"
+}
+@property (copy) BABugExampleRedefinition *property;
+@end
+
+@implementation BABugExample
+@synthesize property = _property;
+@end
+
+// CHECK: internal global [24 x i8] c"^{BABugExample=@}16
diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m
index 3780068..e8d6541 100644
--- a/test/CodeGenObjC/encode-test.m
+++ b/test/CodeGenObjC/encode-test.m
@@ -165,3 +165,7 @@ const char g10[] = @encode(struct f);
// rdar://9622422
// CHECK: @g11 = constant [2 x i8] c"v\00"
const char g11[] = @encode(void);
+
+// PR14628
+// CHECK: @g12 = constant [3 x i8] c"Ai\00"
+const char g12[] = @encode(_Atomic(int));
diff --git a/test/CodeGenObjC/exceptions.m b/test/CodeGenObjC/exceptions.m
index 551e67c..408b94d 100644
--- a/test/CodeGenObjC/exceptions.m
+++ b/test/CodeGenObjC/exceptions.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fobjc-exceptions -O2 -o - %s | FileCheck %s
//
// <rdar://problem/7471679> [irgen] [eh] Exception code built with clang (x86_64) crashes
@@ -28,7 +28,7 @@ void f1() {
// CHECK: call void asm sideeffect "", "*m"
// CHECK-NEXT: call void @foo()
foo();
- // CHECK-NEXT: call void @objc_exception_try_exit
+ // CHECK: call void @objc_exception_try_exit
// CHECK: call void asm sideeffect "", "=*m"
} @finally {
diff --git a/test/CodeGenObjC/extended-block-signature-encode.m b/test/CodeGenObjC/extended-block-signature-encode.m
new file mode 100644
index 0000000..a380856
--- /dev/null
+++ b/test/CodeGenObjC/extended-block-signature-encode.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -fencode-extended-block-signature -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s -check-prefix=BRIEF
+// rdar://12109031
+
+@class NSString, NSArray;
+
+typedef NSString*(^BBB)(NSArray*);
+
+int main ()
+{
+ BBB b1;
+ ^(BBB arg1, double arg2){ return b1; }(0, 3.14);
+}
+// CHECK: @{{.*}} = private unnamed_addr constant [64 x i8] c"@?<@\22NSString\22@?@\22NSArray\22>24@?0@?<@\22NSString\22@?@\22NSArray\22>8d16\00"
+// CHECK-BRIEF: @{{.*}} = private unnamed_addr constant [14 x i8] c"@?24@?0@?8d16\00"
diff --git a/test/CodeGenObjC/externally-initialized-selectors.m b/test/CodeGenObjC/externally-initialized-selectors.m
new file mode 100644
index 0000000..87a7c04
--- /dev/null
+++ b/test/CodeGenObjC/externally-initialized-selectors.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -cc1 -fobjc-runtime=macosx-fragile-10.5 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -cc1 -o - -emit-llvm %s | FileCheck %s
+
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global
+
+void test(id x) {
+ [x doSomething];
+}
diff --git a/test/CodeGenObjC/gc.m b/test/CodeGenObjC/gc.m
index b672181..ce2611e 100644
--- a/test/CodeGenObjC/gc.m
+++ b/test/CodeGenObjC/gc.m
@@ -9,6 +9,8 @@ void test0(void) {
// CHECK-NEXT: store i8* [[T0]], i8** [[X:%.*]], align 8
// CHECK-NEXT: call i8* @test0_helper()
// CHECK-NEXT: [[T0:%.*]] = load i8** [[X]], align 8
- // CHECK-NEXT: call void asm sideeffect "", "r"(i8* [[T0]]) nounwind
+ // CHECK-NEXT: call void asm sideeffect "", "r"(i8* [[T0]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: ret void
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/gnu-exceptions.m b/test/CodeGenObjC/gnu-exceptions.m
index b7d0adb..7aa9709 100644
--- a/test/CodeGenObjC/gnu-exceptions.m
+++ b/test/CodeGenObjC/gnu-exceptions.m
@@ -1,11 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fexceptions -fobjc-exceptions -fobjc-runtime=gcc -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -emit-llvm -fexceptions -fobjc-exceptions -fobjc-runtime=gnustep-1.7 -o - %s | FileCheck -check-prefix=NEW-ABI %s
void opaque(void);
void log(int i);
@class C;
-// CHECK: define void @test0() {
+// CHECK: define void @test0() [[TF:#[0-9]+]] {
void test0() {
@try {
// CHECK: invoke void @opaque()
@@ -21,9 +22,13 @@ void test0() {
// CHECK: call void @log(i32 0)
// CHECK: resume
+ // NEW-ABI: objc_begin_catch
+ // NEW-ABI: objc_end_catch
log(0);
}
log(1);
}
+
+// CHECK: attributes [[TF]] = { "{{.*}} }
diff --git a/test/CodeGenObjC/interface-layout-64.m b/test/CodeGenObjC/interface-layout-64.m
index 16361a2..4b41cf8 100644
--- a/test/CodeGenObjC/interface-layout-64.m
+++ b/test/CodeGenObjC/interface-layout-64.m
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
-// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
// CHECK: @"OBJC_IVAR_$_I3._iv2" = global i64 8, section "__DATA, __objc_ivar", align 8
// CHECK: @"OBJC_IVAR_$_I3._iv3" = global i64 12, section "__DATA, __objc_ivar", align 8
diff --git a/test/CodeGenObjC/ivar-invariant.m b/test/CodeGenObjC/ivar-invariant.m
new file mode 100644
index 0000000..7cafee7
--- /dev/null
+++ b/test/CodeGenObjC/ivar-invariant.m
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck %s
+
+@interface NSObject
++ (id) new;
+- (id) init;
+@end
+
+@interface Base : NSObject @end
+
+// @implementation Base
+// {
+// int dummy;
+// }
+// @end
+
+@interface Derived : Base
+{
+ @public int member;
+}
+@end
+
+@implementation Derived
+- (id) init
+{
+ self = [super init];
+ member = 42;
+ return self;
+}
+@end
+
+// CHECK: define internal i8* @"\01-[Derived init]"
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Derived.member", !invariant.load
+
+void * variant_load_1(int i) {
+ void *ptr;
+ while (i--) {
+ Derived *d = [Derived new];
+ ptr = &d->member;
+ }
+ return ptr;
+}
+
+// CHECK: define i8* @variant_load_1(i32 %i)
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Derived.member"{{$}}
+
+@interface Container : Derived @end
+@implementation Container
+- (void *) invariant_load_1
+{
+ return &self->member;
+}
+@end
+
+// CHECK: define internal i8* @"\01-[Container invariant_load_1]"
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Derived.member", !invariant.load
+
+@interface ForBlock
+{
+@public
+ id foo;
+}
+@end
+
+// CHECK: define internal i8* @block_block_invoke
+// CHECK: load i64* @"OBJC_IVAR_$_ForBlock.foo"
+id (^block)(ForBlock*) = ^(ForBlock* a) {
+ return a->foo;
+};
diff --git a/test/CodeGenObjC/metadata-symbols-32.m b/test/CodeGenObjC/metadata-symbols-32.m
index 1df1560..e8d2512 100644
--- a/test/CodeGenObjC/metadata-symbols-32.m
+++ b/test/CodeGenObjC/metadata-symbols-32.m
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s
-// RUNX: llvm-gcc -m32 -emit-llvm -S -o %t %s &&
// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*section "__OBJC,__category,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
@@ -24,7 +23,7 @@
// RUN: grep '@"\\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global .*section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global .*section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_PROTOCOL_P" = internal global .*section "__OBJC,__protocol,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_[0-9]*" = internal global .*section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4' %t
+// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_[0-9]*" = internal externally_initialized global .*section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_SYMBOLS" = internal global .*section "__OBJC,__symbols,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01l_OBJC_$_PROP_LIST_A" = internal global .*section "__OBJC,__property,regular,no_dead_strip", align 4' %t
// RUN: grep "\.lazy_reference \.objc_class_name_J0" %t
diff --git a/test/CodeGenObjC/metadata-symbols-64.m b/test/CodeGenObjC/metadata-symbols-64.m
index 57f5d50..27017b7 100644
--- a/test/CodeGenObjC/metadata-symbols-64.m
+++ b/test/CodeGenObjC/metadata-symbols-64.m
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o %t %s
-// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
// RUN: grep '@"OBJC_CLASS_$_A" = global' %t
// RUN: grep '@"OBJC_CLASS_$_B" = external global' %t
@@ -13,7 +12,7 @@
// RUN: grep '@"\\01L_OBJC_METH_VAR_NAME_[0-9]*" = internal global .* section "__TEXT,__objc_methname,cstring_literals", align 1' %t
// RUN: grep '@"\\01L_OBJC_METH_VAR_TYPE_[0-9]*" = internal global .* section "__TEXT,__objc_methtype,cstring_literals", align 1' %t
// RUN: grep '@"\\01L_OBJC_PROP_NAME_ATTR_[0-9]*" = internal global .* section "__TEXT,__cstring,cstring_literals", align 1' %t
-// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_*" = internal global .* section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"' %t
+// RUN: grep '@"\\01L_OBJC_SELECTOR_REFERENCES_*" = internal externally_initialized global .* section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"' %t
// RUN: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
// RUN: grep '@"\\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
// RUN: grep '@"\\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global .* section "__DATA, __objc_const", align 8' %t
diff --git a/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m b/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m
index f1e02dd..bb3a20b 100644
--- a/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m
+++ b/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin -O0 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-i386 %s
+// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
+// RUN: FileCheck --input-file=%t-64.layout %s
+// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
+// RUN: FileCheck -check-prefix=CHECK-i386 --input-file=%t-32.layout %s
+// rdar://12184410
// rdar://12184410
void x(id y) {}
@@ -16,25 +19,25 @@ void f() {
__block id byref_bab = (id)0;
__block id bl_var1;
-// block variable layout: BL_UNRETAINED:1, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"`\00"
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"`\00"
+// block variable layout: BL_STRONG:1, BL_OPERATOR:0
+// CHECK: Inline instruction for block variable layout: 0x0100
+// CHECK-i386: Inline instruction for block variable layout: 0x0100
void (^b)() = ^{
x(bar);
};
-// block variable layout: BL_UNRETAINED:2, BL_BYREF:1, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"a@\00"
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"a@\00"
+// block variable layout: BL_STRONG:2, BL_BYREF:1, BL_OPERATOR:0
+// CHECK: Inline instruction for block variable layout: 0x0210
+// CHECK-i386: Inline instruction for block variable layout: 0x0210
void (^c)() = ^{
x(bar);
x(baz);
byref_int = 1;
};
-// block variable layout: BL_UNRETAINED:2, BL_BYREF:3, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00
+// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
+// CHECK: Inline instruction for block variable layout: 0x0230
+// CHECK-i386: Inline instruction for block variable layout: 0x0230
void (^d)() = ^{
x(bar);
x(baz);
@@ -43,9 +46,9 @@ void f() {
byref_bab = 0;
};
-// block variable layout: BL_UNRETAINED:2, BL_BYREF:3, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00"
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00"
+// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
+// CHECK: Inline instruction for block variable layout: 0x0230
+// CHECK-i386: Inline instruction for block variable layout: 0x0230
id (^e)() = ^{
x(bar);
x(baz);
@@ -55,9 +58,8 @@ void f() {
return wid;
};
-// Inline instruction for block variable layout: 0x020
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 32 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 32 }
+// CHECK: Inline instruction for block variable layout: 0x020
+// CHECK-i386: Inline instruction for block variable layout: 0x020
void (^ii)() = ^{
byref_int = 1;
byref_bab = 0;
diff --git a/test/CodeGenObjC/non-lazy-classes.m b/test/CodeGenObjC/non-lazy-classes.m
index 5d82901..d95cb78d 100644
--- a/test/CodeGenObjC/non-lazy-classes.m
+++ b/test/CodeGenObjC/non-lazy-classes.m
@@ -1,4 +1,3 @@
-// RUNX: llvm-gcc -m64 -emit-llvm -S -o %t %s &&
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CLASS_$" = internal global \[1 x .*\] .*@"OBJC_CLASS_$_A".*, section "__DATA, __objc_nlclslist, regular, no_dead_strip", align 8' %t
// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CATEGORY_$" = internal global \[1 x .*\] .*@".01l_OBJC_$_CATEGORY_A_$_Cat".*, section "__DATA, __objc_nlcatlist, regular, no_dead_strip", align 8' %t
diff --git a/test/CodeGenObjC/nonlazy-msgSend.m b/test/CodeGenObjC/nonlazy-msgSend.m
index 7c349b2..0ae9f11 100644
--- a/test/CodeGenObjC/nonlazy-msgSend.m
+++ b/test/CodeGenObjC/nonlazy-msgSend.m
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s
-// RUN: grep -F 'declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind' %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o - | FileCheck %s
+// CHECK: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
void f0(id x) {
[x foo];
}
+
+// CHECK: attributes [[NLB]] = { nonlazybind }
diff --git a/test/CodeGenObjC/ns_consume_null_check.m b/test/CodeGenObjC/ns_consume_null_check.m
index a8e5acd..6a31a80 100644
--- a/test/CodeGenObjC/ns_consume_null_check.m
+++ b/test/CodeGenObjC/ns_consume_null_check.m
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-dispatch-method=mixed -o - %s | FileCheck %s
-// rdar://10444476
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-dispatch-method=mixed -fobjc-runtime-has-weak -fexceptions -o - %s | FileCheck %s
@interface NSObject
- (id) new;
@@ -7,26 +6,80 @@
@interface MyObject : NSObject
- (char)isEqual:(id) __attribute__((ns_consumed)) object;
+- (_Complex float) asComplexWithArg: (id) __attribute__((ns_consumed)) object;
@end
MyObject *x;
-void foo()
-{
- id obj = [NSObject new];
- [x isEqual : obj];
+// rdar://10444476
+void test0(void) {
+ id obj = [NSObject new];
+ [x isEqual : obj];
}
-
-// CHECK: [[TMP:%.*]] = alloca i8{{$}}
-// CHECK: [[FIVE:%.*]] = call i8* @objc_retain
+// CHECK: define void @test0()
+// CHECK: [[FIVE:%.*]] = call i8* @objc_retain
// CHECK-NEXT: [[SIX:%.*]] = bitcast
// CHECK-NEXT: [[SEVEN:%.*]] = icmp eq i8* [[SIX]], null
// CHECK-NEXT: br i1 [[SEVEN]], label [[NULLINIT:%.*]], label [[CALL_LABEL:%.*]]
-// CHECK: [[FN:%.*]] = load i8** getelementptr inbounds
+// CHECK: [[FN:%.*]] = load i8** getelementptr inbounds
// CHECK-NEXT: [[EIGHT:%.*]] = bitcast i8* [[FN]]
// CHECK-NEXT: [[CALL:%.*]] = call signext i8 [[EIGHT]]
-// CHECK-NEXT: store i8 [[CALL]], i8* [[TMP]]
// CHECK-NEXT: br label [[CONT:%.*]]
-// CHECK: call void @objc_release(i8* [[FIVE]]) nounwind
-// CHECK-NEXT: call void @llvm.memset
+// CHECK: call void @objc_release(i8* [[FIVE]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: br label [[CONT]]
+// CHECK: phi i8 [ [[CALL]], {{%.*}} ], [ 0, {{%.*}} ]
+
+// Ensure that we build PHIs correctly in the presence of cleanups.
+// rdar://12046763
+void test1(void) {
+ id obj = [NSObject new];
+ __weak id weakObj = obj;
+ _Complex float result = [x asComplexWithArg: obj];
+}
+// CHECK: define void @test1()
+// CHECK: [[OBJ:%.*]] = alloca i8*, align 8
+// CHECK-NEXT: [[WEAKOBJ:%.*]] = alloca i8*, align 8
+// CHECK-NEXT: [[RESULT:%.*]] = alloca { float, float }, align 4
+// Various initializations.
+// CHECK: [[T0:%.*]] = call i8* bitcast (
+// CHECK-NEXT: store i8* [[T0]], i8** [[OBJ]]
+// CHECK-NEXT: [[T0:%.*]] = load i8** [[OBJ]]
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAKOBJ]], i8* [[T0]]) [[NUW]]
+// Okay, start the message-send.
+// CHECK-NEXT: [[T0:%.*]] = load [[MYOBJECT:%.*]]** @x
+// CHECK-NEXT: [[ARG:%.*]] = load i8** [[OBJ]]
+// CHECK-NEXT: [[ARG_RETAINED:%.*]] = call i8* @objc_retain(i8* [[ARG]])
+// CHECK-NEXT: load i8** @
+// CHECK-NEXT: [[SELF:%.*]] = bitcast [[MYOBJECT]]* [[T0]] to i8*
+// Null check.
+// CHECK-NEXT: [[T0:%.*]] = icmp eq i8* [[SELF]], null
+// CHECK-NEXT: br i1 [[T0]], label [[FORNULL:%.*]], label [[FORCALL:%.*]]
+// Invoke and produce the return values.
+// CHECK: [[CALL:%.*]] = invoke <2 x float> bitcast
+// CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label {{%.*}}
+// CHECK: [[T0:%.*]] = bitcast { float, float }* [[COERCE:%.*]] to <2 x float>*
+// CHECK-NEXT: store <2 x float> [[CALL]], <2 x float>* [[T0]],
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }* [[COERCE]], i32 0, i32 0
+// CHECK-NEXT: [[REALCALL:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }* [[COERCE]], i32 0, i32 1
+// CHECK-NEXT: [[IMAGCALL:%.*]] = load float* [[T0]]
+// CHECK-NEXT: br label [[CONT:%.*]]{{$}}
+// Null path.
+// CHECK: call void @objc_release(i8* [[ARG_RETAINED]]) [[NUW]]
+// CHECK-NEXT: br label [[CONT]]
+// Join point.
+// CHECK: [[REAL:%.*]] = phi float [ [[REALCALL]], [[INVOKE_CONT]] ], [ 0.000000e+00, [[FORNULL]] ]
+// CHECK-NEXT: [[IMAG:%.*]] = phi float [ [[IMAGCALL]], [[INVOKE_CONT]] ], [ 0.000000e+00, [[FORNULL]] ]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }* [[RESULT]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds { float, float }* [[RESULT]], i32 0, i32 1
+// CHECK-NEXT: store float [[REAL]], float* [[T0]]
+// CHECK-NEXT: store float [[IMAG]], float* [[T1]]
+// Epilogue.
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[WEAKOBJ]]) [[NUW]]
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[OBJ]], i8* null) [[NUW]]
+// CHECK-NEXT: ret void
+// Cleanup.
+// CHECK: landingpad
+// CHECK: call void @objc_destroyWeak(i8** [[WEAKOBJ]]) [[NUW]]
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/objc-align.m b/test/CodeGenObjC/objc-align.m
index 324740c..1a9e882 100644
--- a/test/CodeGenObjC/objc-align.m
+++ b/test/CodeGenObjC/objc-align.m
@@ -1,6 +1,5 @@
// 32-bit
-// RUNX: llvm-gcc -m32 -emit-llvm -S -o %t %s &&
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s
// RUN: grep '@"\\01L_OBJC_CATEGORY_A_Cat" = internal global .*, section "__OBJC,__category,regular,no_dead_strip", align 4' %t
// RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
diff --git a/test/CodeGenObjC/objc-arc-container-subscripting.m b/test/CodeGenObjC/objc-arc-container-subscripting.m
index 71339c7..1824562 100644
--- a/test/CodeGenObjC/objc-arc-container-subscripting.m
+++ b/test/CodeGenObjC/objc-arc-container-subscripting.m
@@ -12,9 +12,10 @@ id func() {
}
// CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) nounwind
+// CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) [[NUW:#[0-9]+]]
// CHECK: [[ARRAY_CASTED:%.*]] = bitcast %0** {{%.*}} to i8**
// CHECK: call void @objc_storeStrong(i8** [[ARRAY_CASTED]], i8* null)
-// CHECK: [[EIGHT:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) nounwind
+// CHECK: [[EIGHT:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) [[NUW]]
// CHECK: ret i8* [[EIGHT]]
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/objc-literal-debugger-test.m b/test/CodeGenObjC/objc-literal-debugger-test.m
index 5f69fd5..d4043aa 100644
--- a/test/CodeGenObjC/objc-literal-debugger-test.m
+++ b/test/CodeGenObjC/objc-literal-debugger-test.m
@@ -50,4 +50,6 @@ int main() {
#endif
}
-// CHECK: declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
+// CHECK: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
+
+// CHECK: attributes [[NLB]] = { nonlazybind }
diff --git a/test/CodeGenObjC/objc-literal-tests.m b/test/CodeGenObjC/objc-literal-tests.m
index c513d49..c53ee64 100644
--- a/test/CodeGenObjC/objc-literal-tests.m
+++ b/test/CodeGenObjC/objc-literal-tests.m
@@ -53,7 +53,7 @@ typedef signed char BOOL;
id NSUserName();
-// CHECK: define i32 @main() nounwind
+// CHECK: define i32 @main() [[NUW:#[0-9]+]]
int main() {
// CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 97
NSNumber *aNumber = @'a';
@@ -93,3 +93,5 @@ extern void bar(foo a);
void baz(void) {
bar(^(void) { return YES; });
}
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGenObjC/optimized-setter.m b/test/CodeGenObjC/optimized-setter.m
index 6f5cfb1..7e0a1d7 100644
--- a/test/CodeGenObjC/optimized-setter.m
+++ b/test/CodeGenObjC/optimized-setter.m
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -emit-llvm -fobjc-runtime=macosx-10.8 -triple x86_64-apple-macosx10.8.0 -o - | FileCheck %s
// RUN: %clang_cc1 %s -emit-llvm -fobjc-runtime=ios-6.0.0 -triple x86_64-apple-ios6.0.0 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -fobjc-runtime=gnustep-1.7 -triple x86_64-unknown-freebsd -o - | FileCheck %s
// rdar://10179974
@interface I
diff --git a/test/CodeGenObjC/property.m b/test/CodeGenObjC/property.m
index aab7c73..6a43826 100644
--- a/test/CodeGenObjC/property.m
+++ b/test/CodeGenObjC/property.m
@@ -1,8 +1,5 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
-// PR13820
-// REQUIRES: LP64
-
// TODO: actually test most of this instead of just emitting it
int printf(const char *, ...);
diff --git a/test/CodeGenObjC/protocols-lazy.m b/test/CodeGenObjC/protocols-lazy.m
index 877d492..642f886 100644
--- a/test/CodeGenObjC/protocols-lazy.m
+++ b/test/CodeGenObjC/protocols-lazy.m
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -emit-llvm -triple i686-apple-darwin8 -fobjc-runtime=macosx-fragile-10.5 -o %t %s
-// RUNX: llvm-gcc -S -emit-llvm -o %t %s &&
// No object generated
// RUN: grep OBJC_PROTOCOL_P0 %t | count 0
diff --git a/test/CodeGenObjC/reorder-synthesized-ivars.m b/test/CodeGenObjC/reorder-synthesized-ivars.m
new file mode 100644
index 0000000..747265d
--- /dev/null
+++ b/test/CodeGenObjC/reorder-synthesized-ivars.m
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-default-synthesize-properties -emit-llvm -x objective-c %s -o - | FileCheck %s
+// rdar://13192366
+typedef signed char BOOL;
+@interface NSObject
+{
+ id isa;
+}
+@end
+
+@interface MyClass : NSObject
+
+@property (readwrite) BOOL boolean1;
+@property (readwrite, copy) id object1;
+@property (readwrite) BOOL boolean2;
+@property (readwrite, copy) id object2;
+@property (readwrite) BOOL boolean3;
+@property (readwrite, copy) id object3;
+@property (readwrite) BOOL boolean4;
+@property (readwrite, copy) id object4;
+@property (readwrite) BOOL boolean5;
+@property (readwrite, copy) id object5;
+@property (readwrite) BOOL boolean6;
+@property (readwrite, copy) id object6;
+@property (readwrite) BOOL boolean7;
+@property (readwrite) BOOL MyBool;
+@property (readwrite, copy) id object7;
+@property (readwrite) BOOL boolean8;
+@property (readwrite, copy) id object8;
+@property (readwrite) BOOL boolean9;
+@property (readwrite, copy) id object9;
+@end
+
+@implementation MyClass
+{
+ id MyIvar;
+ BOOL _MyBool;
+ char * pc;
+}
+@end
+
+// CHECK: @"{{.*}}" = internal global [10 x i8] c"_boolean1
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean2
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean3
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean4
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean5
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean6
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean7
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean8
+// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean9
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object1
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object2
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object3
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object4
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object5
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object6
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object7
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object8
+// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object9
OpenPOWER on IntegriCloud