summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-04-09 20:53:23 +0000
committerJohn McCall <rjmccall@apple.com>2012-04-09 20:53:23 +0000
commit12d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6 (patch)
tree25960d2d9bf8000a56ab2d6929b7ca9d81b8f622 /lib/Sema/SemaDeclCXX.cpp
parentae7e939bc027ef19ca91ab8bcccb11338a0bd576 (diff)
Fix the access check performed as part of the determination of whether
to define a special member function as deleted so that it properly establishes an object context for the accesses to the base subobject members. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154343 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 975ea5b7a7..704ff834b4 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4397,9 +4397,31 @@ struct SpecialMemberDeletionInfo {
bool shouldDeleteForSubobjectCall(Subobject Subobj,
Sema::SpecialMemberOverloadResult *SMOR,
bool IsDtorCallInCtor);
+
+ bool isAccessible(Subobject Subobj, CXXMethodDecl *D);
};
}
+/// Is the given special member inaccessible when used on the given
+/// sub-object.
+bool SpecialMemberDeletionInfo::isAccessible(Subobject Subobj,
+ CXXMethodDecl *target) {
+ /// If we're operating on a base class, the object type is the
+ /// type of this special member.
+ QualType objectTy;
+ AccessSpecifier access = target->getAccess();;
+ if (CXXBaseSpecifier *base = Subobj.dyn_cast<CXXBaseSpecifier*>()) {
+ objectTy = S.Context.getTypeDeclType(MD->getParent());
+ access = CXXRecordDecl::MergeAccess(base->getAccessSpecifier(), access);
+
+ // If we're operating on a field, the object type is the type of the field.
+ } else {
+ objectTy = S.Context.getTypeDeclType(target->getParent());
+ }
+
+ return S.isSpecialMemberAccessibleForDeletion(target, access, objectTy);
+}
+
/// Check whether we should delete a special member due to the implicit
/// definition containing a call to a special member of a subobject.
bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
@@ -4414,8 +4436,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
DiagKind = !Decl ? 0 : 1;
else if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
DiagKind = 2;
- else if (S.CheckDirectMemberAccess(Loc, Decl, S.PDiag())
- != Sema::AR_accessible)
+ else if (!isAccessible(Subobj, Decl))
DiagKind = 3;
else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() &&
!Decl->isTrivial()) {