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 | FileCheck %s -check-prefix=WIN64 3 4 namespace trivial { 5 // Trivial structs should be passed directly. 6 struct A { 7 void *p; 8 }; 9 void foo(A); 10 void bar() { 11 foo({}); 12 } 13 // CHECK-LABEL: define void @_ZN7trivial3barEv() 14 // CHECK: alloca %"struct.trivial::A" 15 // CHECK: load i8*, i8** 16 // CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}}) 17 // CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*) 18 19 // WIN64-LABEL: declare void @"\01?foo@trivial@@YAXUA@1@@Z"(i64) 20 } 21 22 namespace default_ctor { 23 struct A { 24 A(); 25 void *p; 26 }; 27 void foo(A); 28 void bar() { 29 // Core issue 1590. We can pass this type in registers, even though C++ 30 // normally doesn't permit copies when using braced initialization. 31 foo({}); 32 } 33 // CHECK-LABEL: define void @_ZN12default_ctor3barEv() 34 // CHECK: alloca %"struct.default_ctor::A" 35 // CHECK: call void @_Z{{.*}}C1Ev( 36 // CHECK: load i8*, i8** 37 // CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}}) 38 // CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*) 39 40 // WIN64-LABEL: declare void @"\01?foo@default_ctor@@YAXUA@1@@Z"(i64) 41 } 42 43 namespace move_ctor { 44 // The presence of a move constructor implicitly deletes the trivial copy ctor 45 // and means that we have to pass this struct by address. 46 struct A { 47 A(); 48 A(A &&o); 49 void *p; 50 }; 51 void foo(A); 52 void bar() { 53 foo({}); 54 } 55 // FIXME: The copy ctor is implicitly deleted. 56 // CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv() 57 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev( 58 // CHECK-DISABLED-NOT: call 59 // CHECK-DISABLED: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}}) 60 // CHECK-DISABLED-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 // FIXME: The copy ctor is deleted. 77 // CHECK-DISABLED-LABEL: define void @_ZN11all_deleted3barEv() 78 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev( 79 // CHECK-DISABLED-NOT: call 80 // CHECK-DISABLED: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}}) 81 // CHECK-DISABLED-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*) 82 83 // WIN64-LABEL: declare void @"\01?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*) 84 } 85 86 namespace implicitly_deleted { 87 struct A { 88 A(); 89 A &operator=(A &&o); 90 void *p; 91 }; 92 void foo(A); 93 void bar() { 94 foo({}); 95 } 96 // FIXME: The copy and move ctors are implicitly deleted. 97 // CHECK-DISABLED-LABEL: define void @_ZN18implicitly_deleted3barEv() 98 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev( 99 // CHECK-DISABLED-NOT: call 100 // CHECK-DISABLED: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}}) 101 // CHECK-DISABLED-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*) 102 103 // WIN64-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 // FIXME: The copy constructor is implicitly deleted. 117 // CHECK-DISABLED-LABEL: define void @_ZN11one_deleted3barEv() 118 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev( 119 // CHECK-DISABLED-NOT: call 120 // CHECK-DISABLED: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}}) 121 // CHECK-DISABLED-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*) 122 123 // WIN64-LABEL: declare void @"\01?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*) 124 } 125 126 namespace copy_defaulted { 127 struct A { 128 A(); 129 A(const A &o) = default; 130 A(A &&o) = delete; 131 void *p; 132 }; 133 void foo(A); 134 void bar() { 135 foo({}); 136 } 137 // CHECK-LABEL: define void @_ZN14copy_defaulted3barEv() 138 // CHECK: call void @_Z{{.*}}C1Ev( 139 // CHECK: load i8*, i8** 140 // CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}}) 141 // CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*) 142 143 // WIN64-LABEL: declare void @"\01?foo@copy_defaulted@@YAXUA@1@@Z"(i64) 144 } 145 146 namespace move_defaulted { 147 struct A { 148 A(); 149 A(const A &o) = delete; 150 A(A &&o) = default; 151 void *p; 152 }; 153 void foo(A); 154 void bar() { 155 foo({}); 156 } 157 // CHECK-LABEL: define void @_ZN14move_defaulted3barEv() 158 // CHECK: call void @_Z{{.*}}C1Ev( 159 // CHECK: load i8*, i8** 160 // CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}}) 161 // CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*) 162 163 // WIN64-LABEL: declare void @"\01?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"*) 164 } 165 166 namespace trivial_defaulted { 167 struct A { 168 A(); 169 A(const A &o) = default; 170 void *p; 171 }; 172 void foo(A); 173 void bar() { 174 foo({}); 175 } 176 // CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv() 177 // CHECK: call void @_Z{{.*}}C1Ev( 178 // CHECK: load i8*, i8** 179 // CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}}) 180 // CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*) 181 182 // WIN64-LABEL: declare void @"\01?foo@trivial_defaulted@@YAXUA@1@@Z"(i64) 183 } 184 185 namespace two_copy_ctors { 186 struct A { 187 A(); 188 A(const A &) = default; 189 A(const A &, int = 0); 190 void *p; 191 }; 192 struct B : A {}; 193 194 void foo(B); 195 void bar() { 196 foo({}); 197 } 198 // FIXME: This class has a non-trivial copy ctor and a trivial copy ctor. It's 199 // not clear whether we should pass by address or in registers. 200 // CHECK-DISABLED-LABEL: define void @_ZN14two_copy_ctors3barEv() 201 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev( 202 // CHECK-DISABLED: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}}) 203 // CHECK-DISABLED-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*) 204 205 // WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*) 206 } 207