diff options
author | John McCall <rjmccall@apple.com> | 2010-05-04 05:11:27 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-05-04 05:11:27 +0000 |
commit | 01ebd9d1883e82c4188325900a4eb9c1e16353bb (patch) | |
tree | be62d9b946d1950c07ae9e62f2798d3e098449b6 /lib/Sema/SemaAccess.cpp | |
parent | 3d6c1782c4fc2ed3e6a924c15042edb1f56fee36 (diff) |
An access is permitted if the current template instantiates to the appropriate
class. Add some conservative support for the idea. Fixes PR 7024.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102999 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaAccess.cpp')
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 30c53ed75a..444ee79858 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -222,6 +222,22 @@ private: } +/// Checks whether one class might instantiate to the other. +static bool MightInstantiateTo(const CXXRecordDecl *From, + const CXXRecordDecl *To) { + // Declaration names are always preserved by instantiation. + if (From->getDeclName() != To->getDeclName()) + return false; + + const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext(); + const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext(); + if (FromDC == ToDC) return true; + if (FromDC->isFileContext() || ToDC->isFileContext()) return false; + + // Be conservative. + return true; +} + /// Checks whether one class is derived from another, inclusively. /// Properly indicates when it couldn't be determined due to /// dependence. @@ -234,6 +250,10 @@ static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, if (Derived == Target) return AR_accessible; + bool CheckDependent = Derived->isDependentContext(); + if (CheckDependent && MightInstantiateTo(Derived, Target)) + return AR_dependent; + AccessResult OnFailure = AR_inaccessible; llvm::SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack @@ -246,10 +266,10 @@ static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, QualType T = I->getType(); if (const RecordType *RT = T->getAs<RecordType>()) { RD = cast<CXXRecordDecl>(RT->getDecl()); + } else if (const InjectedClassNameType *IT + = T->getAs<InjectedClassNameType>()) { + RD = IT->getDecl(); } else { - // It's possible for a base class to be the current - // instantiation of some enclosing template, but I'm guessing - // nobody will ever care that we just dependently delay here. assert(T->isDependentType() && "non-dependent base wasn't a record?"); OnFailure = AR_dependent; continue; @@ -257,6 +277,9 @@ static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, RD = RD->getCanonicalDecl(); if (RD == Target) return AR_accessible; + if (CheckDependent && MightInstantiateTo(RD, Target)) + OnFailure = AR_dependent; + Queue.push_back(RD); } @@ -563,6 +586,9 @@ static AccessResult HasAccess(Sema &S, if (ECRecord == NamingClass) return AR_accessible; + if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass)) + OnFailure = AR_dependent; + // [B3] and [M3] } else { assert(Access == AS_protected); |