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 { 13 }; 14 class D : private B { // expected-note 2 {{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}} 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}} 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}} 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 (void) c.sx; // expected-error {{'sx' is a protected member}} 158 } test(C & c)159 void B::test(C &c) { 160 (void) c.x; // expected-error {{'x' is a protected member}} 161 (void) c.sx; // expected-error {{'sx' is a protected member}} 162 } test(C & c)163 void C::test(C &c) { 164 (void) c.x; 165 (void) c.sx; 166 } test(C & c)167 void D::test(C &c) { 168 (void) c.x; // expected-error {{'x' is a protected member}} 169 (void) c.sx; // expected-error {{'sx' is a protected member}} 170 } 171 } 172 173 namespace test5 { 174 class D; 175 class A { 176 protected: int x; // expected-note 3{{member is declared here}} 177 static int sx; // expected-note 3{{member is declared here}} 178 static void test(D&); 179 }; 180 class B : public A { 181 static void test(D&); 182 }; 183 class C : protected A { 184 static void test(D&); 185 }; 186 class D : private B { // expected-note 6 {{constrained}} 187 static void test(D&); 188 }; 189 test(D & d)190 void A::test(D &d) { 191 (void) d.x; // expected-error {{'x' is a private member}} 192 (void) d.sx; // expected-error {{'sx' is a private member}} 193 } test(D & d)194 void B::test(D &d) { 195 (void) d.x; // expected-error {{'x' is a private member}} 196 (void) d.sx; // expected-error {{'sx' is a private member}} 197 } test(D & d)198 void C::test(D &d) { 199 (void) d.x; // expected-error {{'x' is a private member}} 200 (void) d.sx; // expected-error {{'sx' is a private member}} 201 } test(D & d)202 void D::test(D &d) { 203 (void) d.x; 204 (void) d.sx; 205 } 206 } 207 208 namespace test6 { 209 class Static {}; 210 class A { 211 protected: 212 void foo(int); // expected-note 3 {{can only access this member on an object of type}} 213 void foo(long); 214 static void foo(Static); 215 216 static void test(A&); 217 }; 218 class B : public A { 219 static void test(A&); 220 }; 221 class C : protected A { 222 static void test(A&); 223 }; 224 class D : private B { 225 static void test(A&); 226 }; 227 test(A & a)228 void A::test(A &a) { 229 a.foo(10); 230 a.foo(Static()); 231 } test(A & a)232 void B::test(A &a) { 233 a.foo(10); // expected-error {{'foo' is a protected member}} 234 a.foo(Static()); 235 } test(A & a)236 void C::test(A &a) { 237 a.foo(10); // expected-error {{'foo' is a protected member}} 238 a.foo(Static()); 239 } test(A & a)240 void D::test(A &a) { 241 a.foo(10); // expected-error {{'foo' is a protected member}} 242 a.foo(Static()); 243 } 244 } 245 246 namespace test7 { 247 class Static {}; 248 class A { 249 protected: 250 void foo(int); // expected-note 3 {{must name member using the type of the current context}} 251 void foo(long); 252 static void foo(Static); 253 254 static void test(); 255 }; 256 class B : public A { 257 static void test(); 258 }; 259 class C : protected A { 260 static void test(); 261 }; 262 class D : private B { 263 static void test(); 264 }; 265 test()266 void A::test() { 267 void (A::*x)(int) = &A::foo; 268 void (*sx)(Static) = &A::foo; 269 } test()270 void B::test() { 271 void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} 272 void (*sx)(Static) = &A::foo; 273 } test()274 void C::test() { 275 void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} 276 void (*sx)(Static) = &A::foo; 277 } test()278 void D::test() { 279 void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} 280 void (*sx)(Static) = &A::foo; 281 } 282 } 283 284 namespace test8 { 285 class Static {}; 286 class A { 287 protected: 288 void foo(int); // expected-note 3 {{must name member using the type of the current context}} 289 void foo(long); 290 static void foo(Static); 291 292 static void test(); 293 }; 294 class B : public A { 295 static void test(); 296 }; 297 class C : protected A { 298 static void test(); 299 }; 300 class D : private B { 301 static void test(); 302 }; 303 void call(void (A::*)(int)); 304 void calls(void (*)(Static)); 305 test()306 void A::test() { 307 call(&A::foo); 308 calls(&A::foo); 309 } test()310 void B::test() { 311 call(&A::foo); // expected-error {{'foo' is a protected member}} 312 calls(&A::foo); 313 } test()314 void C::test() { 315 call(&A::foo); // expected-error {{'foo' is a protected member}} 316 calls(&A::foo); 317 } test()318 void D::test() { 319 call(&A::foo); // expected-error {{'foo' is a protected member}} 320 calls(&A::foo); 321 } 322 } 323 324 namespace test9 { 325 class A { // expected-note {{member is declared here}} 326 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}} 327 }; 328 329 class B : public A { // expected-note {{member is declared here}} 330 friend class D; 331 }; 332 333 class C : protected B { // expected-note {{declared}} \ 334 // expected-note 7 {{constrained}} 335 }; 336 337 class D : public A { test(A & a)338 static void test(A &a) { 339 a.foo(); // expected-error {{'foo' is a protected member}} 340 a.A::foo(); // expected-error {{'foo' is a protected member}} 341 a.B::foo(); // expected-error {{'foo' is a protected member}} 342 a.C::foo(); // expected-error {{'foo' is a protected member}} 343 a.D::foo(); // expected-error {{'foo' is a protected member}} 344 } 345 test(B & b)346 static void test(B &b) { 347 b.foo(); 348 b.A::foo(); 349 b.B::foo(); // accessible as named in A 350 b.C::foo(); // expected-error {{'foo' is a protected member}} 351 } 352 test(C & c)353 static void test(C &c) { 354 c.foo(); // expected-error {{'foo' is a protected member}} 355 c.A::foo(); // expected-error {{'A' is a protected member}} \ 356 // expected-error {{cannot cast}} 357 c.B::foo(); // expected-error {{'B' is a protected member}} \ 358 // expected-error {{cannot cast}} 359 c.C::foo(); // expected-error {{'foo' is a protected member}} 360 } 361 test(D & d)362 static void test(D &d) { 363 d.foo(); 364 d.A::foo(); 365 d.B::foo(); 366 d.C::foo(); // expected-error {{'foo' is a protected member}} 367 } 368 }; 369 } 370 371 namespace test10 { 372 template<typename T> class A { 373 protected: 374 int foo(); 375 int foo() const; 376 ~A()377 ~A() { foo(); } 378 }; 379 380 template class A<int>; 381 } 382 383 // class.protected friendship 384 namespace test11 { 385 class A { 386 protected: 387 int foo(); 388 }; 389 390 class B : public A { 391 friend class C; 392 }; 393 394 class C { test()395 void test() { 396 B b; 397 b.A::foo(); 398 } 399 }; 400 } 401 402 // This friendship is considered because a public member of A would be 403 // a private member of C. 404 namespace test12 { 405 class A { protected: int foo(); }; 406 class B : public virtual A {}; 407 class C : private B { friend void test(); }; 408 class D : private C, public virtual A {}; 409 test()410 void test() { 411 D d; 412 d.A::foo(); 413 } 414 } 415 416 // This friendship is not considered because a public member of A is 417 // inaccessible in C. 418 namespace test13 { 419 class A { protected: int foo(); }; // expected-note {{declared protected here}} 420 class B : private virtual A {}; 421 class C : private B { friend void test(); }; 422 class D : public virtual A {}; 423 test()424 void test() { 425 D d; 426 d.A::foo(); // expected-error {{protected member}} 427 } 428 } 429 430 // PR8058 431 namespace test14 { 432 class A { 433 protected: 434 template <class T> void temp(T t); // expected-note {{must name member using the type of the current context}} 435 436 void nontemp(int); // expected-note {{must name member using the type of the current context}} 437 438 template <class T> void ovl_temp(T t); // expected-note {{must name member using the type of the current context}} 439 void ovl_temp(float); 440 441 void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}} 442 void ovl_nontemp(float); 443 444 template <class T> void ovl_withtemp(T); 445 void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}} 446 }; 447 448 class B : public A { use()449 void use() { 450 void (A::*ptr)(int); 451 ptr = &A::temp; // expected-error {{protected member}} 452 ptr = &A::nontemp; // expected-error {{protected member}} 453 ptr = &A::ovl_temp; // expected-error {{protected member}} 454 ptr = &A::ovl_nontemp; // expected-error {{protected member}} 455 ptr = &A::ovl_withtemp; // expected-error {{protected member}} 456 } 457 }; 458 } 459 460 namespace test15 { 461 class A { 462 protected: 463 A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}} 464 A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}} 465 ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}} 466 }; 467 468 class B : public A { 469 // The uses here are fine. B()470 B() {} B(int i)471 B(int i) : A() {} ~B()472 ~B() {} 473 474 // All these uses are bad. 475 test0()476 void test0() { 477 A a; // expected-error {{protected constructor}} expected-error {{protected destructor}} 478 } 479 test1()480 A *test1() { 481 return new A(); // expected-error {{protected constructor}} 482 } 483 test2(A * a)484 void test2(A *a) { 485 delete a; // expected-error {{protected destructor}} 486 } 487 test3(A * a)488 A test3(A *a) { 489 return *a; // expected-error {{protected constructor}} 490 } 491 test4(A * a)492 void test4(A *a) { 493 a->~A(); // expected-error {{protected member}} 494 } 495 }; 496 } 497 498 namespace test16 { 499 class A { 500 protected: 501 ~A(); 502 }; 503 504 class B : public virtual A { 505 public: ~B()506 ~B() {} 507 }; 508 509 class C : public B { ~C()510 ~C() {} 511 }; 512 } 513