mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 13:35:38 +08:00
[Clang] Convert some tests to opaque pointers (NFC)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin11 -emit-llvm -fobjc-arc -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-arc -o - %s | FileCheck %s
|
||||
|
||||
id makeObject1() __attribute__((ns_returns_retained));
|
||||
id makeObject2() __attribute__((ns_returns_retained));
|
||||
@@ -6,16 +6,16 @@ void releaseObject(__attribute__((ns_consumed)) id);
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z20basicCorrectnessTestv
|
||||
void basicCorrectnessTest() {
|
||||
// CHECK: [[X:%.*]] = alloca i8*, align 8
|
||||
// CHECK-NEXT: [[OBJ1:%.*]] = call noundef i8* @_Z11makeObject1v()
|
||||
// CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8
|
||||
// CHECK: [[X:%.*]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: [[OBJ1:%.*]] = call noundef ptr @_Z11makeObject1v()
|
||||
// CHECK-NEXT: store ptr [[OBJ1]], ptr [[X]], align 8
|
||||
id x = makeObject1();
|
||||
|
||||
// CHECK-NEXT: [[OBJ2:%.*]] = call noundef i8* @_Z11makeObject2v()
|
||||
// CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* noundef [[OBJ2]])
|
||||
// CHECK-NEXT: [[OBJ2:%.*]] = call noundef ptr @_Z11makeObject2v()
|
||||
// CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(ptr noundef [[OBJ2]])
|
||||
releaseObject(makeObject2());
|
||||
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null)
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
@@ -30,20 +30,20 @@ void releaseObjectT(__attribute__((ns_consumed)) T);
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z12templateTestv
|
||||
void templateTest() {
|
||||
// CHECK: [[X:%.*]] = alloca i8*, align 8
|
||||
// CHECK-NEXT: [[OBJ1:%.*]] = call noundef i8* @_Z12makeObjectT1IU8__strongP11objc_objectET_v()
|
||||
// CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8
|
||||
// CHECK: [[X:%.*]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: [[OBJ1:%.*]] = call noundef ptr @_Z12makeObjectT1IU8__strongP11objc_objectET_v()
|
||||
// CHECK-NEXT: store ptr [[OBJ1]], ptr [[X]], align 8
|
||||
id x = makeObjectT1<id>();
|
||||
|
||||
// CHECK-NEXT: [[OBJ2:%.*]] = call noundef i8* @_Z12makeObjectT2IU8__strongP11objc_objectET_v()
|
||||
// CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* noundef [[OBJ2]])
|
||||
// CHECK-NEXT: [[OBJ2:%.*]] = call noundef ptr @_Z12makeObjectT2IU8__strongP11objc_objectET_v()
|
||||
// CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(ptr noundef [[OBJ2]])
|
||||
releaseObject(makeObjectT2<id>());
|
||||
|
||||
// CHECK-NEXT: [[OBJ3:%.*]] = call noundef i8* @_Z11makeObject1v()
|
||||
// CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(i8* noundef [[OBJ3]])
|
||||
// CHECK-NEXT: [[OBJ3:%.*]] = call noundef ptr @_Z11makeObject1v()
|
||||
// CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(ptr noundef [[OBJ3]])
|
||||
releaseObjectT(makeObject1());
|
||||
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null)
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
@@ -56,14 +56,14 @@ ForwardConsumed::ForwardConsumed(__attribute__((ns_consumed)) id x) {}
|
||||
|
||||
// CHECK: define{{.*}} void @_ZN15ForwardConsumedC2EP11objc_object(
|
||||
// CHECK-NOT: objc_retain
|
||||
// CHECK: store i8* {{.*}}, i8** [[X:%.*]],
|
||||
// CHECK: store ptr %x, ptr [[X:%.*]],
|
||||
// CHECK-NOT: [[X]]
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** [[X]], i8* null)
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
|
||||
|
||||
// CHECK: define{{.*}} void @_ZN15ForwardConsumedC1EP11objc_object(
|
||||
// CHECK-NOT: objc_retain
|
||||
// CHECK: store i8* {{.*}}, i8** [[X:%.*]],
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8** [[X]],
|
||||
// CHECK-NEXT: store i8* null, i8** [[X]],
|
||||
// CHECK-NEXT: call void @_ZN15ForwardConsumedC2EP11objc_object({{.*}}, i8* noundef [[T0]])
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** [[X]], i8* null)
|
||||
// CHECK: store ptr %x, ptr [[X:%.*]],
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[X]],
|
||||
// CHECK-NEXT: store ptr null, ptr [[X]],
|
||||
// CHECK-NEXT: call void @_ZN15ForwardConsumedC2EP11objc_object({{.*}}, ptr noundef [[T0]])
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)
|
||||
|
||||
@@ -1,33 +1,26 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime-has-weak -o - -std=c++11 %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime-has-weak -o - -std=c++11 %s | FileCheck %s
|
||||
|
||||
// CHECK: %[[TYPE:[a-z0-9]+]] = type opaque
|
||||
// CHECK: @[[CFSTRING:[a-z0-9_]+]] = private global %struct.__NSConstantString_tag
|
||||
@class NSString;
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test1v
|
||||
// CHECK: %[[ALLOCA:[A-Z]+]] = alloca %[[TYPE]]*
|
||||
// CHECK: %[[V0:[0-9]+]] = call i8* @llvm.objc.retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]]
|
||||
// CHECK: %[[V1:[0-9]+]] = bitcast i8* %[[V0]] to %[[TYPE]]*
|
||||
// CHECK: store %[[TYPE]]* %[[V1]], %[[TYPE]]** %[[ALLOCA]]
|
||||
// CHECK: %[[V2:[0-9]+]] = bitcast %[[TYPE]]** %[[ALLOCA]]
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** %[[V2]], i8* null)
|
||||
// CHECK: %[[ALLOCA:[A-Z]+]] = alloca ptr
|
||||
// CHECK: %[[V0:[0-9]+]] = call ptr @llvm.objc.retain(ptr @[[CFSTRING]]
|
||||
// CHECK: store ptr %[[V0]], ptr %[[ALLOCA]]
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr %[[ALLOCA]], ptr null)
|
||||
void test1() {
|
||||
constexpr NSString *S = @"abc";
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test2v
|
||||
// CHECK: %[[CONST:[a-zA-Z]+]] = alloca %[[TYPE]]*
|
||||
// CHECK: %[[REF_CONST:[a-zA-Z]+]] = alloca %[[TYPE]]*
|
||||
// CHECK: %[[V0:[0-9]+]] = call i8* @llvm.objc.retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]]
|
||||
// CHECK-NEXT: %[[V1:[0-9]+]] = bitcast i8* %[[V0]] to %[[TYPE]]*
|
||||
// CHECK-NEXT: store %[[TYPE]]* %[[V1]], %[[TYPE]]** %[[CONST]]
|
||||
// CHECK: %[[V2:[0-9]+]] = call i8* @llvm.objc.retain(i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]]
|
||||
// CHECK-NEXT: %[[V3:[0-9]+]] = bitcast i8* %[[V2]] to %[[TYPE]]*
|
||||
// CHECK-NEXT: store %[[TYPE]]* %[[V3]], %[[TYPE]]** %[[REF_CONST]]
|
||||
// CHECK: %[[V4:[0-9]+]] = bitcast %[[TYPE]]** %[[REF_CONST]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** %[[V4]], i8* null)
|
||||
// CHECK: %[[V5:[0-9]+]] = bitcast %[[TYPE]]** %[[CONST]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** %[[V5]], i8* null)
|
||||
// CHECK: %[[CONST:[a-zA-Z]+]] = alloca ptr
|
||||
// CHECK: %[[REF_CONST:[a-zA-Z]+]] = alloca ptr
|
||||
// CHECK: %[[V0:[0-9]+]] = call ptr @llvm.objc.retain(ptr @[[CFSTRING]]
|
||||
// CHECK-NEXT: store ptr %[[V0]], ptr %[[CONST]]
|
||||
// CHECK: %[[V2:[0-9]+]] = call ptr @llvm.objc.retain(ptr @[[CFSTRING]]
|
||||
// CHECK-NEXT: store ptr %[[V2]], ptr %[[REF_CONST]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr %[[REF_CONST]], ptr null)
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr %[[CONST]], ptr null)
|
||||
void test2() {
|
||||
constexpr NSString *Const = @"abc";
|
||||
// In IR RefConst should be initialized with Const initializer instead of
|
||||
@@ -36,15 +29,12 @@ void test2() {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test3v
|
||||
// CHECK: %[[WEAK_CONST:[a-zA-Z]+]] = alloca %[[TYPE]]*
|
||||
// CHECK: %[[REF_WEAK_CONST:[a-zA-Z]+]] = alloca %[[TYPE]]*
|
||||
// CHECK: %[[V0:[0-9]+]] = bitcast %[[TYPE]]** %[[WEAK_CONST]]
|
||||
// CHECK-NEXT: %[[V1:[0-9]+]] = call i8* @llvm.objc.initWeak(i8** %[[V0]], i8* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]]
|
||||
// CHECK: store %[[TYPE]]* bitcast (%struct.__NSConstantString_tag* @[[CFSTRING]] to %[[TYPE]]*), %[[TYPE]]** %[[REF_WEAK_CONST]]
|
||||
// CHECK: %[[V2:[0-9]+]] = bitcast %[[TYPE]]** %[[REF_WEAK_CONST]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** %[[V2]], i8* null)
|
||||
// CHECK: %[[V3:[0-9]+]] = bitcast %[[TYPE]]** %[[WEAK_CONST]]
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** %[[V3]])
|
||||
// CHECK: %[[WEAK_CONST:[a-zA-Z]+]] = alloca ptr
|
||||
// CHECK: %[[REF_WEAK_CONST:[a-zA-Z]+]] = alloca ptr
|
||||
// CHECK-NEXT: %[[V1:[0-9]+]] = call ptr @llvm.objc.initWeak(ptr %[[WEAK_CONST]], ptr @[[CFSTRING]]
|
||||
// CHECK: store ptr @[[CFSTRING]], ptr %[[REF_WEAK_CONST]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr %[[REF_WEAK_CONST]], ptr null)
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr %[[WEAK_CONST]])
|
||||
void test3() {
|
||||
__weak constexpr NSString *WeakConst = @"abc";
|
||||
NSString* RefWeakConst = WeakConst;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime-has-weak -o - -fobjc-arc-exceptions %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime-has-weak -o - -fobjc-arc-exceptions %s | FileCheck %s
|
||||
|
||||
@class Ety;
|
||||
|
||||
@@ -12,16 +12,12 @@ void test0(void) {
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test0v()
|
||||
// CHECK: [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
|
||||
// CHECK: [[E:%e]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: invoke void @_Z12test0_helperv()
|
||||
// CHECK: [[T0:%.*]] = call i8* @objc_begin_catch(
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) [[NUW:#[0-9]+]]
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
|
||||
// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) [[NUW]]
|
||||
// CHECK: [[T0:%.*]] = call ptr @objc_begin_catch(
|
||||
// CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]]) [[NUW:#[0-9]+]]
|
||||
// CHECK-NEXT: store ptr [[T3]], ptr [[E]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[E]], ptr null) [[NUW]]
|
||||
// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
|
||||
|
||||
void test1_helper(void);
|
||||
@@ -32,15 +28,11 @@ void test1(void) {
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test1v()
|
||||
// CHECK: [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
|
||||
// CHECK: [[E:%e]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: invoke void @_Z12test1_helperv()
|
||||
// CHECK: [[T0:%.*]] = call i8* @objc_begin_catch(
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
|
||||
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) [[NUW]]
|
||||
// CHECK: [[T0:%.*]] = call ptr @objc_begin_catch(
|
||||
// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[E]], ptr [[T0]]) [[NUW]]
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[E]]) [[NUW]]
|
||||
// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
|
||||
|
||||
void test2_helper(void);
|
||||
@@ -51,16 +43,12 @@ void test2(void) {
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test2v()
|
||||
// CHECK: [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
|
||||
// CHECK: [[E:%e]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: invoke void @_Z12test2_helperv()
|
||||
// CHECK: [[T0:%.*]] = call i8* @__cxa_begin_catch(
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retain(i8* [[T2]]) [[NUW]]
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
|
||||
// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[T0]], i8* null) [[NUW]]
|
||||
// CHECK: [[T0:%.*]] = call ptr @__cxa_begin_catch(
|
||||
// CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]]) [[NUW]]
|
||||
// CHECK-NEXT: store ptr [[T3]], ptr [[E]]
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[E]], ptr null) [[NUW]]
|
||||
// CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
|
||||
|
||||
void test3_helper(void);
|
||||
@@ -71,15 +59,11 @@ void test3(void) {
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test3v()
|
||||
// CHECK: [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
|
||||
// CHECK: [[E:%e]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: invoke void @_Z12test3_helperv()
|
||||
// CHECK: [[T0:%.*]] = call i8* @__cxa_begin_catch(
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
|
||||
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) [[NUW]]
|
||||
// CHECK: [[T0:%.*]] = call ptr @__cxa_begin_catch(
|
||||
// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[E]], ptr [[T0]]) [[NUW]]
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[E]]) [[NUW]]
|
||||
// CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
|
||||
|
||||
namespace test4 {
|
||||
@@ -94,29 +78,28 @@ namespace test4 {
|
||||
throw 0;
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_ZN5test41AC2Ev(
|
||||
// CHECK: [[THIS:%.*]] = load [[A:%.*]]*, [[A:%.*]]** {{%.*}}
|
||||
// CHECK: [[THIS:%.*]] = load ptr, ptr {{%.*}}
|
||||
// Construct single.
|
||||
// CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
|
||||
// CHECK-NEXT: store i8* null, i8** [[SINGLE]], align 8
|
||||
// CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[THIS]], i32 0, i32 0
|
||||
// CHECK-NEXT: store ptr null, ptr [[SINGLE]], align 8
|
||||
// Construct array.
|
||||
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [2 x [3 x i8*]]* [[ARRAY]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[T0]], i8 0, i64 48, i1 false)
|
||||
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[THIS]], i32 0, i32 1
|
||||
// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[ARRAY]], i8 0, i64 48, i1 false)
|
||||
// throw 0;
|
||||
// CHECK: invoke void @__cxa_throw(
|
||||
// Landing pad from throw site:
|
||||
// CHECK: landingpad
|
||||
// - First, destroy all of array.
|
||||
// CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x i8*]], [2 x [3 x i8*]]* [[ARRAY]], i32 0, i32 0, i32 0
|
||||
// CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds i8*, i8** [[ARRAYBEGIN]], i64 6
|
||||
// CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x ptr]], ptr [[ARRAY]], i32 0, i32 0, i32 0
|
||||
// CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds ptr, ptr [[ARRAYBEGIN]], i64 6
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: [[AFTER:%.*]] = phi i8** [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
|
||||
// CHECK-NEXT: [[ELT]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[ELT]], i8* null) [[NUW]]
|
||||
// CHECK-NEXT: [[DONE:%.*]] = icmp eq i8** [[ELT]], [[ARRAYBEGIN]]
|
||||
// CHECK: [[AFTER:%.*]] = phi ptr [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
|
||||
// CHECK-NEXT: [[ELT]] = getelementptr inbounds ptr, ptr [[AFTER]], i64 -1
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[ELT]], ptr null) [[NUW]]
|
||||
// CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]
|
||||
// CHECK-NEXT: br i1 [[DONE]],
|
||||
// - Next, destroy single.
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** [[SINGLE]], i8* null) [[NUW]]
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr [[SINGLE]], ptr null) [[NUW]]
|
||||
// CHECK: br label
|
||||
// CHECK: resume
|
||||
}
|
||||
@@ -132,26 +115,26 @@ void test5(void) {
|
||||
};
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test5v()
|
||||
// CHECK: [[ARRAY:%.*]] = alloca [2 x [2 x i8*]], align
|
||||
// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [2 x i8*]], [2 x [2 x i8*]]* [[ARRAY]], i64 0, i64 0
|
||||
// CHECK-NEXT: store [2 x i8*]* [[A0]],
|
||||
// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A0]], i64 0, i64 0
|
||||
// CHECK-NEXT: store i8** [[A00]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef i8* @_Z12test5_helperj(i32 noundef 0)
|
||||
// CHECK: store i8* [[T0]], i8** [[A00]], align
|
||||
// CHECK-NEXT: [[A01:%.*]] = getelementptr inbounds i8*, i8** [[A00]], i64 1
|
||||
// CHECK-NEXT: store i8** [[A01]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef i8* @_Z12test5_helperj(i32 noundef 1)
|
||||
// CHECK: store i8* [[T0]], i8** [[A01]], align
|
||||
// CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A0]], i64 1
|
||||
// CHECK-NEXT: store [2 x i8*]* [[A1]],
|
||||
// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A1]], i64 0, i64 0
|
||||
// CHECK-NEXT: store i8** [[A10]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef i8* @_Z12test5_helperj(i32 noundef 2)
|
||||
// CHECK: store i8* [[T0]], i8** [[A10]], align
|
||||
// CHECK-NEXT: [[A11:%.*]] = getelementptr inbounds i8*, i8** [[A10]], i64 1
|
||||
// CHECK-NEXT: store i8** [[A11]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef i8* @_Z12test5_helperj(i32 noundef 3)
|
||||
// CHECK: store i8* [[T0]], i8** [[A11]], align
|
||||
// CHECK: [[ARRAY:%.*]] = alloca [2 x [2 x ptr]], align
|
||||
// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [2 x ptr]], ptr [[ARRAY]], i64 0, i64 0
|
||||
// CHECK-NEXT: store ptr [[A0]],
|
||||
// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A0]], i64 0, i64 0
|
||||
// CHECK-NEXT: store ptr [[A00]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 0)
|
||||
// CHECK: store ptr [[T0]], ptr [[A00]], align
|
||||
// CHECK-NEXT: [[A01:%.*]] = getelementptr inbounds ptr, ptr [[A00]], i64 1
|
||||
// CHECK-NEXT: store ptr [[A01]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 1)
|
||||
// CHECK: store ptr [[T0]], ptr [[A01]], align
|
||||
// CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A0]], i64 1
|
||||
// CHECK-NEXT: store ptr [[A1]],
|
||||
// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A1]], i64 0, i64 0
|
||||
// CHECK-NEXT: store ptr [[A10]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 2)
|
||||
// CHECK: store ptr [[T0]], ptr [[A10]], align
|
||||
// CHECK-NEXT: [[A11:%.*]] = getelementptr inbounds ptr, ptr [[A10]], i64 1
|
||||
// CHECK-NEXT: store ptr [[A11]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 3)
|
||||
// CHECK: store ptr [[T0]], ptr [[A11]], align
|
||||
|
||||
// CHECK: attributes [[NUW]] = { nounwind }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
|
||||
// Test that we're properly retaining lifetime-qualified pointers
|
||||
// initialized statically and wrapping up those initialization in an
|
||||
@@ -6,21 +6,21 @@
|
||||
id getObject();
|
||||
|
||||
// CHECK-LABEL: define internal void @__cxx_global_var_init
|
||||
// CHECK: call noundef i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use
|
||||
// CHECK-NEXT: {{store i8*.*@global_obj}}
|
||||
// CHECK-NEXT: {{store ptr.*@global_obj}}
|
||||
// CHECK-NEXT: ret void
|
||||
id global_obj = getObject();
|
||||
|
||||
// CHECK-LABEL: define internal void @__cxx_global_var_init
|
||||
// CHECK: call noundef i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use
|
||||
// CHECK-NEXT: {{store i8*.*@global_obj2}}
|
||||
// CHECK-NEXT: {{store ptr.*@global_obj2}}
|
||||
// CHECK-NEXT: ret void
|
||||
id global_obj2 = getObject();
|
||||
|
||||
// CHECK-LABEL: define internal void @_GLOBAL__sub_I_arc_globals.mm
|
||||
// CHECK: call i8* @llvm.objc.autoreleasePoolPush()
|
||||
// CHECK: call ptr @llvm.objc.autoreleasePoolPush()
|
||||
// CHECK-NEXT: call void @__cxx_global_var_init
|
||||
// CHECK-NEXT: call void @__cxx_global_var_init.1
|
||||
// CHECK-NEXT: call void @llvm.objc.autoreleasePoolPop(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.13.0 -std=c++1z -fobjc-arc -fobjc-exceptions -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -std=c++1z -fobjc-arc -fobjc-exceptions -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
// CHECK: %[[V0:.*]] = type opaque
|
||||
// CHECK: %[[STRUCT_CLASS1:.*]] = type { %[[V0]]* }
|
||||
// CHECK: %[[STRUCT_CLASS1:.*]] = type { ptr }
|
||||
|
||||
@interface Class0;
|
||||
@end
|
||||
@@ -25,8 +24,8 @@ Class0 *g;
|
||||
|
||||
// CHECK: define {{.*}} @_Z4testv()
|
||||
// CHECK: invoke noundef zeroext i1 @_Z7getBoolv()
|
||||
// CHECK: landingpad { i8*, i32 }
|
||||
// CHECK: call void @_ZN6Class1D1Ev(%[[STRUCT_CLASS1]]* {{[^,]*}} %{{.*}})
|
||||
// CHECK: landingpad { ptr, i32 }
|
||||
// CHECK: call void @_ZN6Class1D1Ev(ptr {{[^,]*}} %{{.*}})
|
||||
// CHECK: br label
|
||||
|
||||
// CHECK: define linkonce_odr void @_ZN6Class1D1Ev(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -std=c++11 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -std=c++11 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
|
||||
// define{{.*}} void @_Z11simple_moveRU8__strongP11objc_objectS2_
|
||||
void simple_move(__strong id &x, __strong id &y) {
|
||||
// CHECK: = load i8*, i8**
|
||||
// CHECK: store i8* null
|
||||
// CHECK: = load i8*, i8**
|
||||
// CHECK: store i8*
|
||||
// CHECK: = load ptr, ptr
|
||||
// CHECK: store ptr null
|
||||
// CHECK: = load ptr, ptr
|
||||
// CHECK: store ptr
|
||||
// CHECK-NEXT: call void @llvm.objc.release
|
||||
x = static_cast<__strong id&&>(y);
|
||||
// CHECK-NEXT: ret void
|
||||
@@ -33,12 +33,12 @@ typename remove_reference<T>::type&& move(T &&x) {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z12library_moveRU8__strongP11objc_objectS2_
|
||||
void library_move(__strong id &x, __strong id &y) {
|
||||
// CHECK: call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
|
||||
// CHECK: load i8*, i8**
|
||||
// CHECK: store i8* null, i8**
|
||||
// CHECK: load i8**, i8***
|
||||
// CHECK-NEXT: load i8*, i8**
|
||||
// CHECK-NEXT: store i8*
|
||||
// CHECK: call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
|
||||
// CHECK: load ptr, ptr
|
||||
// CHECK: store ptr null, ptr
|
||||
// CHECK: load ptr, ptr
|
||||
// CHECK-NEXT: load ptr, ptr
|
||||
// CHECK-NEXT: store ptr
|
||||
// CHECK-NEXT: call void @llvm.objc.release
|
||||
// CHECK-NEXT: ret void
|
||||
x = move(y);
|
||||
@@ -46,40 +46,36 @@ void library_move(__strong id &x, __strong id &y) {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z12library_moveRU8__strongP11objc_object
|
||||
void library_move(__strong id &y) {
|
||||
// CHECK: [[X:%.*]] = alloca i8*, align 8
|
||||
// CHECK: [[X:%x]] = alloca ptr, align 8
|
||||
// CHECK: [[I:%.*]] = alloca i32, align 4
|
||||
// CHECK: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
|
||||
// CHECK: [[Y:%[a-zA-Z0-9]+]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
|
||||
// CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
|
||||
// CHECK: [[Y:%[a-zA-Z0-9]+]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
|
||||
// Load the object
|
||||
// CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8*, i8** [[Y]]
|
||||
// CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load ptr, ptr [[Y]]
|
||||
// Null out y
|
||||
// CHECK-NEXT: store i8* null, i8** [[Y]]
|
||||
// CHECK-NEXT: store ptr null, ptr [[Y]]
|
||||
// Initialize x with the object
|
||||
// CHECK-NEXT: store i8* [[OBJ]], i8** [[X:%[a-zA-Z0-9]+]]
|
||||
// CHECK-NEXT: store ptr [[OBJ]], ptr [[X:%[a-zA-Z0-9]+]]
|
||||
id x = move(y);
|
||||
|
||||
// CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[IPTR1]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]])
|
||||
// CHECK-NEXT: store i32 17
|
||||
int i = 17;
|
||||
// CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[IPTR2]])
|
||||
// CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8*, i8** [[X]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[OBJ]])
|
||||
// CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[XPTR2]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]])
|
||||
// CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load ptr, ptr [[X]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release(ptr [[OBJ]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[X]])
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z10const_moveRU8__strongKP11objc_object(
|
||||
void const_move(const __strong id &x) {
|
||||
// CHECK: [[Y:%.*]] = alloca i8*,
|
||||
// CHECK: [[X:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongKP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
|
||||
// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
|
||||
// CHECK: [[Y:%y]] = alloca ptr,
|
||||
// CHECK: [[X:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_Z4moveIRU8__strongKP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
|
||||
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
|
||||
// CHECK-NEXT: store ptr [[T1]], ptr [[Y]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])
|
||||
id y = move(x);
|
||||
}
|
||||
|
||||
@@ -1,44 +1,40 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=UNOPT
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-passes | FileCheck %s -check-prefix=CHECK -check-prefix=OPT
|
||||
// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=UNOPT
|
||||
// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-passes | FileCheck %s -check-prefix=CHECK -check-prefix=OPT
|
||||
|
||||
typedef __strong id strong_id;
|
||||
typedef __weak id weak_id;
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z8test_newP11objc_object
|
||||
void test_new(id invalue) {
|
||||
// CHECK: [[INVALUEADDR:%.*]] = alloca i8*
|
||||
// UNOPT-NEXT: store i8* null, i8** [[INVALUEADDR]]
|
||||
// UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]])
|
||||
// OPT-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* [[INVALUE:%.*]])
|
||||
// OPT-NEXT: store i8* [[T0]], i8** [[INVALUEADDR]]
|
||||
// CHECK: [[INVALUEADDR:%.*]] = alloca ptr
|
||||
// UNOPT-NEXT: store ptr null, ptr [[INVALUEADDR]]
|
||||
// UNOPT-NEXT: call void @llvm.objc.storeStrong(ptr [[INVALUEADDR]], ptr [[INVALUE:%.*]])
|
||||
// OPT-NEXT: [[T0:%.*]] = call ptr @llvm.objc.retain(ptr [[INVALUE:%.*]])
|
||||
// OPT-NEXT: store ptr [[T0]], ptr [[INVALUEADDR]]
|
||||
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull i8* @_Znwm
|
||||
// CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
|
||||
// CHECK-NEXT: store i8* null, i8**
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm
|
||||
// CHECK-NEXT: store ptr null, ptr
|
||||
new strong_id;
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull i8* @_Znwm
|
||||
// CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
|
||||
// UNOPT-NEXT: store i8* null, i8**
|
||||
// OPT-NEXT: call i8* @llvm.objc.initWeak(i8** {{.*}}, i8* null)
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm
|
||||
// UNOPT-NEXT: store ptr null, ptr
|
||||
// OPT-NEXT: call ptr @llvm.objc.initWeak(ptr {{.*}}, ptr null)
|
||||
new weak_id;
|
||||
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull i8* @_Znwm
|
||||
// CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
|
||||
// CHECK-NEXT: store i8* null, i8**
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm
|
||||
// CHECK-NEXT: store ptr null, ptr
|
||||
new __strong id;
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull i8* @_Znwm
|
||||
// CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
|
||||
// UNOPT-NEXT: store i8* null, i8**
|
||||
// OPT-NEXT: call i8* @llvm.objc.initWeak(i8** {{.*}}, i8* null)
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm
|
||||
// UNOPT-NEXT: store ptr null, ptr
|
||||
// OPT-NEXT: call ptr @llvm.objc.initWeak(ptr {{.*}}, ptr null)
|
||||
new __weak id;
|
||||
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull i8* @_Znwm
|
||||
// CHECK: call i8* @llvm.objc.retain
|
||||
// CHECK: store i8*
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm
|
||||
// CHECK: call ptr @llvm.objc.retain
|
||||
// CHECK: store ptr
|
||||
new __strong id(invalue);
|
||||
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull i8* @_Znwm
|
||||
// CHECK: call i8* @llvm.objc.initWeak
|
||||
// CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm
|
||||
// CHECK: call ptr @llvm.objc.initWeak
|
||||
new __weak id(invalue);
|
||||
|
||||
// UNOPT: call void @llvm.objc.storeStrong
|
||||
@@ -48,14 +44,14 @@ void test_new(id invalue) {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z14test_array_new
|
||||
void test_array_new() {
|
||||
// CHECK: call noalias noundef nonnull i8* @_Znam
|
||||
// CHECK: store i64 17, i64*
|
||||
// CHECK: call void @llvm.memset.p0i8.i64
|
||||
// CHECK: call noalias noundef nonnull ptr @_Znam
|
||||
// CHECK: store i64 17, ptr
|
||||
// CHECK: call void @llvm.memset.p0.i64
|
||||
new strong_id[17];
|
||||
|
||||
// CHECK: call noalias noundef nonnull i8* @_Znam
|
||||
// CHECK: store i64 17, i64*
|
||||
// CHECK: call void @llvm.memset.p0i8.i64
|
||||
// CHECK: call noalias noundef nonnull ptr @_Znam
|
||||
// CHECK: store i64 17, ptr
|
||||
// CHECK: call void @llvm.memset.p0.i64
|
||||
new weak_id[17];
|
||||
// CHECK: ret void
|
||||
}
|
||||
@@ -63,8 +59,8 @@ void test_array_new() {
|
||||
// CHECK-LABEL: define{{.*}} void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_
|
||||
void test_delete(__strong id *sptr, __weak id *wptr) {
|
||||
// CHECK: br i1
|
||||
// UNOPT: call void @llvm.objc.storeStrong(i8** {{.*}}, i8* null)
|
||||
// OPT: load i8*, i8**
|
||||
// UNOPT: call void @llvm.objc.storeStrong(ptr {{.*}}, ptr null)
|
||||
// OPT: load ptr, ptr
|
||||
// OPT-NEXT: call void @llvm.objc.release
|
||||
// CHECK: call void @_ZdlPv
|
||||
delete sptr;
|
||||
@@ -78,27 +74,27 @@ void test_delete(__strong id *sptr, __weak id *wptr) {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z17test_array_deletePU8__strongP11objc_objectPU6__weakS0_
|
||||
void test_array_delete(__strong id *sptr, __weak id *wptr) {
|
||||
// CHECK: icmp eq i8** [[BEGIN:%.*]], null
|
||||
// CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}}
|
||||
// CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]]
|
||||
// CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
|
||||
// CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
|
||||
// CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
|
||||
// UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[CUR]], i8* null)
|
||||
// OPT-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]]
|
||||
// OPT-NEXT: llvm.objc.release(i8* [[T0]])
|
||||
// CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
|
||||
// CHECK: icmp eq ptr [[BEGIN:%.*]], null
|
||||
// CHECK: [[LEN:%.*]] = load i64, ptr {{%.*}}
|
||||
// CHECK: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 [[LEN]]
|
||||
// CHECK-NEXT: icmp eq ptr [[BEGIN]], [[END]]
|
||||
// CHECK: [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
|
||||
// CHECK-NEXT: [[CUR]] = getelementptr inbounds ptr, ptr [[PAST]], i64 -1
|
||||
// UNOPT-NEXT: call void @llvm.objc.storeStrong(ptr [[CUR]], ptr null)
|
||||
// OPT-NEXT: [[T0:%.*]] = load ptr, ptr [[CUR]]
|
||||
// OPT-NEXT: llvm.objc.release(ptr [[T0]])
|
||||
// CHECK-NEXT: icmp eq ptr [[CUR]], [[BEGIN]]
|
||||
// CHECK: call void @_ZdaPv
|
||||
delete [] sptr;
|
||||
|
||||
// CHECK: icmp eq i8** [[BEGIN:%.*]], null
|
||||
// CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}}
|
||||
// CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]]
|
||||
// CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
|
||||
// CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
|
||||
// CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[CUR]])
|
||||
// CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
|
||||
// CHECK: icmp eq ptr [[BEGIN:%.*]], null
|
||||
// CHECK: [[LEN:%.*]] = load i64, ptr {{%.*}}
|
||||
// CHECK: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 [[LEN]]
|
||||
// CHECK-NEXT: icmp eq ptr [[BEGIN]], [[END]]
|
||||
// CHECK: [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
|
||||
// CHECK-NEXT: [[CUR]] = getelementptr inbounds ptr, ptr [[PAST]], i64 -1
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[CUR]])
|
||||
// CHECK-NEXT: icmp eq ptr [[CUR]], [[BEGIN]]
|
||||
// CHECK: call void @_ZdaPv
|
||||
delete [] wptr;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
|
||||
@interface A
|
||||
@end
|
||||
@@ -9,14 +9,14 @@ void callee();
|
||||
// Lifetime extension for binding a reference to an rvalue
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test0v()
|
||||
void test0() {
|
||||
// CHECK: call noundef i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
|
||||
const __strong id &ref1 = getObject();
|
||||
// CHECK: call void @_Z6calleev
|
||||
callee();
|
||||
// CHECK: call noundef i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
|
||||
// CHECK-NEXT: call i8* @llvm.objc.autorelease
|
||||
// CHECK-NEXT: call ptr @llvm.objc.autorelease
|
||||
const __autoreleasing id &ref2 = getObject();
|
||||
// CHECK: call void @_Z6calleev
|
||||
callee();
|
||||
@@ -38,23 +38,22 @@ typedef __strong id strong_id;
|
||||
|
||||
//CHECK: define{{.*}} void @_Z5test3v
|
||||
void test3() {
|
||||
// CHECK: [[REF:%.*]] = alloca i8**, align 8
|
||||
// CHECK: call i8* @llvm.objc.initWeak
|
||||
// CHECK-NEXT: store i8**
|
||||
// CHECK: [[REF:%.*]] = alloca ptr, align 8
|
||||
// CHECK: call ptr @llvm.objc.initWeak
|
||||
// CHECK-NEXT: store ptr
|
||||
const __weak id &ref = strong_id();
|
||||
// CHECK-NEXT: call void @_Z6calleev()
|
||||
callee();
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak
|
||||
// CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF]])
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test4RU8__strongP11objc_object
|
||||
void test4(__strong id &x) {
|
||||
// CHECK: call i8* @llvm.objc.retain
|
||||
// CHECK: call ptr @llvm.objc.retain
|
||||
__strong A* const &ar = x;
|
||||
// CHECK: store i32 17, i32*
|
||||
// CHECK: store i32 17, ptr
|
||||
int i = 17;
|
||||
// CHECK: call void @llvm.objc.release(
|
||||
// CHECK: ret void
|
||||
@@ -64,27 +63,23 @@ void sink(__strong A* &&);
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test5RU8__strongP11objc_object
|
||||
void test5(__strong id &x) {
|
||||
// CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8
|
||||
// CHECK: [[REFTMP:%.*]] = alloca ptr, align 8
|
||||
// CHECK: [[I:%.*]] = alloca i32, align 4
|
||||
// CHECK: [[OBJ_ID:%.*]] = call i8* @llvm.objc.retain(
|
||||
// CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*
|
||||
// CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]
|
||||
// CHECK: [[OBJ_ID:%.*]] = call ptr @llvm.objc.retain(
|
||||
// CHECK-NEXT: store ptr [[OBJ_ID]], ptr [[REFTMP:%[a-zA-Z0-9]+]]
|
||||
// CHECK-NEXT: call void @_Z4sinkOU8__strongP1A
|
||||
sink(x);
|
||||
// CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]]
|
||||
// CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*
|
||||
// CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load ptr, ptr [[REFTMP]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release
|
||||
// CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[IPTR1]])
|
||||
// CHECK-NEXT: store i32 17, i32
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I]])
|
||||
// CHECK-NEXT: store i32 17, ptr
|
||||
int i = 17;
|
||||
// CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[IPTR2]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[I]])
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define internal void @__cxx_global_var_init(
|
||||
// CHECK: call noundef i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
|
||||
const __strong id &global_ref = getObject();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -o - %s | FileCheck %s
|
||||
// rdar://10139365
|
||||
|
||||
@interface Test58
|
||||
@@ -13,10 +13,8 @@ void foo() {
|
||||
int i = [(ptr) reference_to_interior_int];
|
||||
}
|
||||
|
||||
// CHECK: [[T0:%.*]] = load {{%.*}} {{%.*}}, align 8
|
||||
// CHECK: [[T1:%.*]] = bitcast {{%.*}} [[T0]] to i8*
|
||||
// call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) nounwind
|
||||
// CHECK: [[T2:%.*]] = load {{%.*}} {{%.*}}, align 8
|
||||
// CHECK: [[T3:%.*]] = bitcast {{%.*}} [[T2]] to i8*
|
||||
// call i8* @llvm.objc.retainAutorelease(i8* [[T3]]) nounwind
|
||||
// CHECK: [[T0:%.*]] = load {{.*}} {{%.*}}, align 8
|
||||
// call ptr @llvm.objc.retainAutorelease(ptr [[T0]]) nounwind
|
||||
// CHECK: [[T2:%.*]] = load {{.*}} {{%.*}}, align 8
|
||||
// call ptr @llvm.objc.retainAutorelease(ptr [[T2]]) nounwind
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
|
||||
struct NSFastEnumerationState;
|
||||
@interface NSArray
|
||||
@@ -7,7 +7,7 @@ struct NSFastEnumerationState;
|
||||
count: (unsigned long) bufferSize;
|
||||
@end;
|
||||
NSArray *nsarray() { return 0; }
|
||||
// CHECK: define{{.*}} [[NSARRAY:%.*]]* @_Z7nsarrayv()
|
||||
// CHECK: define{{.*}} ptr @_Z7nsarrayv()
|
||||
|
||||
void use(id);
|
||||
|
||||
@@ -19,22 +19,22 @@ void test0(__weak id *wp, __weak volatile id *wvp) {
|
||||
// TODO: this is sub-optimal, we should retain at the actual call site.
|
||||
// TODO: in the non-volatile case, we do not need to be reloading.
|
||||
|
||||
// CHECK: [[T1:%.*]] = call noundef i8* @_Z12test0_helperv() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
|
||||
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]])
|
||||
// CHECK-NEXT: store i8* [[T4]], i8**
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
|
||||
// CHECK: [[T1:%.*]] = call noundef ptr @_Z12test0_helperv() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr {{%.*}}, align 8
|
||||
// CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.storeWeak(ptr [[T2]], ptr [[T1]])
|
||||
// CHECK-NEXT: [[T4:%.*]] = call ptr @llvm.objc.retain(ptr [[T3]])
|
||||
// CHECK-NEXT: store ptr [[T4]], ptr
|
||||
// CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
|
||||
id x = *wp = test0_helper();
|
||||
|
||||
// CHECK: [[T1:%.*]] = call noundef i8* @_Z12test0_helperv() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
|
||||
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T2]])
|
||||
// CHECK-NEXT: store i8* [[T4]], i8**
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
|
||||
// CHECK: [[T1:%.*]] = call noundef ptr @_Z12test0_helperv() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T1]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr {{%.*}}, align 8
|
||||
// CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.storeWeak(ptr [[T2]], ptr [[T1]])
|
||||
// CHECK-NEXT: [[T4:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T2]])
|
||||
// CHECK-NEXT: store ptr [[T4]], ptr
|
||||
// CHECK-NEXT: call void @llvm.objc.release(ptr [[T1]])
|
||||
id y = *wvp = test0_helper();
|
||||
}
|
||||
|
||||
@@ -42,11 +42,10 @@ void test0(__weak id *wp, __weak volatile id *wvp) {
|
||||
struct Test1_helper { Test1_helper(); };
|
||||
@interface Test1 @end
|
||||
@implementation Test1 { Test1_helper x; } @end
|
||||
// CHECK: define internal noundef i8* @"\01-[Test1 .cxx_construct]"(
|
||||
// CHECK: define internal noundef ptr @"\01-[Test1 .cxx_construct]"(
|
||||
// CHECK: call void @_ZN12Test1_helperC1Ev(
|
||||
// CHECK-NEXT: load
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: ret i8*
|
||||
// CHECK-NEXT: ret ptr
|
||||
|
||||
void test34(int cond) {
|
||||
__strong id strong;
|
||||
@@ -57,61 +56,59 @@ void test34(int cond) {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z6test34i(
|
||||
// CHECK: [[COND:%.*]] = alloca i32
|
||||
// CHECK-NEXT: [[STRONG:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[TEMP1:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[TEMP2:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[STRONG:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: [[WEAK:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: [[TEMP1:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: [[TEMP2:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1
|
||||
// CHECK-NEXT: store i32
|
||||
// CHECK-NEXT: [[STRONGP:%.*]] = bitcast i8** [[STRONG]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[STRONGP]])
|
||||
// CHECK-NEXT: store i8* null, i8** [[STRONG]]
|
||||
// CHECK-NEXT: [[WEAKP:%.*]] = bitcast i8** [[WEAK]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[WEAKP]])
|
||||
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[WEAK]], i8* null)
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[STRONG]])
|
||||
// CHECK-NEXT: store ptr null, ptr [[STRONG]]
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[WEAK]])
|
||||
// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[WEAK]], ptr null)
|
||||
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[COND]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[COND]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
|
||||
// CHECK: [[ARG:%.*]] = phi i8**
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
|
||||
// CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP1]]
|
||||
// CHECK: [[ARG:%.*]] = phi ptr
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[ARG]], null
|
||||
// CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], ptr null, ptr [[TEMP1]]
|
||||
// CHECK-NEXT: br i1 [[T0]],
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8** [[ARG]]
|
||||
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[ARG]]
|
||||
// CHECK-NEXT: store ptr [[T0]], ptr [[TEMP1]]
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: [[W0:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
|
||||
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** noundef [[T1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
|
||||
// CHECK: [[W0:%.*]] = phi ptr [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
|
||||
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(ptr noundef [[T1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[ARG]], null
|
||||
// CHECK-NEXT: br i1 [[T0]],
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP1]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[W0]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARG]]
|
||||
// CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[TEMP1]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]])
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[W0]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[ARG]]
|
||||
// CHECK-NEXT: store ptr [[T1]], ptr [[ARG]]
|
||||
// CHECK-NEXT: call void @llvm.objc.release(ptr [[T2]])
|
||||
// CHECK-NEXT: br label
|
||||
|
||||
// CHECK: [[T0:%.*]] = load i32, i32* [[COND]]
|
||||
// CHECK: [[T0:%.*]] = load i32, ptr [[COND]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
|
||||
// CHECK: [[ARG:%.*]] = phi i8**
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
|
||||
// CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]]
|
||||
// CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]]
|
||||
// CHECK: [[ARG:%.*]] = phi ptr
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[ARG]], null
|
||||
// CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], ptr null, ptr [[TEMP2]]
|
||||
// CHECK-NEXT: store i1 false, ptr [[CONDCLEANUP]]
|
||||
// CHECK-NEXT: br i1 [[T0]],
|
||||
// CHECK: [[T0:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[ARG]])
|
||||
// CHECK-NEXT: store i8* [[T0]], i8** [[CONDCLEANUPSAVE]]
|
||||
// CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]]
|
||||
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]]
|
||||
// CHECK: [[T0:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[ARG]])
|
||||
// CHECK-NEXT: store ptr [[T0]], ptr [[CONDCLEANUPSAVE]]
|
||||
// CHECK-NEXT: store i1 true, ptr [[CONDCLEANUP]]
|
||||
// CHECK-NEXT: store ptr [[T0]], ptr [[TEMP2]]
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** noundef [[T1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
|
||||
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(ptr noundef [[T1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[ARG]], null
|
||||
// CHECK-NEXT: br i1 [[T0]],
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8** [[TEMP2]]
|
||||
// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[ARG]], i8* [[T0]])
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[TEMP2]]
|
||||
// CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr [[ARG]], ptr [[T0]])
|
||||
// CHECK-NEXT: br label
|
||||
|
||||
// CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAK]])
|
||||
// CHECK: call void @llvm.objc.destroyWeak(ptr [[WEAK]])
|
||||
// CHECK: ret void
|
||||
}
|
||||
|
||||
@@ -125,26 +122,26 @@ struct Test35_Helper {
|
||||
// CHECK-LABEL: define{{.*}} void @_Z6test3513Test35_HelperPS_
|
||||
void test35(Test35_Helper x0, Test35_Helper *x0p) {
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* @_ZN13Test35_Helper11makeObject1Ev
|
||||
// CHECK-NOT: call i8* @llvm.objc.retain
|
||||
// CHECK: call noundef ptr @_ZN13Test35_Helper11makeObject1Ev
|
||||
// CHECK-NOT: call ptr @llvm.objc.retain
|
||||
id obj1 = Test35_Helper::makeObject1();
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* @_ZN13Test35_Helper11makeObject2Ev
|
||||
// CHECK-NOT: call i8* @llvm.objc.retain
|
||||
// CHECK: call noundef ptr @_ZN13Test35_Helper11makeObject2Ev
|
||||
// CHECK-NOT: call ptr @llvm.objc.retain
|
||||
id obj2 = x0.makeObject2();
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* @_ZN13Test35_Helper11makeObject2Ev
|
||||
// CHECK-NOT: call i8* @llvm.objc.retain
|
||||
// CHECK: call noundef ptr @_ZN13Test35_Helper11makeObject2Ev
|
||||
// CHECK-NOT: call ptr @llvm.objc.retain
|
||||
id obj3 = x0p->makeObject2();
|
||||
id (Test35_Helper::*pmf)() __attribute__((ns_returns_retained))
|
||||
= &Test35_Helper::makeObject2;
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* %
|
||||
// CHECK-NOT: call i8* @llvm.objc.retain
|
||||
// CHECK: call noundef ptr %
|
||||
// CHECK-NOT: call ptr @llvm.objc.retain
|
||||
id obj4 = (x0.*pmf)();
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* %
|
||||
// CHECK-NOT: call i8* @llvm.objc.retain
|
||||
// CHECK: call noundef ptr %
|
||||
// CHECK-NOT: call ptr @llvm.objc.retain
|
||||
id obj5 = (x0p->*pmf)();
|
||||
|
||||
// CHECK: call void @llvm.objc.release
|
||||
@@ -163,20 +160,20 @@ void test35(Test35_Helper x0, Test35_Helper *x0p) {
|
||||
// CHECK-LABEL: define{{.*}} void @_Z7test35b13Test35_HelperPS_
|
||||
void test35b(Test35_Helper x0, Test35_Helper *x0p) {
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* @_ZN13Test35_Helper11makeObject3Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_ZN13Test35_Helper11makeObject3Ev{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id obj1 = Test35_Helper::makeObject3();
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id obj2 = x0.makeObject4();
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id obj3 = x0p->makeObject4();
|
||||
id (Test35_Helper::*pmf)() = &Test35_Helper::makeObject4;
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* %{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr %{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id obj4 = (x0.*pmf)();
|
||||
// CHECK: call void @llvm.lifetime.start
|
||||
// CHECK: call noundef i8* %{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr %{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id obj5 = (x0p->*pmf)();
|
||||
|
||||
// CHECK: call void @llvm.objc.release
|
||||
@@ -194,7 +191,7 @@ void test35b(Test35_Helper x0, Test35_Helper *x0p) {
|
||||
}
|
||||
|
||||
// rdar://problem/9603128
|
||||
// CHECK-LABEL: define{{.*}} i8* @_Z6test36P11objc_object(
|
||||
// CHECK-LABEL: define{{.*}} ptr @_Z6test36P11objc_object(
|
||||
id test36(id z) {
|
||||
// CHECK: llvm.objc.retain
|
||||
// CHECK: llvm.objc.retain
|
||||
@@ -217,26 +214,22 @@ template <class T> void test37(T *a) {
|
||||
extern template void test37<Test37>(Test37 *a);
|
||||
template void test37<Test37>(Test37 *a);
|
||||
// CHECK-LABEL: define weak_odr void @_Z6test37I6Test37EvPT_(
|
||||
// CHECK: [[T2:%.*]] = call noundef [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)({{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: [[T2:%.*]] = call noundef ptr @objc_msgSend({{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T2]])
|
||||
|
||||
// Make sure it's not immediately released before starting the iteration.
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: @objc_msgSend
|
||||
|
||||
// This bitcast is for the mutation check.
|
||||
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
|
||||
// CHECK-NEXT: @objc_enumerationMutation
|
||||
// CHECK: @objc_enumerationMutation
|
||||
|
||||
// This bitcast is for the 'next' message send.
|
||||
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: @objc_msgSend
|
||||
|
||||
// This bitcast is for the final release.
|
||||
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
|
||||
// CHECK: call void @llvm.objc.release(ptr [[T2]])
|
||||
|
||||
template<typename T>
|
||||
void send_release() {
|
||||
@@ -244,9 +237,8 @@ void send_release() {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z12send_releaseIiEvv(
|
||||
// CHECK: call noundef %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call noundef ptr @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: call void @llvm.objc.release
|
||||
// CHECK-NEXT: ret void
|
||||
template void send_release<int>();
|
||||
@@ -257,12 +249,12 @@ Test37 *instantiate_init() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define weak_odr noundef %2* @_Z16instantiate_initIiEP6Test37v
|
||||
// CHECK: call noundef i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK: call noundef i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK: call i8* @llvm.objc.retain
|
||||
// CHECK-LABEL: define weak_odr noundef ptr @_Z16instantiate_initIiEP6Test37v
|
||||
// CHECK: call noundef ptr @objc_msgSend
|
||||
// CHECK: call noundef ptr @objc_msgSend
|
||||
// CHECK: call ptr @llvm.objc.retain
|
||||
// CHECK: call void @llvm.objc.release
|
||||
// CHECK: call i8* @llvm.objc.autoreleaseReturnValue
|
||||
// CHECK: call ptr @llvm.objc.autoreleaseReturnValue
|
||||
template Test37* instantiate_init<int>();
|
||||
|
||||
// Just make sure that the AST invariants hold properly here,
|
||||
@@ -289,9 +281,9 @@ class Test39 : Test39_base1, Test39_base2 { // base2 is at non-zero offset
|
||||
};
|
||||
id Test39::bar() { return 0; }
|
||||
// Note lack of autorelease.
|
||||
// CHECK-LABEL: define{{.*}} i8* @_ZThn8_N6Test393barEv(
|
||||
// CHECK: call noundef i8* @_ZN6Test393barEv(
|
||||
// CHECK-NEXT: ret i8*
|
||||
// CHECK-LABEL: define{{.*}} ptr @_ZThn8_N6Test393barEv(
|
||||
// CHECK: call noundef ptr @_ZN6Test393barEv(
|
||||
// CHECK-NEXT: ret ptr
|
||||
|
||||
// rdar://13617051
|
||||
// Just a basic correctness check that IR-gen still works after instantiating
|
||||
@@ -305,27 +297,26 @@ template <class T> void test40_helper() {
|
||||
};
|
||||
template void test40_helper<int>();
|
||||
// CHECK-LABEL: define weak_odr void @_Z13test40_helperIiEvv()
|
||||
// CHECK: [[X:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: [[XP:%.*]] = bitcast i8** [[X]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XP]])
|
||||
// CHECK-NEXT: store i8* null, i8** [[X]]
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8** [[X]]
|
||||
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]
|
||||
// CHECK: [[X:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: [[TEMP:%.*]] = alloca ptr
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]])
|
||||
// CHECK-NEXT: store ptr null, ptr [[X]]
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[X]]
|
||||
// CHECK-NEXT: store ptr [[T0]], ptr [[TEMP]]
|
||||
// CHECK: @objc_msgSend
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]]
|
||||
// CHECK-NEXT: call i8* @llvm.objc.retain(i8* [[T0]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[TEMP]]
|
||||
// CHECK-NEXT: call ptr @llvm.objc.retain(ptr [[T0]])
|
||||
|
||||
// Check that moves out of __weak variables are compiled to use objc_moveWeak.
|
||||
void test41(__weak id &&x) {
|
||||
__weak id y = static_cast<__weak id &&>(x);
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z6test41OU6__weakP11objc_object
|
||||
// CHECK: [[X:%.*]] = alloca i8**
|
||||
// CHECK: [[Y:%.*]] = alloca i8*
|
||||
// CHECK: [[T0:%.*]] = load i8**, i8*** [[X]]
|
||||
// CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[Y]], i8** [[T0]])
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Y]])
|
||||
// CHECK: [[X:%.*]] = alloca ptr
|
||||
// CHECK: [[Y:%.*]] = alloca ptr
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[X]]
|
||||
// CHECK-NEXT: call void @llvm.objc.moveWeak(ptr [[Y]], ptr [[T0]])
|
||||
// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[Y]])
|
||||
|
||||
void test42() {
|
||||
__attribute__((ns_returns_retained)) id test42_0();
|
||||
@@ -337,6 +328,6 @@ void test42() {
|
||||
// Check that the pointer returned by test42_0 is released after the full expression.
|
||||
|
||||
// CHECK-LABEL: define void @_Z6test42v()
|
||||
// CHECK: %[[CALL:.*]] = call noundef i8* @_Z8test42_0v()
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @_Z8test42_0v()
|
||||
// CHECK: call void @_Z8test42_2OU15__autoreleasingP11objc_object(
|
||||
// CHECK: call void @llvm.objc.release(i8* %[[CALL]])
|
||||
// CHECK: call void @llvm.objc.release(ptr %[[CALL]])
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple=x86_64-apple-darwin10 -emit-llvm -std=c++14 -fblocks -fobjc-arc -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -std=c++14 -fblocks -fobjc-arc -o - %s | FileCheck %s
|
||||
|
||||
// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
|
||||
// CHECK: %[[S:.*]] = type { i32 }
|
||||
// CHECK: %[[CLASS_ANON_2:.*]] = type { %[[S]]* }
|
||||
// CHECK: %[[CLASS_ANON_2:.*]] = type { ptr }
|
||||
// CHECK: %[[CLASS_ANON_3:.*]] = type { %[[S]] }
|
||||
|
||||
// CHECK: %[[BLOCK_CAPTURED0:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32*, i32* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32*, i32* }>* %[[BLOCK:.*]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[LAMBDA_CLASS:.*]], %[[LAMBDA_CLASS]]* %[[THIS:.*]], i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load i32*, i32** %[[V0]], align 8
|
||||
// CHECK: store i32* %[[V1]], i32** %[[BLOCK_CAPTURED0]], align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED1:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32*, i32* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32*, i32* }>* %[[BLOCK]], i32 0, i32 6
|
||||
// CHECK: %[[V2:.*]] = getelementptr inbounds %[[LAMBDA_CLASS]], %[[LAMBDA_CLASS]]* %[[THIS]], i32 0, i32 1
|
||||
// CHECK: %[[V3:.*]] = load i32*, i32** %[[V2]], align 8
|
||||
// CHECK: store i32* %[[V3]], i32** %[[BLOCK_CAPTURED1]], align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED0:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr }>, ptr %[[BLOCK:.*]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[LAMBDA_CLASS:.*]], ptr %[[THIS:.*]], i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load ptr, ptr %[[V0]], align 8
|
||||
// CHECK: store ptr %[[V1]], ptr %[[BLOCK_CAPTURED0]], align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED1:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 6
|
||||
// CHECK: %[[V2:.*]] = getelementptr inbounds %[[LAMBDA_CLASS]], ptr %[[THIS]], i32 0, i32 1
|
||||
// CHECK: %[[V3:.*]] = load ptr, ptr %[[V2]], align 8
|
||||
// CHECK: store ptr %[[V3]], ptr %[[BLOCK_CAPTURED1]], align 8
|
||||
|
||||
void foo1(int &, int &);
|
||||
|
||||
@@ -37,8 +36,8 @@ void use(id);
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_ZN18CaptureByReference5test0Ev(
|
||||
// CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test0EvENK3$_0clEv"(
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>* %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i64 }* @"__block_descriptor_40_e5_v8\01?0ls32l8" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store ptr @"__block_descriptor_40_e5_v8\01?0ls32l8", ptr %[[BLOCK_DESCRIPTOR]], align 8
|
||||
|
||||
void test0() {
|
||||
id a = getObj();
|
||||
@@ -50,8 +49,8 @@ void test0() {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_ZN18CaptureByReference5test1Ev(
|
||||
// CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test1EvENK3$_0clEv"(
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @"__block_descriptor_56_8_32s40s_e5_v8\01?0l" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store ptr @"__block_descriptor_56_8_32s40s_e5_v8\01?0l", ptr %[[BLOCK_DESCRIPTOR]], align 8
|
||||
|
||||
void test1() {
|
||||
id a = getObj(), b = getObj(), c = getObj();
|
||||
@@ -70,12 +69,12 @@ struct S {
|
||||
|
||||
S getS();
|
||||
|
||||
// CHECK: define internal noundef i32 @"_ZZN18CaptureByReference5test2EvENK3$_0clIiEEDaT_"(%[[CLASS_ANON_2]]* {{[^,]*}} %{{.*}}, i32 noundef %{{.*}})
|
||||
// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %{{.*}}, %[[S]]* }>, align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}, %[[S]]* }>, <{ i8*, i32, i32, i8*, %{{.*}}, %[[S]]* }>* %[[BLOCK]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[CLASS_ANON_2]], %[[CLASS_ANON_2]]* %{{.*}}, i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load %[[S]]*, %[[S]]** %[[V0]], align 8
|
||||
// CHECK: store %[[S]]* %[[V1]], %[[S]]** %[[BLOCK_CAPTURED]], align 8
|
||||
// CHECK: define internal noundef i32 @"_ZZN18CaptureByReference5test2EvENK3$_0clIiEEDaT_"(ptr {{[^,]*}} %{{.*}}, i32 noundef %{{.*}})
|
||||
// CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, {{.*}}, ptr }>, align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, {{.*}}, ptr }>, ptr %[[BLOCK]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[CLASS_ANON_2]], ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load ptr, ptr %[[V0]], align 8
|
||||
// CHECK: store ptr %[[V1]], ptr %[[BLOCK_CAPTURED]], align 8
|
||||
|
||||
int test2() {
|
||||
S s;
|
||||
@@ -87,11 +86,11 @@ int test2() {
|
||||
return fn(123);
|
||||
}
|
||||
|
||||
// CHECK: define internal noundef i32 @"_ZZN18CaptureByReference5test3EvENK3$_0clIiEEDaT_"(%[[CLASS_ANON_3]]* {{[^,]*}} %{{.*}}, i32 noundef %{{.*}})
|
||||
// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %{{.*}}*, %[[S]] }>, align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}*, %[[S]] }>, <{ i8*, i32, i32, i8*, %{{.*}}*, %[[S]] }>* %[[BLOCK]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[CLASS_ANON_3]], %[[CLASS_ANON_3]]* %{{.*}}, i32 0, i32 0
|
||||
// CHECK: call void @_ZN18CaptureByReference1SC1ERKS0_(%[[S]]* {{[^,]*}} %[[BLOCK_CAPTURED]], %[[S]]* {{.*}} %[[V0]])
|
||||
// CHECK: define internal noundef i32 @"_ZZN18CaptureByReference5test3EvENK3$_0clIiEEDaT_"(ptr {{[^,]*}} %{{.*}}, i32 noundef %{{.*}})
|
||||
// CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, %[[S]] }>, align 8
|
||||
// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, %[[S]] }>, ptr %[[BLOCK]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[CLASS_ANON_3]], ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK: call void @_ZN18CaptureByReference1SC1ERKS0_(ptr {{[^,]*}} %[[BLOCK_CAPTURED]], ptr {{.*}} %[[V0]])
|
||||
|
||||
int test3() {
|
||||
const S &s = getS();
|
||||
@@ -105,25 +104,25 @@ int test3() {
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32s40s(
|
||||
// CHECK-NOT: call void @llvm.objc.storeStrong(
|
||||
// CHECK: %[[V4:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5
|
||||
// CHECK: %[[V5:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5
|
||||
// CHECK: %[[BLOCKCOPY_SRC:.*]] = load i8*, i8** %[[V4]], align 8
|
||||
// CHECK: store i8* null, i8** %[[V5]], align 8
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** %[[V5]], i8* %[[BLOCKCOPY_SRC]])
|
||||
// CHECK: %[[V6:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 6
|
||||
// CHECK: %[[V7:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 6
|
||||
// CHECK: %[[BLOCKCOPY_SRC2:.*]] = load i8*, i8** %[[V6]], align 8
|
||||
// CHECK: store i8* null, i8** %[[V7]], align 8
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** %[[V7]], i8* %[[BLOCKCOPY_SRC2]])
|
||||
// CHECK: %[[V4:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 5
|
||||
// CHECK: %[[V5:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 5
|
||||
// CHECK: %[[BLOCKCOPY_SRC:.*]] = load ptr, ptr %[[V4]], align 8
|
||||
// CHECK: store ptr null, ptr %[[V5]], align 8
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr %[[V5]], ptr %[[BLOCKCOPY_SRC]])
|
||||
// CHECK: %[[V6:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 6
|
||||
// CHECK: %[[V7:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 6
|
||||
// CHECK: %[[BLOCKCOPY_SRC2:.*]] = load ptr, ptr %[[V6]], align 8
|
||||
// CHECK: store ptr null, ptr %[[V7]], align 8
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr %[[V7]], ptr %[[BLOCKCOPY_SRC2]])
|
||||
// CHECK-NOT: call void @llvm.objc.storeStrong(
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32s40s(
|
||||
// CHECK: %[[V2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5
|
||||
// CHECK: %[[V3:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 6
|
||||
// CHECK: %[[V2:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 5
|
||||
// CHECK: %[[V3:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 6
|
||||
// CHECK-NOT: call void @llvm.objc.storeStrong(
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** %[[V3]], i8* null)
|
||||
// CHECK: call void @llvm.objc.storeStrong(i8** %[[V2]], i8* null)
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr %[[V3]], ptr null)
|
||||
// CHECK: call void @llvm.objc.storeStrong(ptr %[[V2]], ptr null)
|
||||
// CHECK-NOT: call void @llvm.objc.storeStrong(
|
||||
// CHECK: ret void
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -Wno-objc-root-class -std=gnu++98 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX98,CHECK-NO-TEMP-SPEC %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20,CHECK-NO-TEMP-SPEC %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -fobjc-encode-cxx-class-template-spec -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20,CHECK-TEMP-SPEC %s
|
||||
// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++98 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX98,CHECK-NO-TEMP-SPEC %s
|
||||
// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20,CHECK-NO-TEMP-SPEC %s
|
||||
// RUN: %clang_cc1 -Wno-objc-root-class -std=gnu++20 %s -triple=x86_64-apple-darwin10 -fobjc-encode-cxx-class-template-spec -emit-llvm -o - | FileCheck --check-prefixes CHECK,CHECKCXX20,CHECK-TEMP-SPEC %s
|
||||
|
||||
// CHECK: v17@0:8{vector<float, float, float>=}16
|
||||
// CHECK: {vector<float, float, float>=}
|
||||
@@ -302,30 +302,30 @@ struct Outer0 {
|
||||
};
|
||||
|
||||
// CHECK: @[[STR22:.*]] = {{.*}} [12 x i8] c"{B0<int>=i}\00"
|
||||
// CHECK: @_ZN32test_cxx_template_specialization2b0E = {{.*}} ([12 x i8], [12 x i8]* @[[STR22]], i32 0, i32 0)
|
||||
// CHECK: @_ZN32test_cxx_template_specialization2b0E = global ptr @[[STR22]]
|
||||
// CHECK-NO-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [3 x i8] c"^v\00"
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = global ptr @[[STR23]]
|
||||
// CHECK-TEMP-SPEC: @[[STR23:.*]] = {{.*}} [13 x i8] c"^{B0<int>=i}\00"
|
||||
// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = {{.*}} ([13 x i8], [13 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b02E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d1E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d2E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b01E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3b02E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d0E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d1E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2d2E = global ptr @[[STR23]]
|
||||
// CHECK: @[[STR24:.*]] = {{.*}} [7 x i8] c"^^{D2}\00"
|
||||
// CHECK: @_ZN32test_cxx_template_specialization3d21E = {{.*}} ([7 x i8], [7 x i8]* @[[STR24]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s1E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK: @_ZN32test_cxx_template_specialization3d21E = global ptr @[[STR24]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s0E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2s1E = global ptr @[[STR23]]
|
||||
// CHECK: @[[STR25:.*]] = {{.*}} [12 x i8] c"^{S2=^{S1}}\00"
|
||||
// CHECK: @_ZN32test_cxx_template_specialization2s2E = {{.*}} ([12 x i8], [12 x i8]* @[[STR25]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2u0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3td0E = {{.*}} ([3 x i8], [3 x i8]* @[[STR23]], i32 0, i32 0)
|
||||
// CHECK: @_ZN32test_cxx_template_specialization2s2E = global ptr @[[STR25]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2u0E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization3td0E = global ptr @[[STR23]]
|
||||
// CHECK-NO-TEMP-SPEC: @[[STR26:.*]] = {{.*}} [6 x i8] c"[4^v]\00"
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2a0E = {{.*}} ([6 x i8], [6 x i8]* @[[STR26]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization2a0E = global ptr @[[STR26]]
|
||||
// CHECK: @[[STR27:.*]] = {{.*}} [11 x i8] c"^{Inner0=}\00"
|
||||
// CHECK: @_ZN32test_cxx_template_specialization6inner0E = {{.*}} ([11 x i8], [11 x i8]* @[[STR27]], i32 0, i32 0)
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = {{.*}} ([3 x i8], [3 x i8]* @.str.23, i32 0, i32 0)
|
||||
// CHECK: @_ZN32test_cxx_template_specialization6inner0E = global ptr @[[STR27]]
|
||||
// CHECK-NO-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = global ptr @.str.23
|
||||
// CHECK-TEMP-SPEC: @[[STR34:.*]] = {{.*}} [18 x i8] c"^{Inner1<float>=}\00"
|
||||
// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = {{.*}} ([18 x i8], [18 x i8]* @[[STR34]], i32 0, i32 0)
|
||||
// CHECK-TEMP-SPEC: @_ZN32test_cxx_template_specialization6inner1E = global ptr @[[STR34]]
|
||||
|
||||
const char *b0 = @encode(B0<int>);
|
||||
const char *b01 = @encode(B0<int> *);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
|
||||
|
||||
// Test we maintain at least a basic amount of interoperation between
|
||||
// ObjC and C++ exceptions in the legacy runtime.
|
||||
@@ -14,10 +14,9 @@ void test0(id obj) {
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test0P11objc_object(
|
||||
// Enter the @synchronized block.
|
||||
// CHECK: call i32 @objc_sync_enter(i8* [[OBJ:%.*]])
|
||||
// CHECK: call void @objc_exception_try_enter([[BUF_T:%.*]]* nonnull [[BUF:%.*]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BUF_T]], [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0
|
||||
// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* nonnull [[T0]])
|
||||
// CHECK: call i32 @objc_sync_enter(ptr [[OBJ:%.*]])
|
||||
// CHECK: call void @objc_exception_try_enter(ptr nonnull [[BUF:%.*]])
|
||||
// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
|
||||
// CHECK-NEXT: br i1 [[T2]],
|
||||
|
||||
@@ -25,24 +24,24 @@ void test0(id obj) {
|
||||
// CHECK: invoke void @_Z3foov()
|
||||
|
||||
// Leave the @synchronized. The reload of obj here is unnecessary.
|
||||
// CHECK: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
|
||||
// CHECK: call void @objc_exception_try_exit(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T0]])
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// Real EH cleanup.
|
||||
// CHECK: [[T0:%.*]] = landingpad
|
||||
// CHECK-NEXT: cleanup
|
||||
// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
|
||||
// CHECK-NEXT: call void @objc_exception_try_exit(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T0]])
|
||||
// CHECK-NEXT: resume
|
||||
|
||||
// ObjC EH "cleanup".
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_exception_extract([[BUF_T]]* nonnull [[BUF]])
|
||||
// CHECK-NEXT: call void @objc_exception_throw(i8* [[T0]])
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T0]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = call ptr @objc_exception_extract(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: call void @objc_exception_throw(ptr [[T0]])
|
||||
// CHECK-NEXT: unreachable
|
||||
|
||||
void test1(id obj, bool *failed) {
|
||||
@@ -54,9 +53,8 @@ void test1(id obj, bool *failed) {
|
||||
}
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test1P11objc_objectPb(
|
||||
// Enter the @try block.
|
||||
// CHECK: call void @objc_exception_try_enter([[BUF_T]]* nonnull [[BUF:%.*]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BUF_T]], [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0
|
||||
// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* nonnull [[T0]])
|
||||
// CHECK: call void @objc_exception_try_enter(ptr nonnull [[BUF:%.*]])
|
||||
// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
|
||||
// CHECK-NEXT: br i1 [[T2]],
|
||||
|
||||
@@ -64,12 +62,12 @@ void test1(id obj, bool *failed) {
|
||||
// CHECK: invoke void @_Z3foov()
|
||||
|
||||
// Catch handler. Reload of 'failed' address is unnecessary.
|
||||
// CHECK: [[T0:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: store i8 1, i8* [[T0]],
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: store i8 1, ptr [[T0]],
|
||||
// CHECK-NEXT: br label
|
||||
|
||||
// Leave the @try.
|
||||
// CHECK: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]])
|
||||
// CHECK: call void @objc_exception_try_exit(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: ret void
|
||||
|
||||
@@ -77,6 +75,6 @@ void test1(id obj, bool *failed) {
|
||||
// Real EH cleanup.
|
||||
// CHECK: [[T0:%.*]] = landingpad
|
||||
// CHECK-NEXT: cleanup
|
||||
// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]])
|
||||
// CHECK-NEXT: call void @objc_exception_try_exit(ptr nonnull [[BUF]])
|
||||
// CHECK-NEXT: resume
|
||||
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -x objective-c++ -fblocks -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -std=c++1z -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -x objective-c++ -fblocks -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -std=c++1z -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
// rdar://31385153
|
||||
// Shouldn't crash!
|
||||
|
||||
// CHECK: %[[STRUCT_COPYABLE:.*]] = type { i8 }
|
||||
// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
|
||||
// CHECK: %[[CLASS_ANON:.*]] = type { %[[STRUCT_COPYABLE]] }
|
||||
// CHECK: %[[CLASS_ANON:.*]] = type { %[[STRUCT_COPYABLE:.*]] }
|
||||
// CHECK: %[[STRUCT_COPYABLE]] = type { i8 }
|
||||
// CHECK: %[[CLASS_ANON_0:.*]] = type { %[[STRUCT_COPYABLE]] }
|
||||
// CHECK: %[[CLASS_ANON_1:.*]] = type { %[[STRUCT_COPYABLE]] }
|
||||
// CHECK: %[[CLASS_ANON_2:.*]] = type { %[[STRUCT_COPYABLE]] }
|
||||
|
||||
// CHECK: @[[BLOCK_DESC0:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 33, i8* bitcast (void (i8*, i8*)* @[[COPY_HELPER0:.*__copy_helper_block_.*]] to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block{{.*}} to i8*), {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC1:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 33, i8* bitcast (void (i8*, i8*)* @[[COPY_HELPER1:.*__copy_helper_block_.*]] to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block{{.*}} to i8*), {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC2:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 33, i8* bitcast (void (i8*, i8*)* @[[COPY_HELPER2:.*__copy_helper_block_.*]] to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block{{.*}} to i8*), {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC3:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 33, i8* bitcast (void (i8*, i8*)* @[[COPY_HELPER3:.*__copy_helper_block_.*]] to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block{{.*}} to i8*), {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC0:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 33, ptr @[[COPY_HELPER0:.*__copy_helper_block_.*]], ptr @__destroy_helper_block{{.*}}, {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC1:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 33, ptr @[[COPY_HELPER1:.*__copy_helper_block_.*]], ptr @__destroy_helper_block{{.*}}, {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC2:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 33, ptr @[[COPY_HELPER2:.*__copy_helper_block_.*]], ptr @__destroy_helper_block{{.*}}, {{.*}}}, align 8
|
||||
// CHECK: @[[BLOCK_DESC3:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 33, ptr @[[COPY_HELPER3:.*__copy_helper_block_.*]], ptr @__destroy_helper_block{{.*}}, {{.*}}}, align 8
|
||||
|
||||
// CHECK: define{{.*}} void @_Z9hasLambda8Copyable(
|
||||
// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON]] }>, align 8
|
||||
// CHECK: %[[BLOCK1:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_0]] }>, align 8
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON]] }>* %[[BLOCK]], i32 0, i32 4
|
||||
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESC0]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR6:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_0]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_0]] }>* %[[BLOCK1]], i32 0, i32 4
|
||||
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESC1]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR6]], align 8
|
||||
// CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, %[[CLASS_ANON]] }>, align 8
|
||||
// CHECK: %[[BLOCK1:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, %[[CLASS_ANON_0]] }>, align 8
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, %[[CLASS_ANON]] }>, ptr %[[BLOCK]], i32 0, i32 4
|
||||
// CHECK: store ptr @[[BLOCK_DESC0]], ptr %[[BLOCK_DESCRIPTOR]], align 8
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR6:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, %[[CLASS_ANON_0]] }>, ptr %[[BLOCK1]], i32 0, i32 4
|
||||
// CHECK: store ptr @[[BLOCK_DESC1]], ptr %[[BLOCK_DESCRIPTOR6]], align 8
|
||||
|
||||
void takesBlock(void (^)(void));
|
||||
|
||||
@@ -40,20 +39,20 @@ void hasLambda(Copyable x) {
|
||||
// CHECK: define internal void @[[COPY_HELPER1]]
|
||||
|
||||
// CHECK: define{{.*}} void @_Z17testHelperMerging8Copyable(
|
||||
// CHECK: %[[CALL:.*]] = call noundef void ()* @[[CONV_FUNC0:.*]](%[[CLASS_ANON_1]]*
|
||||
// CHECK: call void @_Z10takesBlockU13block_pointerFvvE(void ()* noundef %[[CALL]])
|
||||
// CHECK: %[[CALL1:.*]] = call noundef void ()* @[[CONV_FUNC0]](%[[CLASS_ANON_1]]*
|
||||
// CHECK: call void @_Z10takesBlockU13block_pointerFvvE(void ()* noundef %[[CALL1]])
|
||||
// CHECK: %[[CALL2:.*]] = call noundef void ()* @[[CONV_FUNC1:.*]](%[[CLASS_ANON_2]]*
|
||||
// CHECK: call void @_Z10takesBlockU13block_pointerFvvE(void ()* noundef %[[CALL2]])
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @[[CONV_FUNC0:.*]](ptr
|
||||
// CHECK: call void @_Z10takesBlockU13block_pointerFvvE(ptr noundef %[[CALL]])
|
||||
// CHECK: %[[CALL1:.*]] = call noundef ptr @[[CONV_FUNC0]](ptr
|
||||
// CHECK: call void @_Z10takesBlockU13block_pointerFvvE(ptr noundef %[[CALL1]])
|
||||
// CHECK: %[[CALL2:.*]] = call noundef ptr @[[CONV_FUNC1:.*]](ptr
|
||||
// CHECK: call void @_Z10takesBlockU13block_pointerFvvE(ptr noundef %[[CALL2]])
|
||||
|
||||
// CHECK: define internal noundef void ()* @[[CONV_FUNC0]](
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_1]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_1]] }>* %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESC2]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
|
||||
// CHECK: define internal noundef ptr @[[CONV_FUNC0]](
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, %[[CLASS_ANON_1]] }>, ptr %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store ptr @[[BLOCK_DESC2]], ptr %[[BLOCK_DESCRIPTOR]], align 8
|
||||
|
||||
// CHECK: define internal noundef void ()* @[[CONV_FUNC1]](
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_2]] }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, %[[CLASS_ANON_2]] }>* %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESC3]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
|
||||
// CHECK: define internal noundef ptr @[[CONV_FUNC1]](
|
||||
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, %[[CLASS_ANON_2]] }>, ptr %{{.*}}, i32 0, i32 4
|
||||
// CHECK: store ptr @[[BLOCK_DESC3]], ptr %[[BLOCK_DESCRIPTOR]], align 8
|
||||
|
||||
// CHECK-LABEL: define internal void @"_ZZ9hasLambda8CopyableEN3$_0C2ERKS0_"
|
||||
// CHECK: call void @_ZN8CopyableC1ERKS_
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -std=gnu++98 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=gnu++98 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
||||
|
||||
#include "literal-support.h"
|
||||
|
||||
@@ -16,31 +16,28 @@ struct Y {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z10test_arrayv
|
||||
void test_array() {
|
||||
// CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*
|
||||
// CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
|
||||
// CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca ptr
|
||||
// CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x ptr]
|
||||
// CHECK: [[TMPX:%[a-zA-Z0-9.]+]] = alloca %
|
||||
// CHECK: [[TMPY:%[a-zA-Z0-9.]+]] = alloca %
|
||||
|
||||
// Initializing first element
|
||||
// CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]])
|
||||
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
|
||||
// CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPX]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
|
||||
// CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr [[ARR]])
|
||||
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 0
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 1, ptr [[TMPX]])
|
||||
// CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]])
|
||||
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke noundef i8* @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store i8* [[OBJECT0]], i8** [[ELEMENT0]]
|
||||
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke noundef ptr @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store ptr [[OBJECT0]], ptr [[ELEMENT0]]
|
||||
|
||||
// Initializing the second element
|
||||
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
|
||||
// CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPY]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
|
||||
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 1
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 1, ptr [[TMPY]])
|
||||
// CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]])
|
||||
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke noundef i8* @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store i8* [[OBJECT1]], i8** [[ELEMENT1]]
|
||||
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke noundef ptr @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store ptr [[OBJECT1]], ptr [[ELEMENT1]]
|
||||
|
||||
// Build the array
|
||||
// CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id arr = @[ X(), Y() ];
|
||||
|
||||
// Destroy temporaries
|
||||
@@ -53,8 +50,7 @@ void test_array() {
|
||||
// CHECK-NEXT: call void @_ZN1XD1Ev
|
||||
// CHECK-NOT: ret void
|
||||
// CHECK: call void @llvm.objc.release
|
||||
// CHECK-NEXT: [[PTR2:%.*]] = bitcast i8** [[ARR]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR2]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[ARR]])
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// Check cleanups
|
||||
@@ -71,25 +67,24 @@ void test_array() {
|
||||
// CHECK-LABEL: define weak_odr void @_Z24test_array_instantiationIiEvv
|
||||
template<typename T>
|
||||
void test_array_instantiation() {
|
||||
// CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*
|
||||
// CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
|
||||
// CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca ptr
|
||||
// CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x ptr]
|
||||
|
||||
// Initializing first element
|
||||
// CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]])
|
||||
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
|
||||
// CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr [[ARR]])
|
||||
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 0
|
||||
// CHECK: call void @_ZN1XC1Ev
|
||||
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke noundef i8* @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store i8* [[OBJECT0]], i8** [[ELEMENT0]]
|
||||
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke noundef ptr @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store ptr [[OBJECT0]], ptr [[ELEMENT0]]
|
||||
|
||||
// Initializing the second element
|
||||
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
|
||||
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 1
|
||||
// CHECK: invoke void @_ZN1YC1Ev
|
||||
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke noundef i8* @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store i8* [[OBJECT1]], i8** [[ELEMENT1]]
|
||||
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke noundef ptr @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: store ptr [[OBJECT1]], ptr [[ELEMENT1]]
|
||||
|
||||
// Build the array
|
||||
// CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
id arr = @[ X(), Y() ];
|
||||
|
||||
// Destroy temporaries
|
||||
@@ -102,8 +97,7 @@ void test_array_instantiation() {
|
||||
// CHECK-NEXT: call void @_ZN1XD1Ev
|
||||
// CHECK-NOT: ret void
|
||||
// CHECK: call void @llvm.objc.release
|
||||
// CHECK-NEXT: [[PTR2]] = bitcast i8** [[ARR]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR2]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[ARR]])
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// Check cleanups
|
||||
|
||||
@@ -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://10153365
|
||||
|
||||
static int gint;
|
||||
@@ -21,8 +21,8 @@ static SetSection gSetSection;
|
||||
}
|
||||
@end
|
||||
|
||||
// CHECK: [[SELF:%.*]] = alloca [[T6:%.*]]*, align
|
||||
// CHECK: [[T0:%.*]] = load {{.*}}, {{.*}}* [[SELF]], align
|
||||
// CHECK: [[T1:%.*]] = load {{.*}}, {{.*}}* @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: [[C:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %struct.SetSection* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK: call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i32* @_ZN10SetSection2atEi(%struct.SetSection* {{[^,]*}} [[C]]
|
||||
// CHECK: [[SELF:%.*]] = alloca ptr, align
|
||||
// CHECK: [[T0:%.*]] = load {{.*}}, ptr [[SELF]], align
|
||||
// CHECK: [[T1:%.*]] = load {{.*}}, ptr @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: [[C:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @objc_msgSend
|
||||
// CHECK: call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN10SetSection2atEi(ptr {{[^,]*}} [[C]]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
|
||||
// rdar://8604515
|
||||
|
||||
@interface I {}
|
||||
@@ -15,6 +15,6 @@
|
||||
}
|
||||
@end
|
||||
|
||||
// CHECK: [[T:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK: [[U:%.*]] = load i32, i32* [[T]]
|
||||
// CHECK: [[T:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @objc_msgSend
|
||||
// CHECK: [[U:%.*]] = load i32, ptr [[T]]
|
||||
// CHECK: [[V:%.*]] = icmp eq i32 [[U]], 0
|
||||
|
||||
@@ -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
|
||||
@@ -50,7 +50,7 @@ template void test3<int>(NSMutableArray*);
|
||||
// CHECK-LABEL: define{{.*}} void @_Z11static_dataP14NSMutableArray
|
||||
void static_data(NSMutableArray *array) {
|
||||
// CHECK: call i32 @__cxa_guard_acquire
|
||||
// CHECK: {{call noundef i8*.*@objc_msgSend }}
|
||||
// CHECK: call noundef ptr @objc_msgSend
|
||||
// CHECK: call void @__cxa_guard_release
|
||||
static id x = array[4];
|
||||
// CHECK: ret void
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s
|
||||
|
||||
// Check that structs consisting solely of __strong or __weak pointer fields are
|
||||
// destructed in the callee function and structs consisting solely of __strong
|
||||
// pointer fields are passed directly.
|
||||
|
||||
// CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }
|
||||
// CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { ptr, ptr }
|
||||
// CHECK: %[[STRUCT_STRONG:.*]] = type { ptr }
|
||||
// CHECK: %[[STRUCT_CONTAINSNONTRIVIAL:.*]] = type { %{{.*}}, ptr }
|
||||
// CHECK: %[[STRUCT_NONTRIVIAL:.*]] = type { ptr }
|
||||
// CHECK: %[[STRUCT_CONTAINSSTRONGWEAK:.*]] = type { %[[STRUCT_STRONGWEAK]] }
|
||||
// CHECK: %[[STRUCT_DERIVEDSTRONGWEAK:.*]] = type { %[[STRUCT_STRONGWEAK]] }
|
||||
// CHECK: %[[STRUCT_STRONG:.*]] = type { i8* }
|
||||
// CHECK: %[[STRUCT_S:.*]] = type { i8* }
|
||||
// CHECK: %[[STRUCT_CONTAINSNONTRIVIAL:.*]] = type { %{{.*}}, i8* }
|
||||
// CHECK: %[[STRUCT_NONTRIVIAL:.*]] = type { i32* }
|
||||
// CHECK: %[[STRUCT_S:.*]] = type { ptr }
|
||||
|
||||
#ifdef TRIVIALABI
|
||||
struct __attribute__((trivial_abi)) StrongWeak {
|
||||
@@ -76,20 +75,20 @@ struct ContainsNonTrivial {
|
||||
- (void)passNonTrivial:(NonTrivial)a;
|
||||
@end
|
||||
|
||||
// CHECK: define{{.*}} void @_Z19testParamStrongWeak10StrongWeak(%[[STRUCT_STRONGWEAK]]* noundef %{{.*}})
|
||||
// CHECK: call noundef %struct.StrongWeak* @_ZN10StrongWeakD1Ev(
|
||||
// CHECK: define{{.*}} void @_Z19testParamStrongWeak10StrongWeak(ptr noundef %{{.*}})
|
||||
// CHECK: call noundef ptr @_ZN10StrongWeakD1Ev(
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
void testParamStrongWeak(StrongWeak a) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z18testCallStrongWeakP10StrongWeak(%[[STRUCT_STRONGWEAK]]* noundef %[[A:.*]])
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8
|
||||
// CHECK: define{{.*}} void @_Z18testCallStrongWeakP10StrongWeak(ptr noundef %[[A:.*]])
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8
|
||||
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONGWEAK]], align 8
|
||||
// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STRUCT_STRONGWEAK]]* {{[^,]*}} %[[AGG_TMP]], %[[STRUCT_STRONGWEAK]]* noundef nonnull align 8 dereferenceable(16) %[[V0]])
|
||||
// CHECK: call void @_Z19testParamStrongWeak10StrongWeak(%[[STRUCT_STRONGWEAK]]* noundef %[[AGG_TMP]])
|
||||
// CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN10StrongWeakC1ERKS_(ptr {{[^,]*}} %[[AGG_TMP]], ptr noundef nonnull align 8 dereferenceable(16) %[[V0]])
|
||||
// CHECK: call void @_Z19testParamStrongWeak10StrongWeak(ptr noundef %[[AGG_TMP]])
|
||||
// CHECK-NOT: call
|
||||
// CHECK: ret void
|
||||
|
||||
@@ -97,51 +96,51 @@ void testCallStrongWeak(StrongWeak *a) {
|
||||
testParamStrongWeak(*a);
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z20testReturnStrongWeakP10StrongWeak(%[[STRUCT_STRONGWEAK:.*]]* noalias sret(%[[STRUCT_STRONGWEAK]]) align 8 %[[AGG_RESULT:.*]], %[[STRUCT_STRONGWEAK]]* noundef %[[A:.*]])
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8
|
||||
// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STRUCT_STRONGWEAK]]* {{[^,]*}} %[[AGG_RESULT]], %[[STRUCT_STRONGWEAK]]* noundef nonnull align 8 dereferenceable(16) %[[V0]])
|
||||
// CHECK: define{{.*}} void @_Z20testReturnStrongWeakP10StrongWeak(ptr noalias sret(%[[STRUCT_STRONGWEAK:.*]]) align 8 %[[AGG_RESULT:.*]], ptr noundef %[[A:.*]])
|
||||
// CHECK: %[[A_ADDR:a.addr]] = alloca ptr, align 8
|
||||
// CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN10StrongWeakC1ERKS_(ptr {{[^,]*}} %[[AGG_RESULT]], ptr noundef nonnull align 8 dereferenceable(16) %[[V0]])
|
||||
// CHECK: ret void
|
||||
|
||||
StrongWeak testReturnStrongWeak(StrongWeak *a) {
|
||||
return *a;
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z27testParamContainsStrongWeak18ContainsStrongWeak(%[[STRUCT_CONTAINSSTRONGWEAK]]* noundef %[[A:.*]])
|
||||
// CHECK: call noundef %[[STRUCT_CONTAINSSTRONGWEAK]]* @_ZN18ContainsStrongWeakD1Ev(%[[STRUCT_CONTAINSSTRONGWEAK]]* {{[^,]*}} %[[A]])
|
||||
// CHECK: define{{.*}} void @_Z27testParamContainsStrongWeak18ContainsStrongWeak(ptr noundef %[[A:.*]])
|
||||
// CHECK: call noundef ptr @_ZN18ContainsStrongWeakD1Ev(ptr {{[^,]*}} %[[A]])
|
||||
|
||||
void testParamContainsStrongWeak(ContainsStrongWeak a) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z26testParamDerivedStrongWeak17DerivedStrongWeak(%[[STRUCT_DERIVEDSTRONGWEAK]]* noundef %[[A:.*]])
|
||||
// CHECK: call noundef %[[STRUCT_DERIVEDSTRONGWEAK]]* @_ZN17DerivedStrongWeakD1Ev(%[[STRUCT_DERIVEDSTRONGWEAK]]* {{[^,]*}} %[[A]])
|
||||
// CHECK: define{{.*}} void @_Z26testParamDerivedStrongWeak17DerivedStrongWeak(ptr noundef %[[A:.*]])
|
||||
// CHECK: call noundef ptr @_ZN17DerivedStrongWeakD1Ev(ptr {{[^,]*}} %[[A]])
|
||||
|
||||
void testParamDerivedStrongWeak(DerivedStrongWeak a) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z15testParamStrong6Strong(i64 %[[A_COERCE:.*]])
|
||||
// CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONG]], align 8
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[A]], i32 0, i32 0
|
||||
// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to i8*
|
||||
// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(%[[STRUCT_STRONG]]* {{[^,]*}} %[[A]])
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], ptr %[[A]], i32 0, i32 0
|
||||
// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to ptr
|
||||
// CHECK: store ptr %[[COERCE_VAL_IP]], ptr %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN6StrongD1Ev(ptr {{[^,]*}} %[[A]])
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define linkonce_odr noundef %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(
|
||||
// CHECK: define linkonce_odr noundef ptr @_ZN6StrongD1Ev(
|
||||
|
||||
void testParamStrong(Strong a) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z14testCallStrongP6Strong(%[[STRUCT_STRONG]]* noundef %[[A:.*]])
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8
|
||||
// CHECK: define{{.*}} void @_Z14testCallStrongP6Strong(ptr noundef %[[A:.*]])
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8
|
||||
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8
|
||||
// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_STRONG]]* {{[^,]*}} %[[AGG_TMP]], %[[STRUCT_STRONG]]* noundef nonnull align 8 dereferenceable(8) %[[V0]])
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[AGG_TMP]], i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64
|
||||
// CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN6StrongC1ERKS_(ptr {{[^,]*}} %[[AGG_TMP]], ptr noundef nonnull align 8 dereferenceable(8) %[[V0]])
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], ptr %[[AGG_TMP]], i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load ptr, ptr %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint ptr %[[V1]] to i64
|
||||
// CHECK: call void @_Z15testParamStrong6Strong(i64 %[[COERCE_VAL_PI]])
|
||||
// CHECK: ret void
|
||||
|
||||
@@ -149,29 +148,29 @@ void testCallStrong(Strong *a) {
|
||||
testParamStrong(*a);
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} i64 @_Z16testReturnStrongP6Strong(%[[STRUCT_STRONG]]* noundef %[[A:.*]])
|
||||
// CHECK: define{{.*}} i64 @_Z16testReturnStrongP6Strong(ptr noundef %[[A:.*]])
|
||||
// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8
|
||||
// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_STRONG]]* {{[^,]*}} %[[RETVAL]], %[[STRUCT_STRONG]]* noundef nonnull align 8 dereferenceable(8) %[[V0]])
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64
|
||||
// CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8
|
||||
// CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8
|
||||
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN6StrongC1ERKS_(ptr {{[^,]*}} %[[RETVAL]], ptr noundef nonnull align 8 dereferenceable(8) %[[V0]])
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], ptr %[[RETVAL]], i32 0, i32 0
|
||||
// CHECK: %[[V1:.*]] = load ptr, ptr %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint ptr %[[V1]] to i64
|
||||
// CHECK: ret i64 %[[COERCE_VAL_PI]]
|
||||
|
||||
Strong testReturnStrong(Strong *a) {
|
||||
return *a;
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z21testParamWeakTemplate1SIU6__weakP11objc_objectE(%[[STRUCT_S]]* noundef %{{.*}})
|
||||
// CHECK: call noundef %struct.S* @_ZN1SIU6__weakP11objc_objectED1Ev(
|
||||
// CHECK: define{{.*}} void @_Z21testParamWeakTemplate1SIU6__weakP11objc_objectE(ptr noundef %{{.*}})
|
||||
// CHECK: call noundef ptr @_ZN1SIU6__weakP11objc_objectED1Ev(
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
void testParamWeakTemplate(S<__weak id> a) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z27testParamContainsNonTrivial18ContainsNonTrivial(%[[STRUCT_CONTAINSNONTRIVIAL]]* noundef %{{.*}})
|
||||
// CHECK: define{{.*}} void @_Z27testParamContainsNonTrivial18ContainsNonTrivial(ptr noundef %{{.*}})
|
||||
// CHECK-NOT: call
|
||||
// CHECK: ret void
|
||||
|
||||
@@ -179,8 +178,8 @@ void testParamContainsNonTrivial(ContainsNonTrivial a) {
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z26testCallContainsNonTrivialP18ContainsNonTrivial(
|
||||
// CHECK: call void @_Z27testParamContainsNonTrivial18ContainsNonTrivial(%[[STRUCT_CONTAINSNONTRIVIAL]]* noundef %{{.*}})
|
||||
// CHECK: call noundef %struct.ContainsNonTrivial* @_ZN18ContainsNonTrivialD1Ev(%[[STRUCT_CONTAINSNONTRIVIAL]]* {{[^,]*}} %{{.*}})
|
||||
// CHECK: call void @_Z27testParamContainsNonTrivial18ContainsNonTrivial(ptr noundef %{{.*}})
|
||||
// CHECK: call noundef ptr @_ZN18ContainsNonTrivialD1Ev(ptr {{[^,]*}} %{{.*}})
|
||||
|
||||
void testCallContainsNonTrivial(ContainsNonTrivial *a) {
|
||||
testParamContainsNonTrivial(*a);
|
||||
@@ -191,12 +190,12 @@ namespace testThunk {
|
||||
// CHECK-LABEL: define{{.*}} i64 @_ZThn8_N9testThunk2D02m0Ev(
|
||||
// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8
|
||||
// CHECK: %[[CALL:.*]] = tail call i64 @_ZN9testThunk2D02m0Ev(
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0
|
||||
// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i8*
|
||||
// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_DIVE2:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0
|
||||
// CHECK: %[[V3:.*]] = load i8*, i8** %[[COERCE_DIVE2]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V3]] to i64
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], ptr %[[RETVAL]], i32 0, i32 0
|
||||
// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to ptr
|
||||
// CHECK: store ptr %[[COERCE_VAL_IP]], ptr %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_DIVE2:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], ptr %[[RETVAL]], i32 0, i32 0
|
||||
// CHECK: %[[V3:.*]] = load ptr, ptr %[[COERCE_DIVE2]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint ptr %[[V3]] to i64
|
||||
// CHECK: ret i64 %[[COERCE_VAL_PI]]
|
||||
|
||||
struct B0 {
|
||||
@@ -221,13 +220,13 @@ namespace testNullReceiver {
|
||||
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8
|
||||
// CHECK: br i1
|
||||
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[AGG_TMP]], i32 0, i32 0
|
||||
// CHECK: %[[V7:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V7]] to i64
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i64)*)({{.*}}, i64 %[[COERCE_VAL_PI]])
|
||||
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], ptr %[[AGG_TMP]], i32 0, i32 0
|
||||
// CHECK: %[[V7:.*]] = load ptr, ptr %[[COERCE_DIVE]], align 8
|
||||
// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint ptr %[[V7]] to i64
|
||||
// CHECK: call void @objc_msgSend({{.*}}, i64 %[[COERCE_VAL_PI]])
|
||||
// CHECK: br
|
||||
|
||||
// CHECK: %[[CALL1:.*]] = call noundef %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(%[[STRUCT_STRONG]]* noundef nonnull align 8 dereferenceable(8) %[[AGG_TMP]])
|
||||
// CHECK: %[[CALL1:.*]] = call noundef ptr @_ZN6StrongD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %[[AGG_TMP]])
|
||||
// CHECK: br
|
||||
|
||||
void test0(C *c) {
|
||||
@@ -238,10 +237,10 @@ void test0(C *c) {
|
||||
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONGWEAK]], align 8
|
||||
// CHECK: br i1
|
||||
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void ({{.*}}, %[[STRUCT_STRONGWEAK]]* noundef %[[AGG_TMP]])
|
||||
// CHECK: call void @objc_msgSend({{.*}}, ptr noundef %[[AGG_TMP]])
|
||||
// CHECK: br
|
||||
|
||||
// CHECK: %[[CALL1:.*]] = call noundef %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakD1Ev(%[[STRUCT_STRONGWEAK]]* noundef nonnull align 8 dereferenceable(16) %[[AGG_TMP]])
|
||||
// CHECK: %[[CALL1:.*]] = call noundef ptr @_ZN10StrongWeakD1Ev(ptr noundef nonnull align 8 dereferenceable(16) %[[AGG_TMP]])
|
||||
// CHECK: br
|
||||
|
||||
void test1(C *c) {
|
||||
@@ -252,8 +251,8 @@ void test1(C *c) {
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_ZN16testNullReceiver5test2EP1C(
|
||||
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_NONTRIVIAL]], align 8
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %[[STRUCT_NONTRIVIAL]]*)*)({{.*}}, %[[STRUCT_NONTRIVIAL]]* noundef %[[AGG_TMP]])
|
||||
// CHECK-NEXT: call noundef %[[STRUCT_NONTRIVIAL]]* @_ZN10NonTrivialD1Ev(%[[STRUCT_NONTRIVIAL]]* noundef nonnull align 8 dereferenceable(8) %[[AGG_TMP]])
|
||||
// CHECK: call void @objc_msgSend({{.*}}, ptr noundef %[[AGG_TMP]])
|
||||
// CHECK-NEXT: call noundef ptr @_ZN10NonTrivialD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %[[AGG_TMP]])
|
||||
|
||||
void test2(C *c) {
|
||||
[c passNonTrivial:NonTrivial()];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -std=c++1z -fobjc-arc -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++1z -fobjc-arc -o - %s | FileCheck %s
|
||||
|
||||
struct S0 {
|
||||
~S0();
|
||||
@@ -19,22 +19,22 @@ struct S1 {
|
||||
@end
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5test0P1C(
|
||||
// CHECK: %{{.*}} = alloca %
|
||||
// CHECK: %{{.*}} = alloca ptr
|
||||
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_S1:.*]], align
|
||||
// CHECK: %[[AGG_TMP_1:.*]] = alloca %[[STRUCT_S0:.*]], align
|
||||
// CHECK: call void @_ZN2S0C1Ev(%[[STRUCT_S0]]* {{[^,]*}} %[[AGG_TMP_1]])
|
||||
// CHECK: call void @_ZN2S1C1E2S0(%[[STRUCT_S1]]* {{[^,]*}} %[[AGG_TMP]], %[[STRUCT_S0]]* noundef %[[AGG_TMP_1]])
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %[[STRUCT_S1]]*)*)(i8* noundef %{{.*}}, i8* noundef %{{.*}}, %[[STRUCT_S1]]* noundef %[[AGG_TMP]])
|
||||
// CHECK: call void @_ZN2S0C1Ev(ptr {{[^,]*}} %[[AGG_TMP_1]])
|
||||
// CHECK: call void @_ZN2S1C1E2S0(ptr {{[^,]*}} %[[AGG_TMP]], ptr noundef %[[AGG_TMP_1]])
|
||||
// CHECK: call void @objc_msgSend(ptr noundef %{{.*}}, ptr noundef %{{.*}}, ptr noundef %[[AGG_TMP]])
|
||||
|
||||
void test0(C *c) {
|
||||
c.f = S0();
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} void @_Z5test1P1C(
|
||||
// CHECK: %{{.*}} = alloca %
|
||||
// CHECK: %{{.*}} = alloca ptr
|
||||
// CHECK: %[[TEMP_LVALUE:.*]] = alloca %[[STRUCT_S1:.*]], align
|
||||
// CHECK: call void @_ZN2S1C1Ev(%[[STRUCT_S1]]* {{[^,]*}} %[[TEMP_LVALUE]])
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %[[STRUCT_S1]]*)*)(i8* noundef %{{.*}}, i8* noundef %{{.*}}, %[[STRUCT_S1]]* noundef %[[TEMP_LVALUE]])
|
||||
// CHECK: call void @_ZN2S1C1Ev(ptr {{[^,]*}} %[[TEMP_LVALUE]])
|
||||
// CHECK: call void @objc_msgSend(ptr noundef %{{.*}}, ptr noundef %{{.*}}, ptr noundef %[[TEMP_LVALUE]])
|
||||
|
||||
void test1(C *c) {
|
||||
c.f = S1();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||
|
||||
struct A { ~A(); };
|
||||
|
||||
@@ -18,7 +18,7 @@ struct A { ~A(); };
|
||||
@end
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z1fP1B
|
||||
// CHECK: objc_msgSend to
|
||||
// CHECK: objc_msgSend
|
||||
// CHECK-NOT: call void @_ZN1AD1Ev
|
||||
// CHECK: ret void
|
||||
void f(B* b) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// PR7864. This all follows GCC's lead.
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace std { class type_info; }
|
||||
@interface B : A
|
||||
@end
|
||||
|
||||
// CHECK: @_ZTIP1B = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}), i32 0, {{.*}}@_ZTI1B
|
||||
// CHECK: @_ZTIP1B = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}, i32 0, {{.*}}@_ZTI1B
|
||||
// CHECK: @_ZTI11objc_object = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS11objc_object
|
||||
// CHECK: @_ZTIP11objc_object = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP11objc_object{{.*}}@_ZTI11objc_object
|
||||
// CHECK: @_ZTI10objc_class = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS10objc_class
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
|
||||
// PR7390
|
||||
|
||||
// CHECK: @[[setprioname:[^ ]*]] = {{.*}}"setPriority:
|
||||
// CHECK-NEXT: @[[setpriosel:[^ ]*]] = {{.*}}getelementptr{{.*}}[[setprioname]]
|
||||
// CHECK-NEXT: @[[setpriosel:[^ ]*]] = {{.*}}[[setprioname]]
|
||||
@interface NSObject
|
||||
- (void)respondsToSelector:(const SEL &)s ps:(SEL *)s1;
|
||||
- (void)setPriority:(int)p;
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
// CHECK-LABEL: define internal void @"\01-[NSObject Meth]"(
|
||||
- (void)Meth {
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8**, i8**)*){{.*}}, i8** noundef @[[setpriosel]])
|
||||
// CHECK: call void @objc_msgSend{{.*}}, ptr noundef @[[setpriosel]])
|
||||
[self respondsToSelector:@selector(setPriority:) ps:&@selector(setPriority:)];
|
||||
}
|
||||
- (void)setPriority:(int)p {
|
||||
|
||||
Reference in New Issue
Block a user