From 12d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6 Mon Sep 17 00:00:00 2001 From: John McCall Date: Mon, 9 Apr 2012 20:53:23 +0000 Subject: 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 --- lib/Sema/SemaDeclCXX.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'lib/Sema/SemaDeclCXX.cpp') 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()) { + 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()) { -- cgit v1.2.3