1 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI 2 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-unknown-unknown -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI 3 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-scei-ps4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI 4 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-sie-ps5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI 5 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-18 6 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-19 7 8 namespace trivial { 9 // Trivial structs should be passed directly. 10 struct A { 11 void *p; 12 }; 13 void foo(A); 14 void bar() { 15 foo({}); 16 } 17 // CHECK-LABEL: define{{.*}} void @_ZN7trivial3barEv() 18 // CHECK: alloca %"struct.trivial::A" 19 // CHECK: load i8*, i8** 20 // CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}}) 21 // CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*) 22 23 // WIN64-LABEL: declare dso_local void @"?foo@trivial@@YAXUA@1@@Z"(i64) 24 } 25 26 namespace default_ctor { 27 struct A { 28 A(); 29 void *p; 30 }; 31 void foo(A); 32 void bar() { 33 // Core issue 1590. We can pass this type in registers, even though C++ 34 // normally doesn't permit copies when using braced initialization. 35 foo({}); 36 } 37 // CHECK-LABEL: define{{.*}} void @_ZN12default_ctor3barEv() 38 // CHECK: alloca %"struct.default_ctor::A" 39 // CHECK: call void @_Z{{.*}}C1Ev( 40 // CHECK: load i8*, i8** 41 // CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}}) 42 // CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*) 43 44 // WIN64-LABEL: declare dso_local void @"?foo@default_ctor@@YAXUA@1@@Z"(i64) 45 } 46 47 namespace move_ctor { 48 // The presence of a move constructor implicitly deletes the trivial copy ctor 49 // and means that we have to pass this struct by address. 50 struct A { 51 A(); 52 A(A &&o); 53 void *p; 54 }; 55 void foo(A); 56 void bar() { 57 foo({}); 58 } 59 // CHECK-LABEL: define{{.*}} void @_ZN9move_ctor3barEv() 60 // CHECK: call void @_Z{{.*}}C1Ev( 61 // CHECK-NOT: call 62 // NEWABI: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* noundef %{{.*}}) 63 // OLDABI: call void @_ZN9move_ctor3fooENS_1AE(i8* %{{.*}}) 64 // NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* noundef) 65 // OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(i8*) 66 67 // WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"* noundef) 68 } 69 70 namespace all_deleted { 71 struct A { 72 A(); 73 A(const A &o) = delete; 74 A(A &&o) = delete; 75 void *p; 76 }; 77 void foo(A); 78 void bar() { 79 foo({}); 80 } 81 // CHECK-LABEL: define{{.*}} void @_ZN11all_deleted3barEv() 82 // CHECK: call void @_Z{{.*}}C1Ev( 83 // CHECK-NOT: call 84 // NEWABI: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* noundef %{{.*}}) 85 // OLDABI: call void @_ZN11all_deleted3fooENS_1AE(i8* %{{.*}}) 86 // NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* noundef) 87 // OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(i8*) 88 89 // WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"* noundef) 90 } 91 92 namespace implicitly_deleted { 93 struct A { 94 A(); 95 A &operator=(A &&o); 96 void *p; 97 }; 98 void foo(A); 99 void bar() { 100 foo({}); 101 } 102 // CHECK-LABEL: define{{.*}} void @_ZN18implicitly_deleted3barEv() 103 // CHECK: call void @_Z{{.*}}C1Ev( 104 // CHECK-NOT: call 105 // NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* noundef %{{.*}}) 106 // OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(i8* %{{.*}}) 107 // NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* noundef) 108 // OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(i8*) 109 110 // In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is. 111 // WIN64-18-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(i64 112 // WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"* noundef) 113 } 114 115 namespace one_deleted { 116 struct A { 117 A(); 118 A(A &&o) = delete; 119 void *p; 120 }; 121 void foo(A); 122 void bar() { 123 foo({}); 124 } 125 // CHECK-LABEL: define{{.*}} void @_ZN11one_deleted3barEv() 126 // CHECK: call void @_Z{{.*}}C1Ev( 127 // CHECK-NOT: call 128 // NEWABI: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* noundef %{{.*}}) 129 // OLDABI: call void @_ZN11one_deleted3fooENS_1AE(i8* %{{.*}}) 130 // NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* noundef) 131 // OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(i8*) 132 133 // WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"* noundef) 134 } 135 136 namespace copy_defaulted { 137 struct A { 138 A(); 139 A(const A &o) = default; 140 A(A &&o) = delete; 141 void *p; 142 }; 143 void foo(A); 144 void bar() { 145 foo({}); 146 } 147 // CHECK-LABEL: define{{.*}} void @_ZN14copy_defaulted3barEv() 148 // CHECK: call void @_Z{{.*}}C1Ev( 149 // CHECK: load i8*, i8** 150 // CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}}) 151 // CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*) 152 153 // WIN64-LABEL: declare dso_local void @"?foo@copy_defaulted@@YAXUA@1@@Z"(i64) 154 } 155 156 namespace move_defaulted { 157 struct A { 158 A(); 159 A(const A &o) = delete; 160 A(A &&o) = default; 161 void *p; 162 }; 163 void foo(A); 164 void bar() { 165 foo({}); 166 } 167 // CHECK-LABEL: define{{.*}} void @_ZN14move_defaulted3barEv() 168 // CHECK: call void @_Z{{.*}}C1Ev( 169 // CHECK: load i8*, i8** 170 // CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}}) 171 // CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*) 172 173 // WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"* noundef) 174 } 175 176 namespace trivial_defaulted { 177 struct A { 178 A(); 179 A(const A &o) = default; 180 void *p; 181 }; 182 void foo(A); 183 void bar() { 184 foo({}); 185 } 186 // CHECK-LABEL: define{{.*}} void @_ZN17trivial_defaulted3barEv() 187 // CHECK: call void @_Z{{.*}}C1Ev( 188 // CHECK: load i8*, i8** 189 // CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}}) 190 // CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*) 191 192 // WIN64-LABEL: declare dso_local void @"?foo@trivial_defaulted@@YAXUA@1@@Z"(i64) 193 } 194 195 namespace two_copy_ctors { 196 struct A { 197 A(); 198 A(const A &) = default; 199 A(const A &, int = 0); 200 void *p; 201 }; 202 struct B : A {}; 203 204 void foo(B); 205 void bar() { 206 foo({}); 207 } 208 // CHECK-LABEL: define{{.*}} void @_ZN14two_copy_ctors3barEv() 209 // CHECK: call void @_Z{{.*}}C1Ev( 210 // NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* noundef %{{.*}}) 211 // OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* noundef byval 212 // NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* noundef) 213 // OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* noundef byval 214 215 // WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"* noundef) 216 } 217 218 namespace definition_only { 219 struct A { 220 A(); 221 A(A &&o); 222 void *p; 223 }; 224 void *foo(A a) { return a.p; } 225 // NEWABI-LABEL: define{{.*}} i8* @_ZN15definition_only3fooENS_1AE(%"struct.definition_only::A"* 226 // OLDABI-LABEL: define{{.*}} i8* @_ZN15definition_only3fooENS_1AE(i8* 227 // WIN64-LABEL: define dso_local noundef i8* @"?foo@definition_only@@YAPEAXUA@1@@Z"(%"struct.definition_only::A"* 228 } 229 230 namespace deleted_by_member { 231 struct B { 232 B(); 233 B(B &&o); 234 void *p; 235 }; 236 struct A { 237 A(); 238 B b; 239 }; 240 void *foo(A a) { return a.b.p; } 241 // NEWABI-LABEL: define{{.*}} i8* @_ZN17deleted_by_member3fooENS_1AE(%"struct.deleted_by_member::A"* 242 // OLDABI-LABEL: define{{.*}} i8* @_ZN17deleted_by_member3fooENS_1AE(i8* 243 // WIN64-LABEL: define dso_local noundef i8* @"?foo@deleted_by_member@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member::A"* 244 } 245 246 namespace deleted_by_base { 247 struct B { 248 B(); 249 B(B &&o); 250 void *p; 251 }; 252 struct A : B { 253 A(); 254 }; 255 void *foo(A a) { return a.p; } 256 // NEWABI-LABEL: define{{.*}} i8* @_ZN15deleted_by_base3fooENS_1AE(%"struct.deleted_by_base::A"* 257 // OLDABI-LABEL: define{{.*}} i8* @_ZN15deleted_by_base3fooENS_1AE(i8* 258 // WIN64-LABEL: define dso_local noundef i8* @"?foo@deleted_by_base@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base::A"* 259 } 260 261 namespace deleted_by_member_copy { 262 struct B { 263 B(); 264 B(const B &o) = delete; 265 void *p; 266 }; 267 struct A { 268 A(); 269 B b; 270 }; 271 void *foo(A a) { return a.b.p; } 272 // NEWABI-LABEL: define{{.*}} i8* @_ZN22deleted_by_member_copy3fooENS_1AE(%"struct.deleted_by_member_copy::A"* 273 // OLDABI-LABEL: define{{.*}} i8* @_ZN22deleted_by_member_copy3fooENS_1AE(i8* 274 // WIN64-LABEL: define dso_local noundef i8* @"?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member_copy::A"* 275 } 276 277 namespace deleted_by_base_copy { 278 struct B { 279 B(); 280 B(const B &o) = delete; 281 void *p; 282 }; 283 struct A : B { 284 A(); 285 }; 286 void *foo(A a) { return a.p; } 287 // NEWABI-LABEL: define{{.*}} i8* @_ZN20deleted_by_base_copy3fooENS_1AE(%"struct.deleted_by_base_copy::A"* 288 // OLDABI-LABEL: define{{.*}} i8* @_ZN20deleted_by_base_copy3fooENS_1AE(i8* 289 // WIN64-LABEL: define dso_local noundef i8* @"?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base_copy::A"* 290 } 291 292 namespace explicit_delete { 293 struct A { 294 A(); 295 A(const A &o) = delete; 296 void *p; 297 }; 298 // NEWABI-LABEL: define{{.*}} i8* @_ZN15explicit_delete3fooENS_1AE(%"struct.explicit_delete::A"* 299 // OLDABI-LABEL: define{{.*}} i8* @_ZN15explicit_delete3fooENS_1AE(i8* 300 // WIN64-LABEL: define dso_local noundef i8* @"?foo@explicit_delete@@YAPEAXUA@1@@Z"(%"struct.explicit_delete::A"* 301 void *foo(A a) { return a.p; } 302 } 303 304 namespace implicitly_deleted_copy_ctor { 305 struct A { 306 // No move ctor due to copy assignment. 307 A &operator=(const A&); 308 // Deleted copy ctor due to rvalue ref member. 309 int &&ref; 310 }; 311 // NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(%"struct.implicitly_deleted_copy_ctor::A"* 312 // OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(i32* 313 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(%"struct.implicitly_deleted_copy_ctor::A"* 314 int &foo(A a) { return a.ref; } 315 316 struct B { 317 // Passed direct: has non-deleted trivial copy ctor. 318 B &operator=(const B&); 319 int &ref; 320 }; 321 int &foo(B b) { return b.ref; } 322 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(i32* 323 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64 324 325 struct X { X(const X&); }; 326 struct Y { Y(const Y&) = default; }; 327 328 union C { 329 C &operator=(const C&); 330 // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor. 331 X x; 332 int n; 333 }; 334 int foo(C c) { return c.n; } 335 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(%"union.implicitly_deleted_copy_ctor::C"* 336 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(%"union.implicitly_deleted_copy_ctor::C"* 337 338 struct D { 339 D &operator=(const D&); 340 // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor. 341 union { 342 X x; 343 int n; 344 }; 345 }; 346 int foo(D d) { return d.n; } 347 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(%"struct.implicitly_deleted_copy_ctor::D"* 348 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(%"struct.implicitly_deleted_copy_ctor::D"* 349 350 union E { 351 // Passed direct: has non-deleted trivial copy ctor. 352 E &operator=(const E&); 353 Y y; 354 int n; 355 }; 356 int foo(E e) { return e.n; } 357 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32 358 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32 359 360 struct F { 361 // Passed direct: has non-deleted trivial copy ctor. 362 F &operator=(const F&); 363 union { 364 Y y; 365 int n; 366 }; 367 }; 368 int foo(F f) { return f.n; } 369 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32 370 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32 371 } 372