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