diff options
Diffstat (limited to 'test/CodeGenObjC')
| -rw-r--r-- | test/CodeGenObjC/NSFastEnumeration.m | 16 | ||||
| -rw-r--r-- | test/CodeGenObjC/arc-arm.m | 2 | ||||
| -rw-r--r-- | test/CodeGenObjC/arc-bridged-cast.m | 8 | ||||
| -rw-r--r-- | test/CodeGenObjC/attr-exception.m | 8 | ||||
| -rw-r--r-- | test/CodeGenObjC/debug-info-block-captured-self.m | 72 | ||||
| -rw-r--r-- | test/CodeGenObjC/debug-info-blocks.m | 21 | ||||
| -rw-r--r-- | test/CodeGenObjC/dllstorage.m | 10 | ||||
| -rw-r--r-- | test/CodeGenObjC/ivar-layout-flexible-array.m | 28 | ||||
| -rw-r--r-- | test/CodeGenObjC/local-static-block.m | 11 | ||||
| -rw-r--r-- | test/CodeGenObjC/mangle-blocks.m | 6 | ||||
| -rw-r--r-- | test/CodeGenObjC/no-sanitize.m | 3 | ||||
| -rw-r--r-- | test/CodeGenObjC/noescape.m | 71 | ||||
| -rw-r--r-- | test/CodeGenObjC/objc-asm-attribute-neg-test.m | 6 | ||||
| -rw-r--r-- | test/CodeGenObjC/os_log.m | 76 |
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 |
