|
1 |
| -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -fobjc-exceptions %s |
| 1 | +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -fobjc-weak -verify -fblocks -fobjc-exceptions %s |
2 | 2 |
|
3 | 3 | // "Move" semantics, trivial version.
|
4 | 4 | void move_it(__strong id &&from) {
|
@@ -111,3 +111,160 @@ void test() {
|
111 | 111 | func(^(A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
|
112 | 112 | }
|
113 | 113 | }
|
| 114 | + |
| 115 | +namespace test_union { |
| 116 | + // Implicitly-declared special functions of a union are deleted by default if |
| 117 | + // ARC is enabled and the union has an ObjC pointer field. |
| 118 | + union U0 { |
| 119 | + id f0; // expected-note 6 {{'U0' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| 120 | + }; |
| 121 | + |
| 122 | + union U1 { |
| 123 | + __weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| 124 | + U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} |
| 125 | + ~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} |
| 126 | + U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} |
| 127 | + U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}} |
| 128 | + U1 & operator=(const U1 &) = default; // expected-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} |
| 129 | + U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}} |
| 130 | + }; |
| 131 | + |
| 132 | + id getStrong(); |
| 133 | + |
| 134 | + // If the ObjC pointer field of a union has a default member initializer, the |
| 135 | + // implicitly-declared default constructor of the union is not deleted by |
| 136 | + // default. |
| 137 | + union U2 { |
| 138 | + id f0 = getStrong(); // expected-note 4 {{'U2' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| 139 | + ~U2(); |
| 140 | + }; |
| 141 | + |
| 142 | + // It's fine if the user has explicitly defined the special functions. |
| 143 | + union U3 { |
| 144 | + id f0; |
| 145 | + U3(); |
| 146 | + ~U3(); |
| 147 | + U3(const U3 &); |
| 148 | + U3(U3 &&); |
| 149 | + U3 & operator=(const U3 &); |
| 150 | + U3 & operator=(U3 &&); |
| 151 | + }; |
| 152 | + |
| 153 | + // ObjC pointer fields in anonymous union fields delete the defaulted special |
| 154 | + // functions of the containing class. |
| 155 | + struct S0 { |
| 156 | + union { |
| 157 | + id f0; // expected-note 6 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| 158 | + char f1; |
| 159 | + }; |
| 160 | + }; |
| 161 | + |
| 162 | + struct S1 { |
| 163 | + union { |
| 164 | + union { // expected-note 2 {{'S1' is implicitly deleted because variant field '' has a non-trivial}} expected-note 4 {{'S1' is implicitly deleted because field '' has a deleted}} |
| 165 | + id f0; // expected-note 2 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| 166 | + char f1; |
| 167 | + }; |
| 168 | + int f2; |
| 169 | + }; |
| 170 | + }; |
| 171 | + |
| 172 | + struct S2 { |
| 173 | + union { |
| 174 | + // FIXME: the note should say 'f0' is causing the special functions to be deleted. |
| 175 | + struct { // expected-note 6 {{'S2' is implicitly deleted because variant field '' has a non-trivial}} |
| 176 | + id f0; |
| 177 | + int f1; |
| 178 | + }; |
| 179 | + int f2; |
| 180 | + }; |
| 181 | + int f3; |
| 182 | + }; |
| 183 | + |
| 184 | + U0 *x0; |
| 185 | + U1 *x1; |
| 186 | + U2 *x2; |
| 187 | + U3 *x3; |
| 188 | + S0 *x4; |
| 189 | + S1 *x5; |
| 190 | + S2 *x6; |
| 191 | + |
| 192 | + static union { // expected-error {{call to implicitly-deleted default constructor of}} |
| 193 | + id g0; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g0' is an ObjC pointer}} |
| 194 | + }; |
| 195 | + |
| 196 | + static union { // expected-error {{call to implicitly-deleted default constructor of}} |
| 197 | + union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}} |
| 198 | + union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}} |
| 199 | + __weak id g1; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g1' is an ObjC pointer}} |
| 200 | + int g2; |
| 201 | + }; |
| 202 | + int g3; |
| 203 | + }; |
| 204 | + int g4; |
| 205 | + }; |
| 206 | + |
| 207 | + void testDefaultConstructor() { |
| 208 | + U0 t0; // expected-error {{call to implicitly-deleted default constructor}} |
| 209 | + U1 t1; // expected-error {{call to implicitly-deleted default constructor}} |
| 210 | + U2 t2; |
| 211 | + U3 t3; |
| 212 | + S0 t4; // expected-error {{call to implicitly-deleted default constructor}} |
| 213 | + S1 t5; // expected-error {{call to implicitly-deleted default constructor}} |
| 214 | + S2 t6; // expected-error {{call to implicitly-deleted default constructor}} |
| 215 | + } |
| 216 | + |
| 217 | + void testDestructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| 218 | + delete u0; // expected-error {{attempt to use a deleted function}} |
| 219 | + delete u1; // expected-error {{attempt to use a deleted function}} |
| 220 | + delete u2; |
| 221 | + delete u3; |
| 222 | + delete s0; // expected-error {{attempt to use a deleted function}} |
| 223 | + delete s1; // expected-error {{attempt to use a deleted function}} |
| 224 | + delete s2; // expected-error {{attempt to use a deleted function}} |
| 225 | + } |
| 226 | + |
| 227 | + void testCopyConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| 228 | + U0 t0(*u0); // expected-error {{call to implicitly-deleted copy constructor}} |
| 229 | + U1 t1(*u1); // expected-error {{call to implicitly-deleted copy constructor}} |
| 230 | + U2 t2(*u2); // expected-error {{call to implicitly-deleted copy constructor}} |
| 231 | + U3 t3(*u3); |
| 232 | + S0 t4(*s0); // expected-error {{call to implicitly-deleted copy constructor}} |
| 233 | + S1 t5(*s1); // expected-error {{call to implicitly-deleted copy constructor}} |
| 234 | + S2 t6(*s2); // expected-error {{call to implicitly-deleted copy constructor}} |
| 235 | + } |
| 236 | + |
| 237 | + void testCopyAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| 238 | + *x0 = *u0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 239 | + *x1 = *u1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 240 | + *x2 = *u2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 241 | + *x3 = *u3; |
| 242 | + *x4 = *s0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 243 | + *x5 = *s1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 244 | + *x6 = *s2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 245 | + } |
| 246 | + |
| 247 | + // The diagnostics below refer to the deleted copy constructors and assignment |
| 248 | + // operators since defaulted move constructors and assignment operators that are |
| 249 | + // defined as deleted are ignored by overload resolution. |
| 250 | + |
| 251 | + void testMoveConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| 252 | + U0 t0(static_cast<U0 &&>(*u0)); // expected-error {{call to implicitly-deleted copy constructor}} |
| 253 | + U1 t1(static_cast<U1 &&>(*u1)); // expected-error {{call to implicitly-deleted copy constructor}} |
| 254 | + U2 t2(static_cast<U2 &&>(*u2)); // expected-error {{call to implicitly-deleted copy constructor}} |
| 255 | + U3 t3(static_cast<U3 &&>(*u3)); |
| 256 | + S0 t4(static_cast<S0 &&>(*s0)); // expected-error {{call to implicitly-deleted copy constructor}} |
| 257 | + S1 t5(static_cast<S1 &&>(*s1)); // expected-error {{call to implicitly-deleted copy constructor}} |
| 258 | + S2 t6(static_cast<S2 &&>(*s2)); // expected-error {{call to implicitly-deleted copy constructor}} |
| 259 | + } |
| 260 | + |
| 261 | + void testMoveAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| 262 | + *x0 = static_cast<U0 &&>(*u0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 263 | + *x1 = static_cast<U1 &&>(*u1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 264 | + *x2 = static_cast<U2 &&>(*u2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 265 | + *x3 = static_cast<U3 &&>(*u3); |
| 266 | + *x4 = static_cast<S0 &&>(*s0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 267 | + *x5 = static_cast<S1 &&>(*s1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 268 | + *x6 = static_cast<S2 &&>(*s2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| 269 | + } |
| 270 | +} |
0 commit comments