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 {{object type must derive}} 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 {{object type must derive}} 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; 134 (void) b.sx; 135 } 136 } 137 138 namespace test4 { 139 class C; 140 class A { 141 protected: int x; // expected-note {{declared}} expected-note 2 {{object type must derive}} 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 {{object type must derive}} 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 {{object type must derive}} 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 {{object type must derive}} 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 2 {{object type must derive}} expected-note {{object type 'test9::A' must derive}} 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(); 348 a.C::foo(); // expected-error {{'foo' is a protected member}} 349 } 350 test(B & b)351 static void test(B &b) { 352 b.foo(); 353 b.A::foo(); 354 b.B::foo(); 355 b.C::foo(); // expected-error {{'foo' is a protected member}} 356 } 357 test(C & c)358 static void test(C &c) { 359 c.foo(); // expected-error {{'foo' is a protected member}} \ 360 // expected-error {{cannot cast}} 361 c.A::foo(); // expected-error {{'A' is a protected member}} \ 362 // expected-error {{cannot cast}} 363 c.B::foo(); // expected-error {{'B' is a protected member}} \ 364 // expected-error {{cannot cast}} 365 c.C::foo(); // expected-error {{'foo' is a protected member}} \ 366 // expected-error {{cannot cast}} 367 } 368 test(D & d)369 static void test(D &d) { 370 d.foo(); 371 d.A::foo(); 372 d.B::foo(); 373 d.C::foo(); // expected-error {{'foo' is a protected member}} 374 } 375 }; 376 } 377 378 namespace test10 { 379 template<typename T> class A { 380 protected: 381 int foo(); 382 int foo() const; 383 ~A()384 ~A() { foo(); } 385 }; 386 387 template class A<int>; 388 } 389 390 // rdar://problem/8360285: class.protected friendship 391 namespace test11 { 392 class A { 393 protected: 394 int foo(); 395 }; 396 397 class B : public A { 398 friend class C; 399 }; 400 401 class C { test()402 void test() { 403 B b; 404 b.A::foo(); 405 } 406 }; 407 } 408 409 // This friendship is considered because a public member of A would be 410 // a private member of C. 411 namespace test12 { 412 class A { protected: int foo(); }; 413 class B : public virtual A {}; 414 class C : private B { friend void test(); }; 415 class D : private C, public virtual A {}; 416 test()417 void test() { 418 D d; 419 d.A::foo(); 420 } 421 } 422 423 // This friendship is not considered because a public member of A is 424 // inaccessible in C. 425 namespace test13 { 426 class A { protected: int foo(); }; // expected-note {{declared protected here}} 427 class B : private virtual A {}; 428 class C : private B { friend void test(); }; 429 class D : public virtual A {}; 430 test()431 void test() { 432 D d; 433 d.A::foo(); // expected-error {{protected member}} 434 } 435 } 436