blob: de8c5f9fcb804414854588c2588cfcc28db9f026 [file] [log] [blame]
Akira Hatanaka02914dc2018-02-05 20:23:22 +00001// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s
2// 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
Akira Hatanakafcbe17c2018-03-28 21:13:14 +00003// 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
4// 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
5
6// Check that structs consisting solely of __strong or __weak pointer fields are
7// destructed in the callee function and structs consisting solely of __strong
8// pointer fields are passed directly.
Akira Hatanaka02914dc2018-02-05 20:23:22 +00009
10// CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }
11// CHECK: %[[STRUCT_STRONG:.*]] = type { i8* }
12// CHECK: %[[STRUCT_S:.*]] = type { i8* }
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000013// CHECK: %[[STRUCT_CONTAINSNONTRIVIAL:.*]] = type { %{{.*}}, i8* }
Akira Hatanaka02914dc2018-02-05 20:23:22 +000014
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000015#ifdef TRIVIALABI
Akira Hatanaka02914dc2018-02-05 20:23:22 +000016struct __attribute__((trivial_abi)) StrongWeak {
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000017#else
18struct StrongWeak {
19#endif
Akira Hatanaka02914dc2018-02-05 20:23:22 +000020 id fstrong;
21 __weak id fweak;
22};
23
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000024#ifdef TRIVIALABI
Akira Hatanaka02914dc2018-02-05 20:23:22 +000025struct __attribute__((trivial_abi)) Strong {
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000026#else
27struct Strong {
28#endif
Akira Hatanaka02914dc2018-02-05 20:23:22 +000029 id fstrong;
30};
31
32template<class T>
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000033#ifdef TRIVIALABI
Akira Hatanaka02914dc2018-02-05 20:23:22 +000034struct __attribute__((trivial_abi)) S {
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000035#else
36struct S {
37#endif
Akira Hatanaka02914dc2018-02-05 20:23:22 +000038 T a;
39};
40
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000041struct NonTrivial {
42 NonTrivial();
43 NonTrivial(const NonTrivial &);
44 ~NonTrivial();
45 int *a;
46};
47
48// This struct is not passed directly nor destructed in the callee because f0
49// has type NonTrivial.
50struct ContainsNonTrivial {
51 NonTrivial f0;
52 id f1;
53};
54
Akira Hatanaka02914dc2018-02-05 20:23:22 +000055// CHECK: define void @_Z19testParamStrongWeak10StrongWeak(%[[STRUCT_STRONGWEAK]]* %{{.*}})
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000056// CHECK: call %struct.StrongWeak* @_ZN10StrongWeakD1Ev(
57// CHECK-NEXT: ret void
Akira Hatanaka02914dc2018-02-05 20:23:22 +000058
59void testParamStrongWeak(StrongWeak a) {
60}
61
62// CHECK: define void @_Z18testCallStrongWeakP10StrongWeak(%[[STRUCT_STRONGWEAK]]* %[[A:.*]])
63// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8
64// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONGWEAK]], align 8
65// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
66// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
67// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STRUCT_STRONGWEAK]]* %[[AGG_TMP]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])
68// CHECK: call void @_Z19testParamStrongWeak10StrongWeak(%[[STRUCT_STRONGWEAK]]* %[[AGG_TMP]])
Akira Hatanakafcbe17c2018-03-28 21:13:14 +000069// CHECK-NOT: call
Akira Hatanaka02914dc2018-02-05 20:23:22 +000070// CHECK: ret void
71
72void testCallStrongWeak(StrongWeak *a) {
73 testParamStrongWeak(*a);
74}
75
76// CHECK: define void @_Z20testReturnStrongWeakP10StrongWeak(%[[STRUCT_STRONGWEAK:.*]]* noalias sret %[[AGG_RESULT:.*]], %[[STRUCT_STRONGWEAK]]* %[[A:.*]])
77// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8
78// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
79// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8
80// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[STRUCT_STRONGWEAK]]* %[[AGG_RESULT]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])
81// CHECK: ret void
82
83StrongWeak testReturnStrongWeak(StrongWeak *a) {
84 return *a;
85}
86
87// CHECK: define void @_Z15testParamStrong6Strong(i64 %[[A_COERCE:.*]])
88// CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONG]], align 8
89// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[A]], i32 0, i32 0
90// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to i8*
91// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8
92// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(%[[STRUCT_STRONG]]* %[[A]])
93// CHECK: ret void
94
95// CHECK: define linkonce_odr %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(
96
97void testParamStrong(Strong a) {
98}
99
100// CHECK: define void @_Z14testCallStrongP6Strong(%[[STRUCT_STRONG]]* %[[A:.*]])
101// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8
102// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8
103// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
104// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
105// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_STRONG]]* %[[AGG_TMP]], %[[STRUCT_STRONG]]* dereferenceable(8) %[[V0]])
106// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[AGG_TMP]], i32 0, i32 0
107// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8
108// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64
109// CHECK: call void @_Z15testParamStrong6Strong(i64 %[[COERCE_VAL_PI]])
110// CHECK: ret void
111
112void testCallStrong(Strong *a) {
113 testParamStrong(*a);
114}
115
116// CHECK: define i64 @_Z16testReturnStrongP6Strong(%[[STRUCT_STRONG]]* %[[A:.*]])
Akira Hatanaka02914dc2018-02-05 20:23:22 +0000117// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8
118// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8
119// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
120// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8
121// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_STRONG]]* %[[RETVAL]], %[[STRUCT_STRONG]]* dereferenceable(8) %[[V0]])
122// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0
123// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8
124// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64
125// CHECK: ret i64 %[[COERCE_VAL_PI]]
126
127Strong testReturnStrong(Strong *a) {
128 return *a;
129}
130
131// CHECK: define void @_Z21testParamWeakTemplate1SIU6__weakP11objc_objectE(%[[STRUCT_S]]* %{{.*}})
Akira Hatanakafcbe17c2018-03-28 21:13:14 +0000132// CHECK: call %struct.S* @_ZN1SIU6__weakP11objc_objectED1Ev(
133// CHECK-NEXT: ret void
134
135void testParamWeakTemplate(S<__weak id> a) {
136}
137
138// CHECK: define void @_Z27testParamContainsNonTrivial18ContainsNonTrivial(%[[STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})
Akira Hatanaka02914dc2018-02-05 20:23:22 +0000139// CHECK-NOT: call
140// CHECK: ret void
141
Akira Hatanakafcbe17c2018-03-28 21:13:14 +0000142void testParamContainsNonTrivial(ContainsNonTrivial a) {
143}
144
145// CHECK: define void @_Z26testCallContainsNonTrivialP18ContainsNonTrivial(
146// CHECK: call void @_Z27testParamContainsNonTrivial18ContainsNonTrivial(%[[STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})
147// CHECK: call %struct.ContainsNonTrivial* @_ZN18ContainsNonTrivialD1Ev(%[[STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})
148
149void testCallContainsNonTrivial(ContainsNonTrivial *a) {
150 testParamContainsNonTrivial(*a);
Akira Hatanaka02914dc2018-02-05 20:23:22 +0000151}