diff options
Diffstat (limited to 'lib')
-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); |