diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 40 | ||||
-rw-r--r-- | clang/test/CXX/class.access/class.friend/p1.cpp | 15 |
2 files changed, 44 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index dda7f67d3f2..35b7f51df1c 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -981,12 +981,20 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, return TC_Failed; } - if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(), - SrcType, DestType, - Paths.front(), + if (!CStyle) { + switch (Self.CheckBaseClassAccess(OpRange.getBegin(), + SrcType, DestType, + Paths.front(), diag::err_downcast_from_inaccessible_base)) { - msg = 0; - return TC_Failed; + case Sema::AR_accessible: + case Sema::AR_delayed: // be optimistic + case Sema::AR_dependent: // be optimistic + break; + + case Sema::AR_inaccessible: + msg = 0; + return TC_Failed; + } } Self.BuildBasePathArray(Paths, BasePath); @@ -1065,12 +1073,22 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, return TC_Failed; } - if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(), - DestClass, SrcClass, - Paths.front(), - diag::err_upcast_to_inaccessible_base)) { - msg = 0; - return TC_Failed; + if (!CStyle) { + switch (Self.CheckBaseClassAccess(OpRange.getBegin(), + DestClass, SrcClass, + Paths.front(), + diag::err_upcast_to_inaccessible_base)) { + case Sema::AR_accessible: + case Sema::AR_delayed: + case Sema::AR_dependent: + // Optimistically assume that the delayed and dependent cases + // will work out. + break; + + case Sema::AR_inaccessible: + msg = 0; + return TC_Failed; + } } if (WasOverloadedFunction) { diff --git a/clang/test/CXX/class.access/class.friend/p1.cpp b/clang/test/CXX/class.access/class.friend/p1.cpp index af4df4c0f25..1668155c181 100644 --- a/clang/test/CXX/class.access/class.friend/p1.cpp +++ b/clang/test/CXX/class.access/class.friend/p1.cpp @@ -326,3 +326,18 @@ namespace test11 { void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}} void A::test3(int x = B::private_type()) {} // expected-error {{'private_type' is a private member of 'test11::B'}} } + + +// PR9221 +namespace test12 { + struct A { + void foo(); + }; + class B : private A { + friend void A::foo(); + void *mem; + }; + void A::foo() { + void *var = static_cast<B*>(this)->mem; + } +} |