1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 namespace test0 { 4 class A { 5 protected: int x; // expected-note 3 {{declared}} \ 6 // expected-note {{member is declared here}} 7 static int sx; // expected-note 3 {{declared}} \ 8 // expected-note {{member is declared here}} 9 }; 10 class B : public A { 11 }; 12 class C : protected A { // expected-note {{declared}} 13 }; 14 class D : private B { // expected-note 3 {{constrained}} 15 }; 16 test(A & a)17 void test(A &a) { 18 (void) a.x; // expected-error {{'x' is a protected member}} 19 (void) a.sx; // expected-error {{'sx' is a protected member}} 20 } test(B & b)21 void test(B &b) { 22 (void) b.x; // expected-error {{'x' is a protected member}} 23 (void) b.sx; // expected-error {{'sx' is a protected member}} 24 } test(C & c)25 void test(C &c) { 26 (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}} 27 (void) c.sx; // expected-error {{'sx' is a protected member}} 28 } test(D & d)29 void test(D &d) { 30 (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}} 31 (void) d.sx; // expected-error {{'sx' is a private member}} 32 } 33 } 34 35 namespace test1 { 36 class A { 37 protected: int x; 38 static int sx; 39 static void test(A&); 40 }; 41 class B : public A { 42 static void test(B&); 43 }; 44 class C : protected A { 45 static void test(C&); 46 }; 47 class D : private B { 48 static void test(D&); 49 }; 50 test(A & a)51 void A::test(A &a) { 52 (void) a.x; 53 (void) a.sx; 54 } test(B & b)55 void B::test(B &b) { 56 (void) b.x; 57 (void) b.sx; 58 } test(C & c)59 void C::test(C &c) { 60 (void) c.x; 61 (void) c.sx; 62 } test(D & d)63 void D::test(D &d) { 64 (void) d.x; 65 (void) d.sx; 66 } 67 } 68 69 namespace test2 { 70 class A { 71 protected: int x; // expected-note 3 {{can only access this member on an object of type}} 72 static int sx; 73 static void test(A&); 74 }; 75 class B : public A { 76 static void test(A&); 77 }; 78 class C : protected A { 79 static void test(A&); 80 }; 81 class D : private B { 82 static void test(A&); 83 }; 84 test(A & a)85 void A::test(A &a) { 86 (void) a.x; 87 (void) a.sx; 88 } test(A & a)89 void B::test(A &a) { 90 (void) a.x; // expected-error {{'x' is a protected member}} 91 (void) a.sx; 92 } test(A & a)93 void C::test(A &a) { 94 (void) a.x; // expected-error {{'x' is a protected member}} 95 (void) a.sx; 96 } test(A & a)97 void D::test(A &a) { 98 (void) a.x; // expected-error {{'x' is a protected member}} 99 (void) a.sx; 100 } 101 } 102 103 namespace test3 { 104 class B; 105 class A { 106 protected: int x; //expected-note {{declared protected}} // expected-note {{can only access this member on an object of type}} 107 static int sx; 108 static void test(B&); 109 }; 110 class B : public A { 111 static void test(B&); 112 }; 113 class C : protected A { 114 static void test(B&); 115 }; 116 class D : private B { 117 static void test(B&); 118 }; 119 test(B & b)120 void A::test(B &b) { 121 (void) b.x; 122 (void) b.sx; 123 } test(B & b)124 void B::test(B &b) { 125 (void) b.x; 126 (void) b.sx; 127 } test(B & b)128 void C::test(B &b) { 129 (void) b.x; // expected-error {{'x' is a protected member}} 130 (void) b.sx; 131 } test(B & b)132 void D::test(B &b) { 133 (void) b.x; // expected-error {{'x' is a protected member}} 134 (void) b.sx; 135 } 136 } 137 138 namespace test4 { 139 class C; 140 class A { 141 protected: int x; // expected-note 2{{declared protected here}} expected-note{{member is declared here}} 142 static int sx; // expected-note 3{{member is declared here}} 143 static void test(C&); 144 }; 145 class B : public A { 146 static void test(C&); 147 }; 148 class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}} 149 static void test(C&); 150 }; 151 class D : private B { 152 static void test(C&); 153 }; 154 test(C & c)155 void A::test(C &c) { 156 (void) c.x; // expected-error {{'x' is a protected member}} \ 157 // expected-error {{protected base class}} 158 (void) c.sx; // expected-error {{'sx' is a protected member}} 159 } test(C & c)160 void B::test(C &c) { 161 (void) c.x; // expected-error {{'x' is a protected member}} \ 162 // expected-error {{protected base class}} 163 (void) c.sx; // expected-error {{'sx' is a protected member}} 164 } test(C & c)165 void C::test(C &c) { 166 (void) c.x; 167 (void) c.sx; 168 } test(C & c)169 void D::test(C &c) { 170 (void) c.x; // expected-error {{'x' is a protected member}} \ 171 // expected-error {{protected base class}} 172 (void) c.sx; // expected-error {{'sx' is a protected member}} 173 } 174 } 175 176 namespace test5 { 177 class D; 178 class A { 179 protected: int x; // expected-note 3{{member is declared here}} 180 static int sx; // expected-note 3{{member is declared here}} 181 static void test(D&); 182 }; 183 class B : public A { 184 static void test(D&); 185 }; 186 class C : protected A { 187 static void test(D&); 188 }; 189 class D : private B { // expected-note 9 {{constrained}} 190 static void test(D&); 191 }; 192 test(D & d)193 void A::test(D &d) { 194 (void) d.x; // expected-error {{'x' is a private member}} \ 195 // expected-error {{cannot cast}} 196 (void) d.sx; // expected-error {{'sx' is a private member}} 197 } test(D & d)198 void B::test(D &d) { 199 (void) d.x; // expected-error {{'x' is a private member}} \ 200 // expected-error {{cannot cast}} 201 (void) d.sx; // expected-error {{'sx' is a private member}} 202 } test(D & d)203 void C::test(D &d) { 204 (void) d.x; // expected-error {{'x' is a private member}} \ 205 // expected-error {{cannot cast}} 206 (void) d.sx; // expected-error {{'sx' is a private member}} 207 } test(D & d)208 void D::test(D &d) { 209 (void) d.x; 210 (void) d.sx; 211 } 212 } 213 214 namespace test6 { 215 class Static {}; 216 class A { 217 protected: 218 void foo(int); // expected-note 3 {{can only access this member on an object of type}} 219 void foo(long); 220 static void foo(Static); 221 222 static void test(A&); 223 }; 224 class B : public A { 225 static void test(A&); 226 }; 227 class C : protected A { 228 static void test(A&); 229 }; 230 class D : private B { 231 static void test(A&); 232 }; 233 test(A & a)234 void A::test(A &a) { 235 a.foo(10); 236 a.foo(Static()); 237 } test(A & a)238 void B::test(A &a) { 239 a.foo(10); // expected-error {{'foo' is a protected member}} 240 a.foo(Static()); 241 } test(A & a)242 void C::test(A &a) { 243 a.foo(10); // expected-error {{'foo' is a protected member}} 244 a.foo(Static()); 245 } test(A & a)246 void D::test(A &a) { 247 a.foo(10); // expected-error {{'foo' is a protected member}} 248 a.foo(Static()); 249 } 250 } 251 252 namespace test7 { 253 class Static {}; 254 class A { 255 protected: 256 void foo(int); // expected-note 3 {{must name member using the type of the current context}} 257 void foo(long); 258 static void foo(Static); 259 260 static void test(); 261 }; 262 class B : public A { 263 static void test(); 264 }; 265 class C : protected A { 266 static void test(); 267 }; 268 class D : private B { 269 static void test(); 270 }; 271 test()272 void A::test() { 273 void (A::*x)(int) = &A::foo; 274 void (*sx)(Static) = &A::foo; 275 } test()276 void B::test() { 277 void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} 278 void (*sx)(Static) = &A::foo; 279 } test()280 void C::test() { 281 void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} 282 void (*sx)(Static) = &A::foo; 283 } test()284 void D::test() { 285 void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} 286 void (*sx)(Static) = &A::foo; 287 } 288 } 289 290 namespace test8 { 291 class Static {}; 292 class A { 293 protected: 294 void foo(int); // expected-note 3 {{must name member using the type of the current context}} 295 void foo(long); 296 static void foo(Static); 297 298 static void test(); 299 }; 300 class B : public A { 301 static void test(); 302 }; 303 class C : protected A { 304 static void test(); 305 }; 306 class D : private B { 307 static void test(); 308 }; 309 void call(void (A::*)(int)); 310 void calls(void (*)(Static)); 311 test()312 void A::test() { 313 call(&A::foo); 314 calls(&A::foo); 315 } test()316 void B::test() { 317 call(&A::foo); // expected-error {{'foo' is a protected member}} 318 calls(&A::foo); 319 } test()320 void C::test() { 321 call(&A::foo); // expected-error {{'foo' is a protected member}} 322 calls(&A::foo); 323 } test()324 void D::test() { 325 call(&A::foo); // expected-error {{'foo' is a protected member}} 326 calls(&A::foo); 327 } 328 } 329 330 namespace test9 { 331 class A { // expected-note {{member is declared here}} 332 protected: int foo(); // expected-note 4 {{declared}} expected-note 3 {{can only access this member on an object of type}} expected-note 2 {{member is declared here}} 333 }; 334 335 class B : public A { // expected-note {{member is declared here}} 336 friend class D; 337 }; 338 339 class C : protected B { // expected-note {{declared}} \ 340 // expected-note 9 {{constrained}} 341 }; 342 343 class D : public A { test(A & a)344 static void test(A &a) { 345 a.foo(); // expected-error {{'foo' is a protected member}} 346 a.A::foo(); // expected-error {{'foo' is a protected member}} 347 a.B::foo(); // expected-error {{'foo' is a protected member}} 348 a.C::foo(); // expected-error {{'foo' is a protected member}} 349 a.D::foo(); // expected-error {{'foo' is a protected member}} 350 } 351 test(B & b)352 static void test(B &b) { 353 b.foo(); 354 b.A::foo(); 355 b.B::foo(); // accessible as named in A 356 b.C::foo(); // expected-error {{'foo' is a protected member}} 357 } 358 test(C & c)359 static void test(C &c) { 360 c.foo(); // expected-error {{'foo' is a protected member}} \ 361 // expected-error {{cannot cast}} 362 c.A::foo(); // expected-error {{'A' is a protected member}} \ 363 // expected-error {{cannot cast}} 364 c.B::foo(); // expected-error {{'B' is a protected member}} \ 365 // expected-error {{cannot cast}} 366 c.C::foo(); // expected-error {{'foo' is a protected member}} \ 367 // expected-error {{cannot cast}} 368 } 369 test(D & d)370 static void test(D &d) { 371 d.foo(); 372 d.A::foo(); 373 d.B::foo(); 374 d.C::foo(); // expected-error {{'foo' is a protected member}} 375 } 376 }; 377 } 378 379 namespace test10 { 380 template<typename T> class A { 381 protected: 382 int foo(); 383 int foo() const; 384 ~A()385 ~A() { foo(); } 386 }; 387 388 template class A<int>; 389 } 390 391 // rdar://problem/8360285: class.protected friendship 392 namespace test11 { 393 class A { 394 protected: 395 int foo(); 396 }; 397 398 class B : public A { 399 friend class C; 400 }; 401 402 class C { test()403 void test() { 404 B b; 405 b.A::foo(); 406 } 407 }; 408 } 409 410 // This friendship is considered because a public member of A would be 411 // a private member of C. 412 namespace test12 { 413 class A { protected: int foo(); }; 414 class B : public virtual A {}; 415 class C : private B { friend void test(); }; 416 class D : private C, public virtual A {}; 417 test()418 void test() { 419 D d; 420 d.A::foo(); 421 } 422 } 423 424 // This friendship is not considered because a public member of A is 425 // inaccessible in C. 426 namespace test13 { 427 class A { protected: int foo(); }; // expected-note {{declared protected here}} 428 class B : private virtual A {}; 429 class C : private B { friend void test(); }; 430 class D : public virtual A {}; 431 test()432 void test() { 433 D d; 434 d.A::foo(); // expected-error {{protected member}} 435 } 436 } 437 438 // PR8058 439 namespace test14 { 440 class A { 441 protected: 442 template <class T> void temp(T t); // expected-note {{must name member using the type of the current context}} 443 444 void nontemp(int); // expected-note {{must name member using the type of the current context}} 445 446 template <class T> void ovl_temp(T t); // expected-note {{must name member using the type of the current context}} 447 void ovl_temp(float); 448 449 void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}} 450 void ovl_nontemp(float); 451 452 template <class T> void ovl_withtemp(T); 453 void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}} 454 }; 455 456 class B : public A { use()457 void use() { 458 void (A::*ptr)(int); 459 ptr = &A::temp; // expected-error {{protected member}} 460 ptr = &A::nontemp; // expected-error {{protected member}} 461 ptr = &A::ovl_temp; // expected-error {{protected member}} 462 ptr = &A::ovl_nontemp; // expected-error {{protected member}} 463 ptr = &A::ovl_withtemp; // expected-error {{protected member}} 464 } 465 }; 466 } 467 468 namespace test15 { 469 class A { 470 protected: 471 A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}} 472 A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}} 473 ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}} 474 }; 475 476 class B : public A { 477 // The uses here are fine. B()478 B() {} B(int i)479 B(int i) : A() {} ~B()480 ~B() {} 481 482 // All these uses are bad. 483 test0()484 void test0() { 485 A a; // expected-error {{protected constructor}} expected-error {{protected destructor}} 486 } 487 test1()488 A *test1() { 489 return new A(); // expected-error {{protected constructor}} 490 } 491 test2(A * a)492 void test2(A *a) { 493 delete a; // expected-error {{protected destructor}} 494 } 495 test3(A * a)496 A test3(A *a) { 497 return *a; // expected-error {{protected constructor}} 498 } 499 test4(A * a)500 void test4(A *a) { 501 a->~A(); // expected-error {{protected member}} 502 } 503 }; 504 } 505 506 namespace test16 { 507 class A { 508 protected: 509 ~A(); 510 }; 511 512 class B : public virtual A { 513 public: ~B()514 ~B() {} 515 }; 516 517 class C : public B { ~C()518 ~C() {} 519 }; 520 } 521