diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp | 83 |
1 files changed, 34 insertions, 49 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp b/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp index 4af3c0f30a8e..df6edb21a50d 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp @@ -10,8 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/Specifiers.h" -#include "clang/Sema/SemaInternal.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" @@ -19,9 +17,12 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DependentDiagnostic.h" #include "clang/AST/ExprCXX.h" +#include "clang/Basic/Specifiers.h" #include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/SemaInternal.h" +#include "llvm/ADT/STLForwardCompat.h" using namespace clang; using namespace sema; @@ -33,9 +34,6 @@ enum AccessResult { AR_dependent }; -/// SetMemberAccessSpecifier - Set the access specifier of a member. -/// Returns true on error (when the previous member decl access specifier -/// is different from the new member decl access specifier). bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS) { @@ -1472,12 +1470,32 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, // specifier, like this: // A::private_type A::foo() { ... } // - // Or we might be parsing something that will turn out to be a friend: - // void foo(A::private_type); - // void B::foo(A::private_type); + // friend declaration should not be delayed because it may lead to incorrect + // redeclaration chain, such as: + // class D { + // class E{ + // class F{}; + // friend void foo(D::E::F& q); + // }; + // friend void foo(D::E::F& q); + // }; if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { - S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity)); - return Sema::AR_delayed; + // [class.friend]p9: + // A member nominated by a friend declaration shall be accessible in the + // class containing the friend declaration. The meaning of the friend + // declaration is the same whether the friend declaration appears in the + // private, protected, or public ([class.mem]) portion of the class + // member-specification. + Scope *TS = S.getCurScope(); + bool IsFriendDeclaration = false; + while (TS && !IsFriendDeclaration) { + IsFriendDeclaration = TS->isFriendScope(); + TS = TS->getParent(); + } + if (!IsFriendDeclaration) { + S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity)); + return Sema::AR_delayed; + } } EffectiveContext EC(S.CurContext); @@ -1569,8 +1587,6 @@ Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, return CheckAccess(*this, E->getNameLoc(), Entity); } -/// Perform access-control checking on a previously-unresolved member -/// access which has now been resolved to a member. Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair Found) { if (!getLangOpts().AccessControl || @@ -1588,8 +1604,6 @@ Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, return CheckAccess(*this, E->getMemberLoc(), Entity); } -/// Is the given member accessible for the purposes of deciding whether to -/// define a special member function as deleted? bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, @@ -1637,7 +1651,6 @@ Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc, return CheckAccess(*this, Loc, Entity); } -/// Checks access to a constructor. Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, CXXConstructorDecl *Constructor, DeclAccessPair Found, @@ -1658,21 +1671,24 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, case InitializedEntity::EK_Base: PD = PDiag(diag::err_access_base_ctor); PD << Entity.isInheritedVirtualBase() - << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor); + << Entity.getBaseSpecifier()->getType() + << llvm::to_underlying(getSpecialMember(Constructor)); break; 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); + PD << Field->getType() + << llvm::to_underlying(getSpecialMember(Constructor)); break; } case InitializedEntity::EK_LambdaCapture: { StringRef VarName = Entity.getCapturedVarName(); PD = PDiag(diag::err_access_lambda_capture); - PD << VarName << Entity.getType() << getSpecialMember(Constructor); + PD << VarName << Entity.getType() + << llvm::to_underlying(getSpecialMember(Constructor)); break; } @@ -1681,7 +1697,6 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD); } -/// Checks access to a constructor. Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, CXXConstructorDecl *Constructor, DeclAccessPair Found, @@ -1723,7 +1738,6 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, return CheckAccess(*this, UseLoc, AccessEntity); } -/// Checks access to an overloaded operator new or delete. Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, @@ -1743,7 +1757,6 @@ Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, return CheckAccess(*this, OpLoc, Entity); } -/// Checks access to a member. Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found) { @@ -1758,7 +1771,6 @@ Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc, return CheckAccess(*this, UseLoc, Entity); } -/// Checks implicit access to a member in a structured binding. Sema::AccessResult Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, @@ -1791,8 +1803,6 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, 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, @@ -1815,7 +1825,6 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, 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())); @@ -1865,12 +1874,6 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr, return CheckAccess(*this, Ovl->getNameLoc(), Entity); } -/// Checks access for a hierarchy conversion. -/// -/// \param ForceCheck true if this check should be performed even if access -/// control is disabled; some things rely on this for semantics -/// \param ForceUnprivileged true if this check should proceed as if the -/// context had no special privileges Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, @@ -1905,7 +1908,6 @@ Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc, return CheckAccess(*this, AccessLoc, Entity); } -/// Checks access to all the declarations in the given result set. void Sema::CheckLookupAccess(const LookupResult &R) { assert(getLangOpts().AccessControl && "performing access check without access control"); @@ -1922,23 +1924,6 @@ void Sema::CheckLookupAccess(const LookupResult &R) { } } -/// Checks access to Target from the given class. The check will take access -/// specifiers into account, but no member access expressions and such. -/// -/// \param Target the declaration to check if it can be accessed -/// \param NamingClass the class in which the lookup was started. -/// \param BaseType type of the left side of member access expression. -/// \p BaseType and \p NamingClass are used for C++ access control. -/// Depending on the lookup case, they should be set to the following: -/// - lhs.target (member access without a qualifier): -/// \p BaseType and \p NamingClass are both the type of 'lhs'. -/// - lhs.X::target (member access with a qualifier): -/// BaseType is the type of 'lhs', NamingClass is 'X' -/// - X::target (qualified lookup without member access): -/// BaseType is null, NamingClass is 'X'. -/// - target (unqualified lookup). -/// BaseType is null, NamingClass is the parent class of 'target'. -/// \return true if the Target is accessible from the Class, false otherwise. bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass, QualType BaseType) { // Perform the C++ accessibility checks first. |