aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp83
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.