diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp | 87 |
1 files changed, 67 insertions, 20 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp b/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp index be30445d143c..4af3c0f30a8e 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp @@ -84,6 +84,20 @@ struct EffectiveContext { : Inner(DC), Dependent(DC->isDependentContext()) { + // An implicit deduction guide is semantically in the context enclosing the + // class template, but for access purposes behaves like the constructor + // from which it was produced. + if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) { + if (DGD->isImplicit()) { + DC = DGD->getCorrespondingConstructor(); + if (!DC) { + // The copy deduction candidate doesn't have a corresponding + // constructor. + DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl()); + } + } + } + // C++11 [class.access.nest]p1: // A nested class is a member and as such has the same access // rights as any other member. @@ -126,7 +140,7 @@ struct EffectiveContext { bool includesClass(const CXXRecordDecl *R) const { R = R->getCanonicalDecl(); - return llvm::find(Records, R) != Records.end(); + return llvm::is_contained(Records, R); } /// Retrieves the innermost "useful" context. Can be null if we're @@ -185,6 +199,16 @@ struct AccessTarget : public AccessedEntity { : Target(S.Target), Has(S.Has) { S.Target = nullptr; } + + // The move assignment operator is defined as deleted pending further + // motivation. + SavedInstanceContext &operator=(SavedInstanceContext &&) = delete; + + // The copy constrcutor and copy assignment operator is defined as deleted + // pending further motivation. + SavedInstanceContext(const SavedInstanceContext &) = delete; + SavedInstanceContext &operator=(const SavedInstanceContext &) = delete; + ~SavedInstanceContext() { if (Target) Target->HasInstanceContext = Has; @@ -1294,17 +1318,18 @@ static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S, SourceLocation AccessLoc, AccessTarget &Entity) { if (UsingShadowDecl *Shadow = - dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) { - const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl(); - if (Entity.getTargetDecl()->getAccess() == AS_private && - (OrigDecl->getAccess() == AS_public || - OrigDecl->getAccess() == AS_protected)) { - S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible) - << Shadow->getUsingDecl()->getQualifiedNameAsString() - << OrigDecl->getQualifiedNameAsString(); - return true; + dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) + if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) { + const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl(); + if (Entity.getTargetDecl()->getAccess() == AS_private && + (OrigDecl->getAccess() == AS_public || + OrigDecl->getAccess() == AS_protected)) { + S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible) + << UD->getQualifiedNameAsString() + << OrigDecl->getQualifiedNameAsString(); + return true; + } } - } return false; } @@ -1478,6 +1503,8 @@ void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) { } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) { if (isa<DeclContext>(TD->getTemplatedDecl())) DC = cast<DeclContext>(TD->getTemplatedDecl()); + } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) { + DC = RD; } EffectiveContext EC(DC); @@ -1634,7 +1661,8 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor); break; - case InitializedEntity::EK_Member: { + case InitializedEntity::EK_Member: + case InitializedEntity::EK_ParenAggInitMember: { const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl()); PD = PDiag(diag::err_access_field_ctor); PD << Field->getType() << getSpecialMember(Constructor); @@ -1746,14 +1774,11 @@ Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc, return CheckAccess(*this, UseLoc, Entity); } -/// Checks access to an overloaded member operator, including -/// conversion operators. Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, Expr *ObjectExpr, - Expr *ArgExpr, + const SourceRange &Range, DeclAccessPair Found) { - if (!getLangOpts().AccessControl || - Found.getAccess() == AS_public) + if (!getLangOpts().AccessControl || Found.getAccess() == AS_public) return AR_accessible; const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>(); @@ -1761,13 +1786,35 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, ObjectExpr->getType()); - Entity.setDiag(diag::err_access) - << ObjectExpr->getSourceRange() - << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange()); + Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range; return CheckAccess(*this, OpLoc, Entity); } +/// Checks access to an overloaded member operator, including +/// conversion operators. +Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, + Expr *ObjectExpr, + Expr *ArgExpr, + DeclAccessPair Found) { + return CheckMemberOperatorAccess( + OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(), + Found); +} + +Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, + Expr *ObjectExpr, + ArrayRef<Expr *> ArgExprs, + DeclAccessPair FoundDecl) { + SourceRange R; + if (!ArgExprs.empty()) { + R = SourceRange(ArgExprs.front()->getBeginLoc(), + ArgExprs.back()->getEndLoc()); + } + + return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl); +} + /// Checks access to the target of a friend declaration. Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) { assert(isa<CXXMethodDecl>(target->getAsFunction())); |