From: Anders Carlsson Date: Fri, 27 Mar 2009 19:01:12 +0000 (+0000) Subject: It is OK to cast to a private base class if the current member belongs to the class... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f8080a39e6e576a820dadb7a4e0bcf5e7c8ffa35;p=clang It is OK to cast to a private base class if the current member belongs to the class that the private base class is a base of: class A {}; class B : private A { void f(B *b) { A* a = b; } }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67860 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 85e1c2ed88..cc212434b7 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -55,6 +55,10 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base, const CXXBaseSpecifier *InacessibleBase = 0; + const CXXRecordDecl* CurrentClassDecl = 0; + if (CXXMethodDecl *MD = dyn_cast_or_null(getCurFunctionDecl())) + CurrentClassDecl = MD->getParent(); + for (BasePaths::paths_iterator Path = Paths.begin(), PathsEnd = Paths.end(); Path != PathsEnd; ++Path) { @@ -71,8 +75,9 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base, // Nothing to do. break; case AS_private: - // FIXME: Check if the current function is a member or friend. - FoundInaccessibleBase = true; + // FIXME: Check if the current function/class is a friend. + if (CurrentClassDecl != Element->Class) + FoundInaccessibleBase = true; break; case AS_protected: // FIXME: Implement diff --git a/test/SemaCXX/access-base-class.cpp b/test/SemaCXX/access-base-class.cpp index 29586759b0..f98437695e 100644 --- a/test/SemaCXX/access-base-class.cpp +++ b/test/SemaCXX/access-base-class.cpp @@ -49,3 +49,34 @@ void f(D *d) { } } + +namespace T5 { + class A {}; + + class B : private A { + void f(B *b) { + A *a = b; + } + }; +} + +namespace T6 { + class C; + + class A {}; + + class B : private A { // expected-note {{'private' inheritance specifier here}} + void f(C* c); + }; + + class C : public B { + void f(C *c) { + A* a = c; // expected-error {{conversion from 'class T6::C' to inaccessible base class 'class T6::A'}} \ + expected-error {{incompatible type initializing 'class T6::C *', expected 'class T6::A *'}} + } + }; + + void B::f(C *c) { + A *a = c; + } +}