[Clang] Convert some tests to opaque pointers (NFC)

This commit is contained in:
Nikita Popov 2023-06-07 15:16:35 +02:00
parent 23431b5246
commit 2eb84c3ae2
23 changed files with 742 additions and 1001 deletions

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
// rdar://8881826
// rdar://9423507
@ -18,7 +18,7 @@
}
@end
// CHECK-NOT: call i8* @objc_getClass
// CHECK: call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK-NOT: call ptr @objc_getClass
// CHECK: call ptr @objc_msgSend
// CHECK: call ptr @objc_msgSend
// CHECK: call void @objc_msgSend

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-NOARC %s
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin -fblocks -emit-llvm -fobjc-arc -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-ARC %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-NOARC %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -fobjc-arc -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-ARC %s
typedef void (^BlockTy)(void);
@ -17,19 +17,17 @@ void noescapeFunc3(__attribute__((noescape)) union U);
// Block descriptors of non-escaping blocks don't need pointers to copy/dispose
// helper functions.
// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
// When the block is non-escaping, copy/dispose helpers aren't generated, so the
// block layout string must include information about __strong captures.
// CHECK-NOARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { i8*, %[[STRUCT_BLOCK_BYREF_B0]]*, i32, i32, i8*, %[[STRUCT_S0:.*]] }
// CHECK-ARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { i8*, %[[STRUCT_BLOCK_BYREF_B0]]*, i32, i32, i8*, i8*, i8*, %[[STRUCT_S0:.*]] }
// CHECK: %[[STRUCT_S0]] = type { i8*, i8* }
// CHECK: @[[BLOCK_DESCIPTOR_TMP_2:.*ls32l8"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i64 } { i64 0, i64 40, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i64 256 }, align 8
// CHECK-NOARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { ptr, ptr, i32, i32, ptr, %[[STRUCT_S0:.*]] }
// CHECK-ARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { ptr, ptr, i32, i32, ptr, ptr, ptr, %[[STRUCT_S0:.*]] }
// CHECK: %[[STRUCT_S0]] = type { ptr, ptr }
// CHECK: @[[BLOCK_DESCIPTOR_TMP_2:.*ls32l8"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, i64 } { i64 0, i64 40, ptr @{{.*}}, i64 256 }, align 8
// CHECK-LABEL: define{{.*}} void @test0(
// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}})
// CHECK: declare void @noescapeFunc0(i8* noundef, {{.*}} nocapture noundef)
// CHECK: declare void @noescapeFunc0(ptr noundef, {{.*}} nocapture noundef)
void test0(BlockTy b) {
noescapeFunc0(0, b);
}
@ -58,7 +56,7 @@ void test3(union U 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 {{.*}})
// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}, ptr nocapture {{.*}})
@interface C0
-(void) m0:(int*)__attribute__((noescape)) p0;
@ -74,9 +72,9 @@ void test4(C0 *c0, int *p) {
}
// CHECK-LABEL: define{{.*}} void @test5(
// CHECK: call void {{.*}}(i8* noundef bitcast ({ i8**, i32, i32, i8*, {{.*}} }* @{{.*}} to i8*), i32* nocapture {{.*}})
// CHECK: call void {{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
// CHECK: define internal void @{{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
// CHECK: call void {{.*}}(ptr noundef @{{.*}}, ptr nocapture {{.*}})
// CHECK: call void {{.*}}(ptr {{.*}}, ptr nocapture {{.*}})
// CHECK: define internal void @{{.*}}(ptr {{.*}}, ptr nocapture {{.*}})
typedef void (^BlockTy2)(__attribute__((noescape)) int *);
@ -88,28 +86,28 @@ void test5(BlockTy2 b, int *p) {
// If the block is non-escaping, set the BLOCK_IS_NOESCAPE and BLOCK_IS_GLOBAL
// bits of field 'flags' and set the 'isa' field to 'NSConcreteGlobalBlock'.
// CHECK: define{{.*}} void @test6(i8* noundef %{{.*}}, i8* noundef %[[B:.*]])
// CHECK: %{{.*}} = alloca i8*, align 8
// CHECK: %[[B_ADDR:.*]] = alloca i8*, align 8
// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
// CHECK-NOARC: store i8* %[[B]], i8** %[[B_ADDR]], align 8
// CHECK-ARC: store i8* null, i8** %[[B_ADDR]], align 8
// CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[B_ADDR]], i8* %[[B]])
// CHECK: %[[BLOCK_ISA:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 0
// CHECK: store i8* bitcast (i8** @_NSConcreteGlobalBlock to i8*), i8** %[[BLOCK_ISA]], align 8
// CHECK: %[[BLOCK_FLAGS:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 1
// CHECK: store i32 -796917760, i32* %[[BLOCK_FLAGS]], align 8
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 4
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i64 }* @[[BLOCK_DESCIPTOR_TMP_2]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 5
// CHECK-NOARC: %[[V1:.*]] = load i8*, i8** %[[B_ADDR]], align 8
// CHECK-NOARC: store i8* %[[V1]], i8** %[[BLOCK_CAPTURED]], align 8
// CHECK-ARC: %[[V2:.*]] = load i8*, i8** %[[B_ADDR]], align 8
// CHECK-ARC: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %[[V2]])
// CHECK-ARC: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED]], align 8
// CHECK: define{{.*}} void @test6(ptr noundef %{{.*}}, ptr noundef %[[B:.*]])
// CHECK: %{{.*}} = alloca ptr, align 8
// CHECK: %[[B_ADDR:.*]] = alloca ptr, align 8
// CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
// CHECK-NOARC: store ptr %[[B]], ptr %[[B_ADDR]], align 8
// CHECK-ARC: store ptr null, ptr %[[B_ADDR]], align 8
// CHECK-ARC: call void @llvm.objc.storeStrong(ptr %[[B_ADDR]], ptr %[[B]])
// CHECK: %[[BLOCK_ISA:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 0
// CHECK: store ptr @_NSConcreteGlobalBlock, ptr %[[BLOCK_ISA]], align 8
// CHECK: %[[BLOCK_FLAGS:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 1
// CHECK: store i32 -796917760, ptr %[[BLOCK_FLAGS]], align 8
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 4
// CHECK: store ptr @[[BLOCK_DESCIPTOR_TMP_2]], ptr %[[BLOCK_DESCRIPTOR]], align 8
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 5
// CHECK-NOARC: %[[V1:.*]] = load ptr, ptr %[[B_ADDR]], align 8
// CHECK-NOARC: store ptr %[[V1]], ptr %[[BLOCK_CAPTURED]], align 8
// CHECK-ARC: %[[V2:.*]] = load ptr, ptr %[[B_ADDR]], align 8
// CHECK-ARC: %[[V3:.*]] = call ptr @llvm.objc.retain(ptr %[[V2]])
// CHECK-ARC: store ptr %[[V3]], ptr %[[BLOCK_CAPTURED]], align 8
// CHECK: call void @noescapeFunc0(
// CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[BLOCK_CAPTURED]], i8* null)
// CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[B_ADDR]], i8* null)
// CHECK-ARC: call void @llvm.objc.storeStrong(ptr %[[BLOCK_CAPTURED]], ptr null)
// CHECK-ARC: call void @llvm.objc.storeStrong(ptr %[[B_ADDR]], ptr null)
// Non-escaping blocks don't need copy/dispose helper functions.
@ -126,11 +124,11 @@ void test6(id a, id b) {
// __block variables that are not captured by escaping blocks.
// CHECK: define{{.*}} void @test7(
// CHECK: alloca i8*, align 8
// CHECK: %[[B0:.*]] = alloca i8*, align 8
// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, align 8
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>* %[[BLOCK]], i32 0, i32 5
// CHECK: store i8** %[[B0]], i8*** %[[BLOCK_CAPTURED]], align 8
// CHECK: alloca ptr, align 8
// CHECK: %[[B0:.*]] = alloca ptr, align 8
// CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 5
// CHECK: store ptr %[[B0]], ptr %[[BLOCK_CAPTURED]], align 8
// CHECK-ARC-NOT: define internal void @__Block_byref_object_copy_
// CHECK-ARC-NOT: define internal void @__Block_byref_object_dispose_
@ -144,13 +142,12 @@ void test7(void) {
// __block variables captured by escaping blocks need byref helper functions.
// CHECK: define{{.*}} void @test8(
// CHECK: %[[A:.*]] = alloca i8*, align 8
// CHECK: %[[A:.*]] = alloca ptr, align 8
// CHECK: %[[B0:.*]] = alloca %[[STRUCT_BLOCK_BYREF_B0]], align 8
// CHECK: alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
// CHECK: %[[BLOCK1:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
// CHECK: %[[BLOCK_CAPTURED7:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK1]], i32 0, i32 5
// CHECK: %[[V3:.*]] = bitcast %[[STRUCT_BLOCK_BYREF_B0]]* %[[B0]] to i8*
// CHECK: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED7]], align 8
// CHECK: alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
// CHECK: %[[BLOCK1:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
// CHECK: %[[BLOCK_CAPTURED7:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK1]], i32 0, i32 5
// CHECK: store ptr %[[B0]], ptr %[[BLOCK_CAPTURED7]], align 8
// CHECK-ARC: define internal void @__Block_byref_object_copy_
// CHECK-ARC: define internal void @__Block_byref_object_dispose_

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -fobjc-exceptions -fexceptions -debug-info-kind=line-tables-only -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -fobjc-exceptions -fexceptions -debug-info-kind=line-tables-only -emit-llvm -o - %s | FileCheck %s
// CHECK: %[[STRUCT_STRONG:.*]] = type { i32, i8* }
// CHECK: %[[STRUCT_WEAK:.*]] = type { i32, i8* }
// CHECK: %[[STRUCT_STRONG:.*]] = type { i32, ptr }
// CHECK: %[[STRUCT_WEAK:.*]] = type { i32, ptr }
typedef struct {
int i;
@ -17,16 +17,14 @@ typedef struct {
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8
// CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_STRONG]], align 8
// CHECK: %[[CALL:.*]] = call [2 x i64] @genStrong()
// CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONG]]* %[[AGG_TMP]] to [2 x i64]*
// CHECK: store [2 x i64] %[[CALL]], [2 x i64]* %[[V0]], align 8
// CHECK: store [2 x i64] %[[CALL]], ptr %[[AGG_TMP]], align 8
// CHECK: invoke [2 x i64] @genStrong()
// CHECK: call void @calleeStrong([2 x i64] %{{.*}}, [2 x i64] %{{.*}})
// CHECK-NEXT: ret void
// CHECK: landingpad { i8*, i32 }
// CHECK: %[[V9:.*]] = bitcast %[[STRUCT_STRONG]]* %[[AGG_TMP]] to i8**{{.*}}, !dbg [[ARTIFICIAL_LOC_1:![0-9]+]]
// CHECK: call void @__destructor_8_s8(i8** %[[V9]]){{.*}}, !dbg [[ARTIFICIAL_LOC_1]]
// CHECK: landingpad { ptr, i32 }
// CHECK: call void @__destructor_8_s8(ptr %[[AGG_TMP]]){{.*}}, !dbg [[ARTIFICIAL_LOC_1:![0-9]+]]
// CHECK: br label
// CHECK: resume
@ -41,21 +39,20 @@ void testStrongException(void) {
// CHECK: define{{.*}} void @testWeakException()
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_WEAK]], align 8
// CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_WEAK]], align 8
// CHECK: call void @genWeak(%[[STRUCT_WEAK]]* sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP]])
// CHECK: invoke void @genWeak(%[[STRUCT_WEAK]]* sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP1]])
// CHECK: call void @genWeak(ptr sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP]])
// CHECK: invoke void @genWeak(ptr sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP1]])
// CHECK: call void @calleeWeak(%[[STRUCT_WEAK]]* noundef %[[AGG_TMP]], %[[STRUCT_WEAK]]* noundef %[[AGG_TMP1]])
// CHECK: call void @calleeWeak(ptr noundef %[[AGG_TMP]], ptr noundef %[[AGG_TMP1]])
// CHECK: ret void
// CHECK: landingpad { i8*, i32 }
// CHECK: %[[V3:.*]] = bitcast %[[STRUCT_WEAK]]* %[[AGG_TMP]] to i8**{{.*}}, !dbg [[ARTIFICIAL_LOC_2:![0-9]+]]
// CHECK: call void @__destructor_8_w8(i8** %[[V3]]){{.*}}, !dbg [[ARTIFICIAL_LOC_2]]
// CHECK: landingpad { ptr, i32 }
// CHECK: call void @__destructor_8_w8(ptr %[[AGG_TMP]]){{.*}}, !dbg [[ARTIFICIAL_LOC_2:![0-9]+]]
// CHECK: br label
// CHECK: resume
// CHECK: define{{.*}} void @__destructor_8_w8({{.*}} !dbg ![[DTOR_SP:.*]] {
// CHECK: load i8**, i8*** {{.*}}, !dbg ![[DTOR_LOC:.*]]
// CHECK: load ptr, ptr {{.*}}, !dbg ![[DTOR_LOC:.*]]
Weak genWeak(void);
void calleeWeak(Weak, Weak);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-dispatch-method=mixed -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-dispatch-method=mixed -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
@interface NSObject
- (id) new;
@ -18,15 +18,13 @@ void test0(void) {
[x isEqual : obj];
}
// CHECK-LABEL: define{{.*}} void @test0()
// CHECK: [[FIVE:%.*]] = call i8* @llvm.objc.retain
// CHECK-NEXT: [[SIX:%.*]] = bitcast
// CHECK-NEXT: [[SEVEN:%.*]] = icmp eq i8* [[SIX]], null
// CHECK: [[FIVE:%.*]] = call ptr @llvm.objc.retain
// CHECK-NEXT: [[SEVEN:%.*]] = icmp eq ptr {{.*}}, null
// CHECK-NEXT: br i1 [[SEVEN]], label [[NULLINIT:%.*]], label [[CALL_LABEL:%.*]]
// CHECK: [[FN:%.*]] = load i8*, i8** getelementptr inbounds
// CHECK-NEXT: [[EIGHT:%.*]] = bitcast i8* [[FN]]
// CHECK-NEXT: [[CALL:%.*]] = call signext i8 [[EIGHT]]
// CHECK: [[FN:%.*]] = load ptr, ptr
// CHECK-NEXT: [[CALL:%.*]] = call signext i8 [[FN]]
// CHECK-NEXT: br label [[CONT:%.*]]
// CHECK: call void @llvm.objc.release(i8* [[FIVE]]) [[NUW:#[0-9]+]]
// CHECK: call void @llvm.objc.release(ptr [[FIVE]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: br label [[CONT]]
// CHECK: phi i8 [ [[CALL]], {{%.*}} ], [ 0, {{%.*}} ]
@ -38,61 +36,59 @@ void test1(void) {
_Complex float result = [x asComplexWithArg: obj];
}
// CHECK-LABEL: define{{.*}} void @test1()
// CHECK: [[OBJ:%.*]] = alloca i8*, align 8
// CHECK-NEXT: [[WEAKOBJ:%.*]] = alloca i8*, align 8
// CHECK: [[OBJ:%.*]] = alloca ptr, align 8
// CHECK-NEXT: [[WEAKOBJ:%.*]] = alloca ptr, 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*, i8** [[OBJ]]
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[WEAKOBJ]], i8* [[T0]]) [[NUW]]
// CHECK: [[T0:%.*]] = call ptr
// CHECK-NEXT: store ptr [[T0]], ptr [[OBJ]]
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[OBJ]]
// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[WEAKOBJ]], ptr [[T0]]) [[NUW]]
// Okay, start the message-send.
// CHECK-NEXT: [[T0:%.*]] = load [[MYOBJECT:%.*]]*, [[MYOBJECT:%.*]]** @x
// CHECK-NEXT: [[ARG:%.*]] = load i8*, i8** [[OBJ]]
// CHECK-NEXT: [[ARG_RETAINED:%.*]] = call i8* @llvm.objc.retain(i8* [[ARG]])
// CHECK-NEXT: [[SELF:%.*]] = bitcast [[MYOBJECT]]* [[T0]] to i8*
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @x
// CHECK-NEXT: [[ARG:%.*]] = load ptr, ptr [[OBJ]]
// CHECK-NEXT: [[ARG_RETAINED:%.*]] = call ptr @llvm.objc.retain(ptr [[ARG]])
// Null check.
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8* [[SELF]], null
// CHECK-NEXT: br i1 [[T0]], label [[FORNULL:%.*]], label %[[FORCALL:.*]]
// CHECK-NEXT: [[T1:%.*]] = icmp eq ptr [[T0]], null
// CHECK-NEXT: br i1 [[T1]], label [[FORNULL:%.*]], label %[[FORCALL:.*]]
// Invoke and produce the return values.
// CHECK: [[FORCALL]]:
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[CALL:%.*]] = invoke <2 x float> bitcast
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[CALL:%.*]] = invoke <2 x float>
// 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 }, { float, float }* [[COERCE]], i32 0, i32 0
// CHECK-NEXT: [[REALCALL:%.*]] = load float, float* [[T0]]
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }, { float, float }* [[COERCE]], i32 0, i32 1
// CHECK-NEXT: [[IMAGCALL:%.*]] = load float, float* [[T0]]
// CHECK: store <2 x float> [[CALL]], ptr [[COERCE:%.*]],
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// CHECK-NEXT: [[REALCALL:%.*]] = load float, ptr [[T0]]
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// CHECK-NEXT: [[IMAGCALL:%.*]] = load float, ptr [[T0]]
// CHECK-NEXT: br label [[CONT:%.*]]{{$}}
// Null path.
// CHECK: call void @llvm.objc.release(i8* [[ARG_RETAINED]]) [[NUW]]
// CHECK: call void @llvm.objc.release(ptr [[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 }, { float, float }* [[RESULT]], i32 0, i32 0
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds { float, float }, { float, float }* [[RESULT]], i32 0, i32 1
// CHECK-NEXT: store float [[REAL]], float* [[T0]]
// CHECK-NEXT: store float [[IMAG]], float* [[T1]]
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { float, float }, ptr [[RESULT]], i32 0, i32 0
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds { float, float }, ptr [[RESULT]], i32 0, i32 1
// CHECK-NEXT: store float [[REAL]], ptr [[T0]]
// CHECK-NEXT: store float [[IMAG]], ptr [[T1]]
// Epilogue.
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[WEAKOBJ]]) [[NUW]]
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[OBJ]], i8* null) [[NUW]]
// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[WEAKOBJ]]) [[NUW]]
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[OBJ]], ptr null) [[NUW]]
// CHECK-NEXT: ret void
// Cleanup.
// CHECK: landingpad
// CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAKOBJ]]) [[NUW]]
// CHECK: call void @llvm.objc.destroyWeak(ptr [[WEAKOBJ]]) [[NUW]]
void test2(id a) {
id obj = [MyObject m0:a];
}
// CHECK-LABEL: define{{.*}} void @test2(
// CHECK: %[[CALL:.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK-NEXT: %[[V6:.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]])
// CHECK: %[[CALL:.*]] = call ptr @objc_msgSend
// CHECK-NEXT: %[[V6:.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %[[CALL]])
// CHECK: phi i8* [ %[[V6]], %{{.*}} ], [ null, %{{.*}} ]
// CHECK: phi ptr [ %[[V6]], %{{.*}} ], [ null, %{{.*}} ]
void test3(id a) {
@try {
@ -102,9 +98,9 @@ void test3(id a) {
}
// CHECK-LABEL: define{{.*}} void @test3(
// CHECK: %[[CALL:.*]] = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: %[[V6:.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]])
// CHECK: %[[CALL:.*]] = invoke ptr @objc_msgSend
// CHECK: %[[V6:.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %[[CALL]])
// CHECK: phi i8* [ %[[V6]], %{{.*}} ], [ null, %{{.*}} ]
// CHECK: phi ptr [ %[[V6]], %{{.*}} ], [ null, %{{.*}} ]
// CHECK: attributes [[NUW]] = { nounwind }

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
// RUN: %clang_cc1 -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
#import "nsvalue-boxed-expressions-support.h"
@ -17,15 +17,11 @@ void doRange(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSRange ns_range = { .location = 0, .length = 42 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue
NSValue *range = @(ns_range);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -36,15 +32,11 @@ void doPoint(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.CGPoint{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.CGPoint{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.CGPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGPoint* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
CGPoint cg_point = { .x = 42, .y = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}})
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr {{.*}}[[POINT_STR]]{{.*}})
// CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue
NSValue *point = @(cg_point);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -55,15 +47,11 @@ void doSize(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.CGSize{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.CGSize{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.CGSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGSize* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
CGSize cg_size = { .width = 42, .height = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}})
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr {{.*}}[[SIZE_STR]]{{.*}})
// CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue
NSValue *size = @(cg_size);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -74,17 +62,13 @@ void doRect(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.CGRect{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.CGRect{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.CGRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGRect* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
CGPoint cg_point = { .x = 42, .y = 24 };
CGSize cg_size = { .width = 42, .height = 24 };
CGRect cg_rect = { .origin = cg_point, .size = cg_size };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}})
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[RECT_STR]]{{.*}})
// CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue
NSValue *rect = @(cg_rect);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -95,15 +79,11 @@ void doNSEdgeInsets(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSEdgeInsets ns_edge_insets;
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}})
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[EDGE_STR]]{{.*}})
// CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue
NSValue *edge_insets = @(ns_edge_insets);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -114,11 +94,9 @@ void doRangeRValue(void) {
// CHECK: [[COERCE:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: call {{.*}} @getRange({{.*}} [[COERCE]])
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[COERCE]], ptr {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue
NSValue *range_rvalue = @(getRange());
// CHECK: call void @llvm.objc.release
// CHECK: ret void

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s
// RUN: %clang_cc1 -I %S/Inputs -triple armv7-apple-ios8.0.0 -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s
#import "nsvalue-boxed-expressions-support.h"
@ -17,14 +17,10 @@ void doRange(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSRange ns_range = { .location = 0, .length = 42 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr noundef {{.*}}[[RANGE_STR]]{{.*}})
NSValue *range = @(ns_range);
// CHECK: ret void
}
@ -34,14 +30,10 @@ void doPoint(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.CGPoint{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.CGPoint{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.CGPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGPoint* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
CGPoint cg_point = { .x = 42, .y = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[POINT_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr noundef {{.*}}[[POINT_STR]]{{.*}})
NSValue *point = @(cg_point);
// CHECK: ret void
}
@ -51,14 +43,10 @@ void doSize(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.CGSize{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.CGSize{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.CGSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGSize* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
CGSize cg_size = { .width = 42, .height = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[SIZE_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr noundef {{.*}}[[SIZE_STR]]{{.*}})
NSValue *size = @(cg_size);
// CHECK: ret void
}
@ -68,16 +56,12 @@ void doRect(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.CGRect{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.CGRect{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.CGRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGRect* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
CGPoint cg_point = { .x = 42, .y = 24 };
CGSize cg_size = { .width = 42, .height = 24 };
CGRect cg_rect = { .origin = cg_point, .size = cg_size };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[RECT_STR]]{{.*}})
NSValue *rect = @(cg_rect);
// CHECK: ret void
}
@ -87,14 +71,10 @@ void doNSEdgeInsets(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSEdgeInsets ns_edge_insets;
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[EDGE_STR]]{{.*}})
NSValue *edge_insets = @(ns_edge_insets);
// CHECK: ret void
}
@ -104,10 +84,8 @@ void doRangeRValue(void) {
// CHECK: [[COERCE:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: call {{.*}} @getRange({{.*}} [[COERCE]])
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[COERCE]], ptr noundef {{.*}}[[RANGE_STR]]{{.*}})
NSValue *range_rvalue = @(getRange());
// CHECK: ret void
}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
#import "nsvalue-boxed-expressions-support.h"
@ -17,14 +17,10 @@ void doRange(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSRange ns_range = { .location = 0, .length = 42 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
NSValue *range = @(ns_range);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -35,14 +31,10 @@ void doPoint(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSPoint{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSPoint{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSPoint* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSPoint ns_point = { .x = 42, .y = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr {{.*}}[[POINT_STR]]{{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
NSValue *point = @(ns_point);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -53,14 +45,10 @@ void doSize(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSSize{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSSize{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSSize* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSSize ns_size = { .width = 42, .height = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr {{.*}}[[SIZE_STR]]{{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
NSValue *size = @(ns_size);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -71,16 +59,12 @@ void doRect(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRect{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRect{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRect* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSPoint ns_point = { .x = 42, .y = 24 };
NSSize ns_size = { .width = 42, .height = 24 };
NSRect ns_rect = { .origin = ns_point, .size = ns_size };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[RECT_STR]]{{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
NSValue *rect = @(ns_rect);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -91,14 +75,10 @@ void doNSEdgeInsets(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSEdgeInsets ns_edge_insets;
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[EDGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
NSValue *edge_insets = @(ns_edge_insets);
// CHECK: call void @llvm.objc.release
// CHECK: ret void
@ -109,14 +89,11 @@ void doRangeRValue(void) {
// CHECK: [[COERCE:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[RVAL:%.*]] = call {{.*}} @getRange()
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
// CHECK: [[COERCE_CAST_PTR:%.*]] = getelementptr {{.*}} [[COERCE_CAST]], {{.*}}
// CHECK: [[COERCE_VAR_PTR:%.*]] = getelementptr {{.*}} [[COERCE]], {{.*}}
// CHECK: [[EXTR_RVAL:%.*]] = extractvalue {{.*}} [[RVAL]]{{.*}}
// CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_CAST_PTR]]{{.*}}
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_VAR_PTR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[COERCE]], ptr {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
NSValue *range_rvalue = @(getRange());
// CHECK: call void @llvm.objc.release
// CHECK: ret void

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s
// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s
#import "nsvalue-boxed-expressions-support.h"
@ -17,14 +17,10 @@ void doRange(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSRange ns_range = { .location = 0, .length = 42 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr noundef {{.*}}[[RANGE_STR]]{{.*}})
NSValue *range = @(ns_range);
// CHECK: ret void
}
@ -34,14 +30,10 @@ void doPoint(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSPoint{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSPoint{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSPoint* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSPoint ns_point = { .x = 42, .y = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[POINT_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr noundef {{.*}}[[POINT_STR]]{{.*}})
NSValue *point = @(ns_point);
// CHECK: ret void
}
@ -51,14 +43,10 @@ void doSize(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSSize{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSSize{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSSize* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSSize ns_size = { .width = 42, .height = 24 };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[SIZE_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr noundef {{.*}}[[SIZE_STR]]{{.*}})
NSValue *size = @(ns_size);
// CHECK: ret void
}
@ -68,16 +56,12 @@ void doRect(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRect{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRect{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRect* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSPoint ns_point = { .x = 42, .y = 24 };
NSSize ns_size = { .width = 42, .height = 24 };
NSRect ns_rect = { .origin = ns_point, .size = ns_size };
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[RECT_STR]]{{.*}})
NSValue *rect = @(ns_rect);
// CHECK: ret void
}
@ -87,14 +71,10 @@ void doNSEdgeInsets(void) {
// CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[TEMP_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_VAR]]{{.*}} [[LOCAL_VAR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
NSEdgeInsets ns_edge_insets;
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}})
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[TEMP_VAR]], ptr{{.*}}[[EDGE_STR]]{{.*}})
NSValue *edge_insets = @(ns_edge_insets);
// CHECK: ret void
}
@ -104,14 +84,11 @@ void doRangeRValue(void) {
// CHECK: [[COERCE:%.*]] = alloca %struct._NSRange{{.*}}
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
// CHECK: [[RVAL:%.*]] = call {{.*}} @getRange()
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
// CHECK: [[COERCE_CAST_PTR:%.*]] = getelementptr {{.*}} [[COERCE_CAST]], {{.*}}
// CHECK: [[COERCE_VAR_PTR:%.*]] = getelementptr {{.*}} [[COERCE]], {{.*}}
// CHECK: [[EXTR_RVAL:%.*]] = extractvalue {{.*}} [[RVAL]]{{.*}}
// CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_CAST_PTR]]{{.*}}
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
// CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_VAR_PTR]]{{.*}}
// CHECK: [[SEL:%.*]] = load ptr, ptr [[VALUE_SEL]]
// CHECK: call {{.*objc_msgSend.*}}(ptr noundef [[RECV_PTR]], ptr noundef [[SEL]], ptr noundef [[COERCE]], ptr noundef {{.*}}[[RANGE_STR]]{{.*}})
NSValue *range_rvalue = @(getRange());
// CHECK: ret void
}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64e-apple-ios15.0.0 -emit-llvm-bc -fobjc-arc -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple arm64e-apple-ios15.0.0 -emit-llvm-bc -fobjc-arc -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
// rdar://73361264
@ -28,7 +28,7 @@ typedef struct {
@end
// CHECK-LABEL: msgSend.call:
// CHECK: [[CALL:%[^ ]+]] = call i1 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to
// CHECK: [[CALL:%[^ ]+]] = call i1 @objc_msgSend
// CHECK-NEXT: br label %msgSend.cont
// CHECK-LABEL: msgSend.null-receiver:

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -fobjc-arc -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
// RUN: %clang_cc1 -fobjc-arc -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
@interface NSMutableArray
- (id)objectAtIndexedSubscript:(int)index;
@ -11,11 +11,10 @@ id func(void) {
return array[3];
}
// CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: [[SIX:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[call]]) [[NUW:#[0-9]+]]
// CHECK: [[ARRAY_CASTED:%.*]] = bitcast %0** {{%.*}} to i8**
// CHECK: call void @llvm.objc.storeStrong(i8** [[ARRAY_CASTED]], i8* null)
// CHECK: [[EIGHT:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[SIX]]) [[NUW]]
// CHECK: ret i8* [[EIGHT]]
// CHECK: [[call:%.*]] = call ptr @objc_msgSend
// CHECK: [[SIX:%.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[call]]) [[NUW:#[0-9]+]]
// CHECK: call void @llvm.objc.storeStrong(ptr {{%.*}}, ptr null)
// CHECK: [[EIGHT:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[SIX]]) [[NUW]]
// CHECK: ret ptr [[EIGHT]]
// CHECK: attributes [[NUW]] = { nounwind }

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
typedef unsigned int size_t;
@protocol P @end
@ -18,39 +18,35 @@ int main(void) {
id val;
id oldObject = array[10];
// CHECK: [[ARR:%.*]] = load {{%.*}} [[array:%.*]], align 8
// CHECK-NEXT: [[ARRC:%.*]] = bitcast {{%.*}} [[ARR]] to i8*
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* noundef [[ARRC]], i8* noundef [[SEL]], i32 noundef 10)
// CHECK-NEXT: store i8* [[CALL]], i8** [[OLDOBJ:%.*]], align 8
// CHECK: [[ARR:%.*]] = load {{.*}} [[array:%.*]], align 8
// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[CALL:%.*]] = call ptr @objc_msgSend(ptr noundef [[ARR]], ptr noundef [[SEL]], i32 noundef 10)
// CHECK-NEXT: store ptr [[CALL]], ptr [[OLDOBJ:%.*]], align 8
val = (array[10] = oldObject);
// CHECK: [[FOUR:%.*]] = load i8*, i8** [[oldObject:%.*]], align 8
// CHECK-NEXT: [[THREE:%.*]] = load {{%.*}} [[array:%.*]], align 8
// CHECK-NEXT: [[SIX:%.*]] = bitcast {{%.*}} [[THREE]] to i8*
// CHECK-NEXT: [[FIVE:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i32)*)(i8* noundef [[SIX]], i8* noundef [[FIVE]], i8* noundef [[FOUR]], i32 noundef 10)
// CHECK-NEXT: store i8* [[FOUR]], i8** [[val:%.*]]
// CHECK: [[FOUR:%.*]] = load ptr, ptr [[oldObject:%.*]], align 8
// CHECK-NEXT: [[THREE:%.*]] = load {{.*}} [[array:%.*]], align 8
// CHECK-NEXT: [[FIVE:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_.2
// CHECK-NEXT: call void @objc_msgSend(ptr noundef [[THREE]], ptr noundef [[FIVE]], ptr noundef [[FOUR]], i32 noundef 10)
// CHECK-NEXT: store ptr [[FOUR]], ptr [[val:%.*]]
NSMutableDictionary *dictionary;
id key;
id newObject;
oldObject = dictionary[key];
// CHECK: [[SEVEN:%.*]] = load {{%.*}} [[DICTIONARY:%.*]], align 8
// CHECK-NEXT: [[EIGHT:%.*]] = load i8*, i8** [[KEY:%.*]], align 8
// CHECK-NEXT: [[ELEVEN:%.*]] = bitcast {{%.*}} [[SEVEN]] to i8*
// CHECK-NEXT: [[TEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.4
// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[ELEVEN]], i8* noundef [[TEN]], i8* noundef [[EIGHT]])
// CHECK-NEXT: store i8* [[CALL1]], i8** [[oldObject:%.*]], align 8
// CHECK: [[SEVEN:%.*]] = load {{.*}} [[DICTIONARY:%.*]], align 8
// CHECK-NEXT: [[EIGHT:%.*]] = load ptr, ptr [[KEY:%.*]], align 8
// CHECK-NEXT: [[TEN:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_.4
// CHECK-NEXT: [[CALL1:%.*]] = call ptr @objc_msgSend(ptr noundef [[SEVEN]], ptr noundef [[TEN]], ptr noundef [[EIGHT]])
// CHECK-NEXT: store ptr [[CALL1]], ptr [[oldObject:%.*]], align 8
val = (dictionary[key] = newObject);
// CHECK: [[FOURTEEN:%.*]] = load i8*, i8** [[NEWOBJECT:%.*]], align 8
// CHECK-NEXT: [[TWELVE:%.*]] = load {{%.*}} [[DICTIONARY]], align 8
// CHECK-NEXT: [[THIRTEEN:%.*]] = load i8*, i8** [[KEY]], align 8
// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast {{%.*}} [[TWELVE]] to i8*
// CHECK-NEXT: [[SIXTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i8*)*)(i8* noundef [[SEVENTEEN]], i8* noundef [[SIXTEEN]], i8* noundef [[FOURTEEN]], i8* noundef [[THIRTEEN]])
// CHECK-NEXT: store i8* [[FOURTEEN]], i8** [[val:%.*]]
// CHECK: [[FOURTEEN:%.*]] = load ptr, ptr [[NEWOBJECT:%.*]], align 8
// CHECK-NEXT: [[TWELVE:%.*]] = load {{.*}} [[DICTIONARY]], align 8
// CHECK-NEXT: [[THIRTEEN:%.*]] = load ptr, ptr [[KEY]], align 8
// CHECK-NEXT: [[SIXTEEN:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_.6
// CHECK-NEXT: call void @objc_msgSend(ptr noundef [[TWELVE]], ptr noundef [[SIXTEEN]], ptr noundef [[FOURTEEN]], ptr noundef [[THIRTEEN]])
// CHECK-NEXT: store ptr [[FOURTEEN]], ptr [[val:%.*]]
}

View File

@ -1,11 +1,11 @@
// RUN: %clang_cc1 -no-opaque-pointers -fobjc-dispatch-method=mixed -triple i386-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK_NEW_DISPATCH %s
// RUN: %clang_cc1 -fobjc-dispatch-method=mixed -triple i386-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK_NEW_DISPATCH %s
//
// CHECK_NEW_DISPATCH-LABEL: define{{.*}} void @f0
// CHECK_NEW_DISPATCH: bitcast {{.*}}objc_msgSend_fixup_alloc
// CHECK_NEW_DISPATCH: @_objc_msgSend_fixup_alloc
// CHECK_NEW_DISPATCH-LABEL: define{{.*}} void @f1
// CHECK_NEW_DISPATCH: load {{.*}}OBJC_SELECTOR_REFERENCES
//
// RUN: %clang_cc1 -no-opaque-pointers -fobjc-dispatch-method=legacy -emit-llvm -o - %s | FileCheck -check-prefix=CHECK_OLD_DISPATCH %s
// RUN: %clang_cc1 -fobjc-dispatch-method=legacy -emit-llvm -o - %s | FileCheck -check-prefix=CHECK_OLD_DISPATCH %s
//
// CHECK_OLD_DISPATCH-LABEL: define {{.*}}void @f0
// CHECK_OLD_DISPATCH: load {{.*}}OBJC_SELECTOR_REFERENCES

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -no-opaque-pointers %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O2 -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-O2
// RUN: %clang_cc1 -no-opaque-pointers %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O0 | FileCheck %s --check-prefixes=CHECK,CHECK-O0
// RUN: %clang_cc1 -no-opaque-pointers %s -emit-llvm -o - -triple x86_64-darwin-apple -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-MRR
// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O2 -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-O2
// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O0 | FileCheck %s --check-prefixes=CHECK,CHECK-O0
// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-MRR
// 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
@ -20,37 +20,30 @@ extern __attribute__((visibility("default"))) NSString *GenString(void);
void os_log_pack_send(void *);
// CHECK-LABEL: define{{.*}} void @test_builtin_os_log1(
// CHECK: alloca i8*, align 8
// CHECK: %[[A_ADDR:.*]] = alloca i8*, align 8
// CHECK: %[[OS_LOG_ARG:.*]] = alloca %{{.*}}*, align 8
// CHECK-O2: %[[V0:.*]] = call i8* @llvm.objc.retain(
// CHECK-O2: store i8* %[[V0]], i8** %[[A_ADDR]], align 8,
// CHECK-O0: call void @llvm.objc.storeStrong(i8** %[[A_ADDR]], i8* %{{.*}})
// CHECK-O2: %[[V4:.*]] = call %{{.*}}* @GenString() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[CALL:.*]] = call %{{.*}}* @GenString()
// CHECK-O0: %[[V2:.*]] = bitcast %{{.*}}* %[[CALL]] to i8*
// CHECK-O0: %[[V3:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V2]])
// CHECK-O0: %[[V4:.*]] = bitcast i8* %[[V3]] to %{{.*}}*
// CHECK: %[[V5:.*]] = bitcast %{{.*}}* %[[V4]] to i8*
// CHECK: %[[V6:.*]] = call i8* @llvm.objc.retain(i8* %[[V5]])
// CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to %{{.*}}*
// CHECK: store %{{.*}}* %[[V7]], %{{.*}}** %[[OS_LOG_ARG]],
// CHECK: %[[V8:.*]] = ptrtoint %{{.*}}* %[[V7]] to i64
// CHECK: %[[V9:.*]] = load i8*, i8** %[[A_ADDR]], align 8
// CHECK: %[[V10:.*]] = ptrtoint i8* %[[V9]] to i64
// CHECK: call void @__os_log_helper_1_2_2_8_64_8_64(i8* noundef %{{.*}}, i64 noundef %[[V8]], i64 noundef %[[V10]])
// CHECK: %[[V11:.*]] = bitcast %{{.*}}* %[[V4]] to i8*
// CHECK: call void @llvm.objc.release(i8* %[[V11]])
// CHECK: call void @os_log_pack_send(i8* noundef %{{.*}})
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(%{{.*}}* %[[V7]])
// CHECK-O2: %[[V13:.*]] = load %{{.*}}*, %{{.*}}** %[[OS_LOG_ARG]], align 8
// CHECK-O2: %[[V14:.*]] = bitcast %{{.*}}* %[[V13]] to i8*
// CHECK-O2: call void @llvm.objc.release(i8* %[[V14]])
// CHECK-O2: %[[V15:.*]] = load i8*, i8** %[[A_ADDR]], align 8
// CHECK-O2: call void @llvm.objc.release(i8* %[[V15]])
// CHECK-O0: %[[V12:.*]] = bitcast %{{.*}}** %[[OS_LOG_ARG]] to i8**
// CHECK-O0: call void @llvm.objc.storeStrong(i8** %[[V12]], i8* null)
// CHECK-O0: call void @llvm.objc.storeStrong(i8** %[[A_ADDR]], i8* null)
// CHECK: alloca ptr, align 8
// CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8
// CHECK: %[[OS_LOG_ARG:.*]] = alloca ptr, align 8
// CHECK-O2: %[[V0:.*]] = call ptr @llvm.objc.retain(
// CHECK-O2: store ptr %[[V0]], ptr %[[A_ADDR]], align 8,
// CHECK-O0: call void @llvm.objc.storeStrong(ptr %[[A_ADDR]], ptr %{{.*}})
// CHECK-O2: %[[V3:.*]] = call ptr @GenString() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[CALL:.*]] = call ptr @GenString()
// CHECK-O0: %[[V3:.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %[[CALL]])
// CHECK: %[[V6:.*]] = call ptr @llvm.objc.retain(ptr %[[V3]])
// CHECK: store ptr %[[V6]], ptr %[[OS_LOG_ARG]],
// CHECK: %[[V8:.*]] = ptrtoint ptr %[[V6]] to i64
// CHECK: %[[V9:.*]] = load ptr, ptr %[[A_ADDR]], align 8
// CHECK: %[[V10:.*]] = ptrtoint ptr %[[V9]] to i64
// CHECK: call void @__os_log_helper_1_2_2_8_64_8_64(ptr noundef %{{.*}}, i64 noundef %[[V8]], i64 noundef %[[V10]])
// CHECK: call void @llvm.objc.release(ptr %[[V3]])
// CHECK: call void @os_log_pack_send(ptr noundef %{{.*}})
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(ptr %[[V6]])
// CHECK-O2: %[[V13:.*]] = load ptr, ptr %[[OS_LOG_ARG]], align 8
// CHECK-O2: call void @llvm.objc.release(ptr %[[V13]])
// CHECK-O2: %[[V15:.*]] = load ptr, ptr %[[A_ADDR]], align 8
// CHECK-O2: call void @llvm.objc.release(ptr %[[V15]])
// CHECK-O0: call void @llvm.objc.storeStrong(ptr %[[OS_LOG_ARG]], ptr null)
// CHECK-O0: call void @llvm.objc.storeStrong(ptr %[[A_ADDR]], ptr null)
// CHECK-MRR-LABEL: define{{.*}} void @test_builtin_os_log1(
// CHECK-MRR-NOT: call {{.*}} @llvm.objc
@ -70,25 +63,21 @@ void test_builtin_os_log2(void *buf, id __unsafe_unretained a) {
}
// CHECK-LABEL: define{{.*}} void @test_builtin_os_log3(
// CHECK: alloca i8*, align 8
// CHECK: %[[OS_LOG_ARG:.*]] = alloca i8*, align 8
// CHECK-O2: %[[V3:.*]] = call %{{.*}}* @GenString() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[CALL:.*]] = call %{{.*}}* @GenString()
// CHECK-O0: %[[V1:.*]] = bitcast %{{.*}}* %[[CALL]] to i8*
// CHECK-O0: %[[V2:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]])
// CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %{{.*}}*
// CHECK: %[[V4:.*]] = bitcast %{{.*}}* %[[V3]] to i8*
// CHECK: %[[V5:.*]] = call i8* @llvm.objc.retain(i8* %[[V4]])
// CHECK: store i8* %[[V5]], i8** %[[OS_LOG_ARG]], align 8
// CHECK: %[[V6:.*]] = ptrtoint i8* %[[V5]] to i64
// CHECK: call void @__os_log_helper_1_2_1_8_64(i8* noundef %{{.*}}, i64 noundef %[[V6]])
// CHECK: %[[V7:.*]] = bitcast %{{.*}}* %[[V3]] to i8*
// CHECK: call void @llvm.objc.release(i8* %[[V7]])
// CHECK: call void @os_log_pack_send(i8* noundef %{{.*}})
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(i8* %[[V5]])
// CHECK-O2: %[[V9:.*]] = load i8*, i8** %[[OS_LOG_ARG]], align 8
// CHECK-O2: call void @llvm.objc.release(i8* %[[V9]])
// CHECK-O0: call void @llvm.objc.storeStrong(i8** %[[OS_LOG_ARG]], i8* null)
// CHECK: alloca ptr, align 8
// CHECK: %[[OS_LOG_ARG:.*]] = alloca ptr, align 8
// CHECK-O2: %[[V2:.*]] = call ptr @GenString() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[CALL:.*]] = call ptr @GenString()
// CHECK-O0: %[[V2:.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %[[CALL]])
// CHECK: %[[V5:.*]] = call ptr @llvm.objc.retain(ptr %[[V2]])
// CHECK: store ptr %[[V5]], ptr %[[OS_LOG_ARG]], align 8
// CHECK: %[[V6:.*]] = ptrtoint ptr %[[V5]] to i64
// CHECK: call void @__os_log_helper_1_2_1_8_64(ptr noundef %{{.*}}, i64 noundef %[[V6]])
// CHECK: call void @llvm.objc.release(ptr %[[V2]])
// CHECK: call void @os_log_pack_send(ptr noundef %{{.*}})
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(ptr %[[V5]])
// CHECK-O2: %[[V9:.*]] = load ptr, ptr %[[OS_LOG_ARG]], align 8
// CHECK-O2: call void @llvm.objc.release(ptr %[[V9]])
// CHECK-O0: call void @llvm.objc.storeStrong(ptr %[[OS_LOG_ARG]], ptr null)
void test_builtin_os_log3(void *buf) {
__builtin_os_log_format(buf, "capabilities: %@", (id)GenString());
@ -96,31 +85,31 @@ void test_builtin_os_log3(void *buf) {
}
// CHECK-LABEL: define{{.*}} void @test_builtin_os_log4(
// CHECK: alloca i8*, align 8
// CHECK: %[[OS_LOG_ARG:.*]] = alloca i8*, align 8
// CHECK: %[[OS_LOG_ARG2:.*]] = alloca i8*, align 8
// CHECK-O2: %[[V4:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: alloca ptr, align 8
// CHECK: %[[OS_LOG_ARG:.*]] = alloca ptr, align 8
// CHECK: %[[OS_LOG_ARG2:.*]] = alloca ptr, align 8
// CHECK-O2: %[[V4:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[CALL:.*]] = call {{.*}} @objc_msgSend
// CHECK-O0: %[[V4:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]])
// CHECK: %[[V5:.*]] = call i8* @llvm.objc.retain(i8* %[[V4]])
// CHECK: store i8* %[[V5]], i8** %[[OS_LOG_ARG]], align 8
// CHECK: %[[V6:.*]] = ptrtoint i8* %[[V5]] to i64
// CHECK-O2: %[[V10:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[V4:.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %[[CALL]])
// CHECK: %[[V5:.*]] = call ptr @llvm.objc.retain(ptr %[[V4]])
// CHECK: store ptr %[[V5]], ptr %[[OS_LOG_ARG]], align 8
// CHECK: %[[V6:.*]] = ptrtoint ptr %[[V5]] to i64
// CHECK-O2: %[[V10:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-O0: %[[CALL1:.*]] = call {{.*}} @objc_msgSend
// CHECK-O0: %[[V10:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]])
// CHECK: %[[V11:.*]] = call i8* @llvm.objc.retain(i8* %[[V10]])
// CHECK: store i8* %[[V11]], i8** %[[OS_LOG_ARG2]], align 8
// CHECK: %[[V12:.*]] = ptrtoint i8* %[[V11]] to i64
// CHECK: call void @__os_log_helper_1_2_2_8_64_8_64(i8* noundef %{{.*}}, i64 noundef %[[V6]], i64 noundef %[[V12]])
// CHECK: call void @llvm.objc.release(i8* %[[V10]])
// CHECK: call void @llvm.objc.release(i8* %[[V4]])
// CHECK: call void @os_log_pack_send(i8* noundef %{{.*}})
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(i8* %[[V11]])
// CHECK-O2: %[[V14:.*]] = load i8*, i8** %[[OS_LOG_ARG2]], align 8
// CHECK-O2: call void @llvm.objc.release(i8* %[[V14]])
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(i8* %[[V5]])
// CHECK-O2: %[[V15:.*]] = load i8*, i8** %[[OS_LOG_ARG]], align 8
// CHECK-O2: call void @llvm.objc.release(i8* %[[V15]])
// CHECK-O0: %[[V10:.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %[[CALL1]])
// CHECK: %[[V11:.*]] = call ptr @llvm.objc.retain(ptr %[[V10]])
// CHECK: store ptr %[[V11]], ptr %[[OS_LOG_ARG2]], align 8
// CHECK: %[[V12:.*]] = ptrtoint ptr %[[V11]] to i64
// CHECK: call void @__os_log_helper_1_2_2_8_64_8_64(ptr noundef %{{.*}}, i64 noundef %[[V6]], i64 noundef %[[V12]])
// CHECK: call void @llvm.objc.release(ptr %[[V10]])
// CHECK: call void @llvm.objc.release(ptr %[[V4]])
// CHECK: call void @os_log_pack_send(ptr noundef %{{.*}})
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(ptr %[[V11]])
// CHECK-O2: %[[V14:.*]] = load ptr, ptr %[[OS_LOG_ARG2]], align 8
// CHECK-O2: call void @llvm.objc.release(ptr %[[V14]])
// CHECK-O2: call void (...) @llvm.objc.clang.arc.use(ptr %[[V5]])
// CHECK-O2: %[[V15:.*]] = load ptr, ptr %[[OS_LOG_ARG]], align 8
// CHECK-O2: call void @llvm.objc.release(ptr %[[V15]])
void test_builtin_os_log4(void *buf) {
__builtin_os_log_format(buf, "capabilities: %@ %@", [c m0], [C m1]);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -fblocks -fobjc-arc -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fobjc-arc -emit-llvm -o - %s | FileCheck %s
// Parameterized classes have no effect on code generation; this test
// mainly verifies that CodeGen doesn't assert when substituted types
@ -61,26 +61,22 @@ void printMe(NSString *name) { }
// CHECK-LABEL: define{{.*}} void @blockTest
void blockTest(NSMutableArray<void (^)(void)> *array, NSString *name) {
// CHECK-NOT: ret void
// CHECK: call i8* @llvm.objc.retainBlock
// CHECK: call ptr @llvm.objc.retainBlock
[array addObject: ^ { printMe(name); }];
// CHECK-NOT: ret void
array[0] = ^ { printMe(name); };
// CHECK: call i8* @llvm.objc.retainBlock
// CHECK: call ptr @llvm.objc.retainBlock
// CHECK: ret void
}
// CHECK-LABEL: define internal void @"\01-[Derived setDest:]
// CHECK: %[[SELFADDR:.*]] = alloca %[[SELFTY:.*]]*
// CHECK: %[[AADDR:.*]] = alloca %[[IVARTY:.*]]*
// CHECK: %[[V2:.*]] = load %[[IVARTY]]*, %[[IVARTY]]** %[[AADDR]]
// CHECK: %[[V3:.*]] = load %[[SELFTY]]*, %[[SELFTY]]** %[[SELFADDR]]
// CHECK: %[[IVAR:.*]] = load i64, i64* @"OBJC_IVAR_$_Base._destination"
// CHECK: %[[V4:.*]] = bitcast %[[SELFTY]]* %[[V3]] to i8*
// CHECK: %[[ADDPTR:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 %[[IVAR]]
// CHECK: %[[V5:.*]] = bitcast i8* %[[ADDPTR]] to %[[IVARTY]]**
// CHECK: %[[V6:.*]] = bitcast %[[IVARTY]]** %[[V5]] to i8**
// CHECK: %[[V7:.*]] = bitcast %[[IVARTY]]* %[[V2]] to i8*
// CHECK: call void @llvm.objc.storeStrong(i8** %[[V6]], i8* %[[V7]])
// CHECK: %[[SELFADDR:.*]] = alloca ptr
// CHECK: %[[AADDR:a.addr]] = alloca ptr
// CHECK: %[[V2:.*]] = load ptr, ptr %[[AADDR]]
// CHECK: %[[V3:.*]] = load ptr, ptr %[[SELFADDR]]
// CHECK: %[[IVAR:.*]] = load i64, ptr @"OBJC_IVAR_$_Base._destination"
// CHECK: %[[ADDPTR:.*]] = getelementptr inbounds i8, ptr %[[V3]], i64 %[[IVAR]]
// CHECK: call void @llvm.objc.storeStrong(ptr %[[ADDPTR]], ptr %[[V2]])
@interface Base<DestType> : NSObject {
DestType _destination;
@ -100,12 +96,11 @@ void blockTest(NSMutableArray<void (^)(void)> *array, NSString *name) {
// CHECK-LABEL: define internal void @"\01-[C0 foo1]"(
// CHECK: {{.*}} = alloca
// CHECK: {{.*}} = alloca
// CHECK: %[[D:.*]] = alloca %[[TY:.*]]*
// CHECK: %[[TEMP:.*]] = alloca %[[TY]]*
// CHECK: %[[V4:.*]] = load %[[TY]]*, %[[TY]]** %[[D]]
// CHECK: store %[[TY]]* %[[V4]], %[[TY]]** %[[TEMP]]
// CHECK: %[[V7:.*]] = bitcast %[[TY]]** %[[TEMP]] to i8**
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8**)*)(i8* noundef %{{.*}}, i8* noundef %{{.*}}, i8** noundef %[[V7]])
// CHECK: %[[D:.*]] = alloca ptr
// CHECK: %[[TEMP:.*]] = alloca ptr
// CHECK: %[[V4:.*]] = load ptr, ptr %[[D]]
// CHECK: store ptr %[[V4]], ptr %[[TEMP]]
// CHECK: call void @objc_msgSend(ptr noundef %{{.*}}, ptr noundef %{{.*}}, ptr noundef %[[TEMP]])
@interface P0<ObjectType> : NSObject
- (void)m0:(ObjectType *)first;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple x86_64-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x objective-c++ -triple x86_64-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -x objective-c++ -triple x86_64-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
// rdar: // 8399655
@interface TestClass
@ -14,5 +14,5 @@ void FUNC (void) {
(void)obj.myGetter;
}
// CHECK: call i32 bitcast
// CHECK: call double bitcast
// CHECK: call i32
// CHECK: call double

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// rdar://8966864
@interface Foo
@ -10,8 +10,8 @@ void bar(Foo *x) {
x.myfo++;
}
// CHECK: [[C1:%.*]] = call float bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: [[C1:%.*]] = call float @objc_msgSend
// CHECK: [[I:%.*]] = fadd float [[C1]], 1.000000e+00
// CHECK: [[CONV:%.*]] = fptosi float [[I]] to i32
// CHECK: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: [[T3:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_.2
// CHECK: call void @objc_msgSend

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
// TODO: actually test most of this instead of just emitting it
@ -57,24 +57,20 @@ int printf(const char *, ...);
// CHECK-LABEL: define{{.*}} void @test2
A *test2_helper(void);
void test2(void) {
// CHECK: [[BASE:%.*]] = call [[A:%.*]]* @test2_helper()
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
// CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]])
// CHECK: [[BASE:%.*]] = call ptr @test2_helper()
// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr
// CHECK-NEXT: [[LD:%.*]] = call i32 @objc_msgSend(ptr noundef [[BASE]], ptr noundef [[SEL]])
// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LD]], 1
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]], i32 noundef [[ADD]])
// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr
// CHECK-NEXT: call void @objc_msgSend(ptr noundef [[BASE]], ptr noundef [[SEL]], i32 noundef [[ADD]])
test2_helper().dyn++;
// CHECK: [[BASE:%.*]] = call [[A]]* @test2_helper()
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
// CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]])
// CHECK: [[BASE:%.*]] = call ptr @test2_helper()
// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr
// CHECK-NEXT: [[LD:%.*]] = call i32 @objc_msgSend(ptr noundef [[BASE]], ptr noundef [[SEL]])
// CHECK-NEXT: [[ADD:%.*]] = mul nsw i32 [[LD]], 10
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]], i32 noundef [[ADD]])
// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr
// CHECK-NEXT: call void @objc_msgSend(ptr noundef [[BASE]], ptr noundef [[SEL]], i32 noundef [[ADD]])
test2_helper().dyn *= 10;
}
@ -97,9 +93,9 @@ void test3(test3_object *p) {
// CHECK-LABEL: define{{.*}} void @test4
void test4(Test4 *t) {
extern int test4_printf(const char *, ...);
// CHECK: [[TMP:%.*]] = call float {{.*}} @objc_msgSend
// CHECK: [[TMP:%.*]] = call float @objc_msgSend
// CHECK-NEXT: [[EXT:%.*]] = fpext float [[TMP]] to double
// CHECK-NEXT: call i32 (i8*, ...) @test4_printf(i8* {{.*}}, double noundef [[EXT]])
// CHECK-NEXT: call i32 (ptr, ...) @test4_printf(ptr {{.*}}, double noundef [[EXT]])
// CHECK-NEXT: ret void
test4_printf("%.2f", t.f);
}
@ -132,37 +128,31 @@ void test7(Test7 *t) {
t.x |= 5;
t.x ^= 8;
}
// CHECK: define{{.*}} void @test7([[TEST7:%.*]]*
// CHECK: [[T:%.*]] = alloca [[TEST7]]*,
// CHECK: define{{.*}} void @test7(ptr
// CHECK: [[T:%.*]] = alloca ptr,
// CHECK-NEXT: store
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]], align
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
// CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 2
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: call void bitcast
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: call void
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]], align
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
// CHECK-NEXT: [[T4:%.*]] = or i32 [[T3]], 5
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: call void bitcast
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: call void
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]], align
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
// CHECK-NEXT: [[T4:%.*]] = xor i32 [[T3]], 8
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: call void bitcast
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: call void
// CHECK-NEXT: ret void

View File

@ -1,19 +1,19 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// CHECK: @"_OBJC_$_PROTOCOL_METHOD_TYPES_P1" = internal global
// CHECK: @[[PROTO_P1:"_OBJC_PROTOCOL_\$_P1"]] = weak hidden
// CHECK: @[[LABEL_PROTO_P1:"_OBJC_LABEL_PROTOCOL_\$_P1"]] = weak hidden global %{{.*}}* @[[PROTO_P1]]
// CHECK: @[[LABEL_PROTO_P1:"_OBJC_LABEL_PROTOCOL_\$_P1"]] = weak hidden global ptr @[[PROTO_P1]]
// CHECK: @[[PROTO_P2:"_OBJC_PROTOCOL_\$_P2"]] = weak hidden
// CHECK: @[[LABEL_PROTO_P2:"_OBJC_LABEL_PROTOCOL_\$_P2"]] = weak hidden global %{{.*}}* @[[PROTO_P2]]
// CHECK: @"_OBJC_$_PROTOCOL_REFS_P3" = internal global { i64, [3 x %{{.*}}] } { i64 2, [3 x %{{.*}}*] [%{{.*}}* @[[PROTO_P1]], %{{.*}}* @[[PROTO_P2]], %{{.*}}* null] }
// CHECK: @[[LABEL_PROTO_P2:"_OBJC_LABEL_PROTOCOL_\$_P2"]] = weak hidden global ptr @[[PROTO_P2]]
// CHECK: @"_OBJC_$_PROTOCOL_REFS_P3" = internal global { i64, [3 x ptr] } { i64 2, [3 x ptr] [ptr @[[PROTO_P1]], ptr @[[PROTO_P2]], ptr null] }
// CHECK: @[[PROTO_P3:"_OBJC_PROTOCOL_\$_P3"]] = weak hidden
// CHECK: @[[LABEL_PROTO_P3:"_OBJC_LABEL_PROTOCOL_\$_P3"]] = weak hidden global %{{.*}}* @[[PROTO_P3]]
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P3" = weak hidden global %{{.*}}* bitcast (%{{.*}}* @[[PROTO_P3]] to %{{.*}}*)
// CHECK: @[[LABEL_PROTO_P3:"_OBJC_LABEL_PROTOCOL_\$_P3"]] = weak hidden global ptr @[[PROTO_P3]]
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P3" = weak hidden global ptr @[[PROTO_P3]]
// CHECK: @[[PROTO_P0:"_OBJC_PROTOCOL_\$_P0"]] = weak hidden
// CHECK: @[[LABEL_PROTO_P0:"_OBJC_LABEL_PROTOCOL_\$_P0"]] = weak hidden global %{{.*}}* @[[PROTO_P0]]
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P0" = weak hidden global %0* bitcast (%{{.*}}* @[[PROTO_P0]] to %{{.*}}*)
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P1" = weak hidden global %0* bitcast (%{{.*}}* @[[PROTO_P1]] to %{{.*}}*)
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P2" = weak hidden global %0* bitcast (%{{.*}}* @[[PROTO_P2]] to %{{.*}}*)
// CHECK: @[[LABEL_PROTO_P0:"_OBJC_LABEL_PROTOCOL_\$_P0"]] = weak hidden global ptr @[[PROTO_P0]]
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P0" = weak hidden global ptr @[[PROTO_P0]]
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P1" = weak hidden global ptr @[[PROTO_P1]]
// CHECK: "_OBJC_PROTOCOL_REFERENCE_$_P2" = weak hidden global ptr @[[PROTO_P2]]
void p(const char*, ...);

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-darwin -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-darwin -fobjc-arc -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK,ARC
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -fobjc-arc -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK,ARC
// RUN: %clang_cc1 -triple arm64-apple-darwin -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-darwin -fobjc-arc -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK,ARC
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK,ARC
struct stret { int x[100]; };
struct stret one = {{1}};
@ -14,16 +14,16 @@ struct stret one = {{1}};
void foo(id o, id p) {
[o method];
// CHECK: @llvm.lifetime.start
// CHECK: call void bitcast {{.*}} @objc_msgSend
// CHECK: call void @objc_msgSend
// CHECK: @llvm.lifetime.end
// CHECK-NOT: call void @llvm.memset
[o methodConsuming:p];
// ARC: [[T0:%.*]] = icmp eq i8*
// ARC: [[T0:%.*]] = icmp eq ptr
// ARC: br i1 [[T0]]
// CHECK: @llvm.lifetime.start
// CHECK: call void bitcast {{.*}} @objc_msgSend
// CHECK: call void @objc_msgSend
// CHECK: @llvm.lifetime.end
// ARC: br label

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -no-opaque-pointers -DSTRET -triple x86_64-pc-linux-gnu -fobjc-runtime=objfw -emit-llvm -o - %s | FileCheck -check-prefix=HASSTRET %s
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-pc-linux-gnu -fobjc-runtime=gcc -emit-llvm -o - %s | FileCheck -check-prefix=NOSTRET %s
// RUN: %clang_cc1 -DSTRET -triple x86_64-pc-linux-gnu -fobjc-runtime=objfw -emit-llvm -o - %s | FileCheck -check-prefix=HASSTRET %s
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fobjc-runtime=gcc -emit-llvm -o - %s | FileCheck -check-prefix=NOSTRET %s
// Test stret lookup
@ -19,11 +19,9 @@ void test0(void) {
}
// HASSTRET-LABEL: define{{.*}} void @test0()
// HASSTRET: [[T0:%.*]] = call i8* (i8*, i8*, ...)* @objc_msg_lookup_stret(i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*),
// HASSTRET-NEXT: [[T1:%.*]] = bitcast i8* (i8*, i8*, ...)* [[T0]] to void (%struct.test*, i8*, i8*)*
// HASSTRET-NEXT: call void [[T1]](%struct.test* sret(%struct.test) {{.*}}, i8* noundef bitcast (i64* @_OBJC_CLASS_Test0 to i8*),
// HASSTRET: [[T0:%.*]] = call ptr @objc_msg_lookup_stret(ptr @_OBJC_CLASS_Test0,
// HASSTRET-NEXT: call void [[T0]](ptr sret(%struct.test) {{.*}}, ptr noundef @_OBJC_CLASS_Test0,
// NOSTRET-LABEL: define{{.*}} void @test0()
// NOSTRET: [[T0:%.*]] = call i8* (i8*, i8*, ...)* @objc_msg_lookup(i8*
// NOSTRET-NEXT: [[T1:%.*]] = bitcast i8* (i8*, i8*, ...)* [[T0]] to void (%struct.test*, i8*, i8*)*
// NOSTRET-NEXT: call void [[T1]](%struct.test* sret(%struct.test) {{.*}}, i8* {{.*}}, i8* noundef bitcast ([2 x { i8*, i8* }]*
// NOSTRET: [[T0:%.*]] = call ptr @objc_msg_lookup(ptr
// NOSTRET-NEXT: call void [[T0]](ptr sret(%struct.test) {{.*}}, ptr {{.*}}, ptr noundef

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -no-opaque-pointers -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nonnull-attribute %s -o - -w | FileCheck %s
// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nonnull-attribute %s -o - -w | FileCheck %s
@interface A
@ -13,36 +13,36 @@
@implementation A
// CHECK-LABEL: define internal void @"\01-[A one_arg:]"
// CHECK-SAME: i32* noundef nonnull
// CHECK-SAME: ptr noundef nonnull
-(void) one_arg: (__attribute__((nonnull)) int *) arg1 {}
// CHECK-LABEL: define internal void @"\01-[A varargs:]"
// CHECK-SAME: i32* noundef nonnull
// CHECK-SAME: ptr noundef nonnull
-(void) varargs: (__attribute__((nonnull)) int *) arg1, ... {}
// CHECK-LABEL: define internal void @"\01+[A clsmethod:]"
// CHECK-SAME: i32* noundef nonnull
// CHECK-SAME: ptr noundef nonnull
+(void) clsmethod: (__attribute__((nonnull)) int *) arg1 {}
@end
// CHECK-LABEL: define{{.*}} void @call_A
void call_A(A *a, int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr [[P1:%.*]], null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
// CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* noundef [[P1]])
// CHECK: call void @objc_msgSend({{.*}}, ptr noundef [[P1]])
[a one_arg: p];
// CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr [[P2:%.*]], null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
// CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* noundef [[P2]], {{.*}})
// CHECK: call void (ptr, ptr, ptr, ...) @objc_msgSend({{.*}}, ptr noundef [[P2]], {{.*}})
[a varargs: p, p];
// CHECK: [[ICMP:%.*]] = icmp ne i32* [[P3:%.*]], null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr [[P3:%.*]], null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
// CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* noundef [[P3]])
// CHECK: call void @objc_msgSend({{.*}}, ptr noundef [[P3]])
[A clsmethod: p];
}

View File

@ -1,6 +1,6 @@
// REQUIRES: asserts
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fblocks -fobjc-arc -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fblocks -fobjc-arc -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fblocks -fobjc-arc -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fblocks -fobjc-arc -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 100, i32 6
// CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23
@ -16,14 +16,15 @@
#define INULL ((int *)NULL)
#define INNULL ((int *_Nonnull)NULL)
// CHECK-LABEL: define{{.*}} i32* @{{.*}}nonnull_retval1
// CHECK-LABEL: define{{.*}} ptr @{{.*}}nonnull_retval1
#line 100
int *_Nonnull nonnull_retval1(int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
// CHECK: nullcheck:
// CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
return p;
// CHECK: ret i32*
// CHECK: ret ptr
}
#line 190
@ -32,7 +33,7 @@ void nonnull_arg(int *_Nonnull p) {}
// CHECK-LABEL: define{{.*}} void @{{.*}}call_func_with_nonnull_arg
#line 200
void call_func_with_nonnull_arg(int *_Nonnull p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]]
nonnull_arg(p);
@ -41,7 +42,7 @@ void call_func_with_nonnull_arg(int *_Nonnull p) {
// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign1
#line 300
void nonnull_assign1(int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]]
int *_Nonnull local;
@ -51,7 +52,7 @@ void nonnull_assign1(int *p) {
// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign2
#line 400
void nonnull_assign2(int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]]
int *_Nonnull arr[1];
@ -65,7 +66,7 @@ struct S1 {
// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign3
#line 500
void nonnull_assign3(int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]]
// CHECK-NOT: call void @__ubsan_handle_type_mismatch
@ -76,7 +77,7 @@ void nonnull_assign3(int *p) {
// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init1
#line 600
void nonnull_init1(int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
int *_Nonnull local = p;
@ -85,37 +86,37 @@ void nonnull_init1(int *p) {
// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init2
#line 700
void nonnull_init2(int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]]
// CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
int *_Nonnull arr[] = {p, p};
}
// CHECK-LABEL: define{{.*}} i32* @{{.*}}nonnull_retval2
// CHECK-LABEL: define{{.*}} ptr @{{.*}}nonnull_retval2
#line 800
int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
int *_Nonnull arg2, //< Test this.
int *_Nullable arg3, //< Don't test the rest.
int *arg4,
int arg5, ...) {
// CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
// CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
// CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
// CHECK: [[ARG2CMP:%.*]] = icmp ne ptr %arg2, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
// CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
// CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null
// CHECK-NEXT: [[DO_RV_CHECK_3:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK_2]]
// CHECK: br i1 [[DO_RV_CHECK_3]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
// CHECK: [[NULL]]:
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]]
return arg1;
// CHECK: [[NONULL]]:
// CHECK-NEXT: ret i32*
// CHECK-NEXT: ret ptr
}
@interface A
@ -125,53 +126,53 @@ int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
@implementation A
// CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]"
// CHECK-LABEL: define internal ptr @"\01+[A objc_clsmethod:]"
+(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
// CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
// CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
// CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
// CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]]
// CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
// CHECK: [[NULL]]:
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_return{{.*}}
return arg1;
// CHECK: [[NONULL]]:
// CHECK-NEXT: ret i32*
// CHECK-NEXT: ret ptr
}
// CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
// CHECK-LABEL: define internal ptr @"\01-[A objc_method:]"
-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
// CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
// CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
// CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
// CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]]
// CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
// CHECK: [[NULL]]:
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
// CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_return{{.*}}
return arg1;
// CHECK: [[NONULL]]:
// CHECK-NEXT: ret i32*
// CHECK-NEXT: ret ptr
}
@end
// CHECK-LABEL: define{{.*}} void @{{.*}}call_A
void call_A(A *a, int *p) {
// CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr [[P1:%.*]], null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
// CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]])
// CHECK: call ptr @objc_msgSend({{.*}}, ptr [[P1]])
[a objc_method: p];
// CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
// CHECK: [[ICMP:%.*]] = icmp ne ptr [[P2:%.*]], null, !nosanitize
// CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
// CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]])
// CHECK: call ptr @objc_msgSend({{.*}}, ptr [[P2]])
[A objc_clsmethod: p];
}