aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenObjC
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenObjC')
-rw-r--r--test/CodeGenObjC/NSFastEnumeration.m16
-rw-r--r--test/CodeGenObjC/arc-arm.m2
-rw-r--r--test/CodeGenObjC/arc-bridged-cast.m8
-rw-r--r--test/CodeGenObjC/attr-exception.m8
-rw-r--r--test/CodeGenObjC/debug-info-block-captured-self.m72
-rw-r--r--test/CodeGenObjC/debug-info-blocks.m21
-rw-r--r--test/CodeGenObjC/dllstorage.m10
-rw-r--r--test/CodeGenObjC/ivar-layout-flexible-array.m28
-rw-r--r--test/CodeGenObjC/local-static-block.m11
-rw-r--r--test/CodeGenObjC/mangle-blocks.m6
-rw-r--r--test/CodeGenObjC/no-sanitize.m3
-rw-r--r--test/CodeGenObjC/noescape.m71
-rw-r--r--test/CodeGenObjC/objc-asm-attribute-neg-test.m6
-rw-r--r--test/CodeGenObjC/os_log.m76
14 files changed, 228 insertions, 110 deletions
diff --git a/test/CodeGenObjC/NSFastEnumeration.m b/test/CodeGenObjC/NSFastEnumeration.m
new file mode 100644
index 0000000000000..ba131fc4c7caa
--- /dev/null
+++ b/test/CodeGenObjC/NSFastEnumeration.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-apple-ios10.3 -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK32
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK32
+// RUN: %clang_cc1 -triple x86_64-apple-ios10.3 -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK64
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK64
+
+void f(id a) {
+ for (id i in a)
+ (void)i;
+}
+
+// CHECK32: call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i32)*)
+// CHECK32: call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i32)*)
+
+// CHECK64: call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)
+// CHECK64: call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)
+
diff --git a/test/CodeGenObjC/arc-arm.m b/test/CodeGenObjC/arc-arm.m
index 8d5f0d5c4b359..63c861f28951e 100644
--- a/test/CodeGenObjC/arc-arm.m
+++ b/test/CodeGenObjC/arc-arm.m
@@ -13,7 +13,7 @@ id test0(void) {
void test1(void) {
extern id test1_helper(void);
// CHECK: [[T0:%.*]] = call [[CC]]i8* @test1_helper()
- // CHECK-NEXT: call void asm sideeffect "mov
+ // CHECK-NEXT: call void asm sideeffect "mov\09{{fp, fp|r7, r7}}\09\09// marker for objc_retainAutoreleaseReturnValue"
// CHECK-NEXT: [[T1:%.*]] = call [[CC]]i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]],
// CHECK-NEXT: call [[CC]]void @objc_storeStrong(
diff --git a/test/CodeGenObjC/arc-bridged-cast.m b/test/CodeGenObjC/arc-bridged-cast.m
index 97a45c5a2f109..42795d5d80090 100644
--- a/test/CodeGenObjC/arc-bridged-cast.m
+++ b/test/CodeGenObjC/arc-bridged-cast.m
@@ -97,3 +97,11 @@ void bridge_of_cf(int *i) {
// CHECK-NEXT: ret void
}
+// CHECK-LABEL: define %struct.__CFString* @bridge_of_paren_expr()
+CFStringRef bridge_of_paren_expr() {
+ // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue(
+ // CHECK-NOT: call void @objc_release(
+ CFStringRef r = (__bridge CFStringRef)(CreateNSString());
+ r = (__bridge CFStringRef)((NSString *)(CreateNSString()));
+ return r;
+}
diff --git a/test/CodeGenObjC/attr-exception.m b/test/CodeGenObjC/attr-exception.m
index 00ebb0f2a0f12..30b637c8bc879 100644
--- a/test/CodeGenObjC/attr-exception.m
+++ b/test/CodeGenObjC/attr-exception.m
@@ -13,8 +13,8 @@ __attribute__((objc_exception))
@implementation A
@end
-// CHECK: @"OBJC_EHTYPE_$_A" = global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
-// CHECK-HIDDEN: @"OBJC_EHTYPE_$_A" = hidden global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK: @"OBJC_EHTYPE_$_A" = global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK-HIDDEN: @"OBJC_EHTYPE_$_A" = hidden global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
__attribute__((objc_exception))
__attribute__((visibility("default")))
@@ -23,5 +23,5 @@ __attribute__((visibility("default")))
@implementation B
@end
-// CHECK: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
-// CHECK-HIDDEN: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK-HIDDEN: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m
deleted file mode 100644
index e142a0bceb8ff..0000000000000
--- a/test/CodeGenObjC/debug-info-block-captured-self.m
+++ /dev/null
@@ -1,72 +0,0 @@
-// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -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-NEXT: [[DBGADDR:%.*]] = alloca [[BLOCK_T:<{.*}>]]*, align 8
-// CHECK: store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8
-// CHECK: %[[TMP0:.*]] = load i8*, i8** %[[MEM1]]
-// CHECK: call void @llvm.dbg.value(metadata i8* %[[TMP0]], i64 0, metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
-// CHECK: call void @llvm.dbg.declare(metadata i8* [[BLOCK_DESC]], metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
-// CHECK: store [[BLOCK_T]]* {{%.*}}, [[BLOCK_T]]** [[DBGADDR]], align 8
-// CHECK: call void @llvm.dbg.declare(metadata [[BLOCK_T]]** [[DBGADDR]], metadata ![[SELF:.*]], metadata !{{.*}})
-// make sure we are still in the same function
-// CHECK: define {{.*}}__copy_helper_block_
-// Metadata
-// CHECK: ![[MAIN:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Main"
-// CHECK-SAME: line: 23,
-// CHECK: ![[PMAIN:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[MAIN]],
-// CHECK: ![[BDMD]] = !DILocalVariable(name: ".block_descriptor", arg:
-// CHECK: ![[SELF]] = !DILocalVariable(name: "self"
-// CHECK-NOT: arg:
-// CHECK-SAME: line: 40,
diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m
index 0bf566395aa99..848e389f701b8 100644
--- a/test/CodeGenObjC/debug-info-blocks.m
+++ b/test/CodeGenObjC/debug-info-blocks.m
@@ -10,23 +10,20 @@
// CHECK-NEXT: call void @llvm.dbg.declare(metadata <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}})
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %1** %d, metadata ![[D:[0-9]+]], metadata !{{.*}})
-// rdar://problem/14386148
-// Test that we don't emit bogus line numbers for the helper functions.
-// Test that we do emit scope info for the helper functions.
+// Test that we do emit scope info for the helper functions, and that the
+// parameters to these functions are marked as artificial (so the debugger
+// doesn't accidentally step into the function).
// CHECK: define {{.*}} @__copy_helper_block_{{.*}}(i8*, i8*)
// CHECK-NOT: ret
// CHECK: call {{.*}}, !dbg ![[DBG_LINE:[0-9]+]]
// CHECK-NOT: ret
// CHECK: load {{.*}}, !dbg ![[COPY_LINE:[0-9]+]]
+// CHECK: ret void, !dbg ![[COPY_LINE]]
// CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(i8*)
// CHECK-NOT: ret
// CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
+// CHECK: ret void, !dbg ![[DESTROY_LINE]]
-// CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
-// CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: 0, scope: ![[DESTROY_SP:[0-9]+]])
-// CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
typedef unsigned int NSUInteger;
@protocol NSObject
@@ -60,6 +57,14 @@ static void run(void (^block)(void))
- (id)init
{
if ((self = [super init])) {
+ // CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
+ // CHECK-DAG: [[COPY_LINE]] = !DILocation(line: [[@LINE+7]], scope: ![[COPY_SP:[0-9]+]])
+ // CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
+ // CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: [[@LINE+5]], scope: ![[DESTROY_SP:[0-9]+]])
+ // CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
+ // CHECK-DAG: !DILocalVariable(arg: 1, scope: ![[COPY_SP]], {{.*}}, flags: DIFlagArtificial)
+ // CHECK-DAG: !DILocalVariable(arg: 2, scope: ![[COPY_SP]], {{.*}}, flags: DIFlagArtificial)
+ // CHECK-DAG: !DILocalVariable(arg: 1, scope: ![[DESTROY_SP]], {{.*}}, flags: DIFlagArtificial)
run(^{
// CHECK-DAG: ![[SELF]] = !DILocalVariable(name: "self", scope:{{.*}}, line: [[@LINE+4]],
// CHECK-DAG: ![[D]] = !DILocalVariable(name: "d", scope:{{.*}}, line: [[@LINE+1]],
diff --git a/test/CodeGenObjC/dllstorage.m b/test/CodeGenObjC/dllstorage.m
index 4bdbd509151b6..a2665eefad855 100644
--- a/test/CodeGenObjC/dllstorage.m
+++ b/test/CodeGenObjC/dllstorage.m
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -fobjc-runtime=ios -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=macosx -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=objfw -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FW %s
@@ -114,6 +115,15 @@ __attribute__((__objc_exception__))
// CHECK-IR-DAG: @"OBJC_EHTYPE_$_P" = external global %struct._objc_typeinfo
+@interface Q : M
+@end
+
+id f(Q *q) {
+ return q->_ivar;
+}
+
+// CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
+
int g() {
@autoreleasepool {
M *mi = [M new];
diff --git a/test/CodeGenObjC/ivar-layout-flexible-array.m b/test/CodeGenObjC/ivar-layout-flexible-array.m
new file mode 100644
index 0000000000000..28849c86c2afc
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-flexible-array.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -Wno-objc-root-class -fobjc-arc -emit-llvm -o - %s | FileCheck %s
+
+// rdar://problem/21054495
+@interface FlexibleArrayMember {
+ char flexible_array[][4][2];
+}
+@end
+@implementation FlexibleArrayMember
+@end
+// CHECK: @OBJC_METH_VAR_NAME_{{.*}} = private unnamed_addr constant {{.*}} c"flexible_array\00"
+// CHECK-NEXT: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant {{.*}} c"^[4[2c]]\00"
+
+
+typedef char FlexibleArray[];
+
+struct Packet {
+ int size;
+ FlexibleArray data;
+};
+
+@interface VariableSizeIvar {
+ struct Packet flexible_struct;
+}
+@end
+@implementation VariableSizeIvar
+@end
+// CHECK: @OBJC_METH_VAR_NAME_{{.*}} = private unnamed_addr constant {{.*}} c"flexible_struct\00"
+// CHECK-NEXT: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant {{.*}} c"{Packet=\22size\22i\22data\22[0c]}\00"
diff --git a/test/CodeGenObjC/local-static-block.m b/test/CodeGenObjC/local-static-block.m
index 73c670f5c9259..67ede63fc0a29 100644
--- a/test/CodeGenObjC/local-static-block.m
+++ b/test/CodeGenObjC/local-static-block.m
@@ -46,6 +46,17 @@ void FUNC()
}
}
+void FUNC2() {
+ static void (^const block1)(int) = ^(int a){
+ if (a--)
+ block1(a);
+ };
+}
+
+// CHECK-LABEL-LP64: define void @FUNC2(
+// CHECK: define internal void @_block_invoke{{.*}}(
+// CHECK: call void %{{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{.*}} to i8*), i32 %{{.*}})
+
void FUNC1()
{
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
diff --git a/test/CodeGenObjC/mangle-blocks.m b/test/CodeGenObjC/mangle-blocks.m
index 4cc3204033229..73522cd41c638 100644
--- a/test/CodeGenObjC/mangle-blocks.m
+++ b/test/CodeGenObjC/mangle-blocks.m
@@ -18,11 +18,11 @@ void __assert_rtn(const char *, const char *, int, const char *);
@end
// CHECK: @"__func__.__14-[Test mangle]_block_invoke_2" = private unnamed_addr constant [30 x i8] c"-[Test mangle]_block_invoke_2\00", align 1
-// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
-// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
+// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1
+// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
// CHECK: define internal void @"__14-[Test mangle]_block_invoke"(i8* %.block_descriptor)
// CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(i8* %.block_descriptor){{.*}}{
-// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0))
// CHECK: }
diff --git a/test/CodeGenObjC/no-sanitize.m b/test/CodeGenObjC/no-sanitize.m
index 39f8575670d5b..07a196b6419dc 100644
--- a/test/CodeGenObjC/no-sanitize.m
+++ b/test/CodeGenObjC/no-sanitize.m
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 %s -emit-llvm -fsanitize=address -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -fsanitize=address -fblocks -o - | FileCheck %s
@interface I0 @end
@implementation I0
// CHECK-NOT: sanitize_address
- (void) im0: (int) a0 __attribute__((no_sanitize("address"))) {
+ int (^blockName)() = ^int() { return 0; };
}
@end
diff --git a/test/CodeGenObjC/noescape.m b/test/CodeGenObjC/noescape.m
new file mode 100644
index 0000000000000..49bc0e4a7d33a
--- /dev/null
+++ b/test/CodeGenObjC/noescape.m
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck %s
+
+typedef void (^BlockTy)(void);
+
+union U {
+ int *i;
+ long long *ll;
+} __attribute__((transparent_union));
+
+void noescapeFunc0(id, __attribute__((noescape)) BlockTy);
+void noescapeFunc1(__attribute__((noescape)) int *);
+void noescapeFunc2(__attribute__((noescape)) id);
+void noescapeFunc3(__attribute__((noescape)) union U);
+
+// CHECK-LABEL: define void @test0(
+// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc0(i8*, {{.*}} nocapture)
+void test0(BlockTy b) {
+ noescapeFunc0(0, b);
+}
+
+// CHECK-LABEL: define void @test1(
+// CHECK: call void @noescapeFunc1({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc1({{.*}} nocapture)
+void test1(int *i) {
+ noescapeFunc1(i);
+}
+
+// CHECK-LABEL: define void @test2(
+// CHECK: call void @noescapeFunc2({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc2({{.*}} nocapture)
+void test2(id i) {
+ noescapeFunc2(i);
+}
+
+// CHECK-LABEL: define void @test3(
+// CHECK: call void @noescapeFunc3({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc3({{.*}} nocapture)
+void test3(union U u) {
+ noescapeFunc3(u);
+}
+
+// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+
+// CHECK-LABEL: define void @test4(
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32*)*)(i8* {{.*}}, i8* {{.*}}, i32* nocapture {{.*}})
+
+@interface C0
+-(void) m0:(int*)__attribute__((noescape)) p0;
+@end
+
+@implementation C0
+-(void) m0:(int*)__attribute__((noescape)) p0 {
+}
+@end
+
+void test4(C0 *c0, int *p) {
+ [c0 m0:p];
+}
+
+// CHECK-LABEL: define void @test5(
+// CHECK: call void {{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, {{.*}} }* @{{.*}} to i8*), i32* nocapture {{.*}})
+// CHECK: call void {{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
+// CHECK: define internal void @{{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
+
+typedef void (^BlockTy2)(__attribute__((noescape)) int *);
+
+void test5(BlockTy2 b, int *p) {
+ ^(int *__attribute__((noescape)) p0){}(p);
+ b(p);
+}
diff --git a/test/CodeGenObjC/objc-asm-attribute-neg-test.m b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
index e9bef4cdb7626..de809d8a048d8 100644
--- a/test/CodeGenObjC/objc-asm-attribute-neg-test.m
+++ b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
@@ -7,15 +7,15 @@ __attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
@interface Message <Protocol> {
-__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
id MyIVAR;
}
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
-- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
-- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
@end
diff --git a/test/CodeGenObjC/os_log.m b/test/CodeGenObjC/os_log.m
index 5d48783de4723..1cf0c9f1f35c4 100644
--- a/test/CodeGenObjC/os_log.m
+++ b/test/CodeGenObjC/os_log.m
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O2 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O0 | FileCheck %s -check-prefix=CHECK-O0
// Make sure we emit clang.arc.use before calling objc_release as part of the
// cleanup. This way we make sure the object will not be released until the
@@ -12,28 +13,67 @@ extern __attribute__((visibility("default"))) NSString *GenString();
// Behavior of __builtin_os_log differs between platforms, so only test on X86
#ifdef __x86_64__
// CHECK-LABEL: define i8* @test_builtin_os_log
+// CHECK-O0-LABEL: define i8* @test_builtin_os_log
+// CHECK: (i8* returned %[[BUF:.*]])
+// CHECK-O0: (i8* %[[BUF:.*]])
void *test_builtin_os_log(void *buf) {
return __builtin_os_log_format(buf, "capabilities: %@", GenString());
- // CHECK: store i8 2, i8*
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* {{.*}}, i64 1
- // CHECK: store i8 1, i8* [[NUM_ARGS]]
- //
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* {{.*}}, i64 2
- // CHECK: store i8 64, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* {{.*}}, i64 3
- // CHECK: store i8 8, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* {{.*}}, i64 4
- // CHECK: [[ARG1_CAST:%.*]] = bitcast i8* [[ARG1]] to
+ // CHECK: %[[CALL:.*]] = tail call %[[TY0:.*]]* (...) @GenString()
+ // CHECK: %[[V0:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
+ // CHECK: %[[V1:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V0]])
+ // CHECK: %[[V2:.*]] = ptrtoint %[[TY0]]* %[[CALL]] to i64
+ // CHECK: store i8 2, i8* %[[BUF]], align 1
+ // CHECK: %[[NUMARGS_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+ // CHECK: store i8 1, i8* %[[NUMARGS_I]], align 1
+ // CHECK: %[[ARGDESCRIPTOR_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+ // CHECK: store i8 64, i8* %[[ARGDESCRIPTOR_I]], align 1
+ // CHECK: %[[ARGSIZE_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+ // CHECK: store i8 8, i8* %[[ARGSIZE_I]], align 1
+ // CHECK: %[[ARGDATA_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+ // CHECK: %[[ARGDATACAST_I:.*]] = bitcast i8* %[[ARGDATA_I]] to i64*
+ // CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST_I]], align 1
+ // CHECK: tail call void (...) @clang.arc.use(%[[TY0]]* %[[CALL]])
+ // CHECK: tail call void @objc_release(i8* %[[V0]])
+ // CHECK: ret i8* %[[BUF]]
- // CHECK: [[STRING:%.*]] = {{.*}} call {{.*}} @GenString()
- // CHECK: [[STRING_CAST:%.*]] = bitcast {{.*}} [[STRING]] to
- // CHECK: call {{.*}} @objc_retainAutoreleasedReturnValue(i8* [[STRING_CAST]])
- // CHECK: store {{.*}} [[STRING]], {{.*}} [[ARG1_CAST]]
-
- // CHECK: call void (...) @clang.arc.use({{.*}} [[STRING]])
- // CHECK: call void @objc_release(i8* [[STRING_CAST]])
- // CHECK: ret i8*
+ // clang.arc.use is used and removed in IR optimizations. At O0, we should not
+ // emit clang.arc.use, since it will not be removed and we will have a link
+ // error.
+ // CHECK-O0: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK-O0: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK-O0: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK-O0: %[[CALL:.*]] = call %[[TY0:.*]]* (...) @GenString()
+ // CHECK-O0: %[[V1:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
+ // CHECK-O0: %[[V2:.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V1]])
+ // CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %[[TY0]]*
+ // CHECK-O0: %[[V4:.*]] = ptrtoint %[[TY0]]* %[[V3]] to i64
+ // CHECK-O0: call void @__os_log_helper_1_2_1_8_64(i8* %[[V0]], i64 %[[V4]])
+ // CHECK-O0: %[[V5:.*]] = bitcast %[[TY0]]* %[[V3]] to i8*
+ // CHECK-O0-NOT call void (...) @clang.arc.use({{.*}}
+ // CHECK-O0: call void @objc_release(i8* %[[V5]])
+ // CHECK-O0: ret i8* %[[V0]]
}
+// CHECK-O0-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_8_64
+// CHECK-O0: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]])
+
+// CHECK-O0: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK-O0: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK-O0: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK-O0: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK-O0: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK-O0: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK-O0: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK-O0: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK-O0: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK-O0: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK-O0: store i8 64, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK-O0: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK-O0: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK-O0: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK-O0: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK-O0: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK-O0: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+
#endif