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 | 9720514f3be323f8433dc6280cc5d278ab5c9757 (patch) | |
tree | ca43c5c190ffa89a963437b9620271a18e1e0907 /clang/lib/Sema/SemaAccess.cpp | |
parent | e61b02bcaf8a21d1507348b1a411b8f94091a328 (diff) | |
download | bcm5719-llvm-9720514f3be323f8433dc6280cc5d278ab5c9757.tar.gz bcm5719-llvm-9720514f3be323f8433dc6280cc5d278ab5c9757.zip |
An access is permitted if the current template instantiates to the appropriate
class. Add some conservative support for the idea. Fixes PR 7024.
llvm-svn: 102999
Diffstat (limited to 'clang/lib/Sema/SemaAccess.cpp')
-rw-r--r-- | clang/lib/Sema/SemaAccess.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 30c53ed75ae..444ee798587 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/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); |