Access control for implicit calls to copy assignment operators and copy
constructors from implicitly-defined members.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98614 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2675734..4c25844 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2628,6 +2628,9 @@
AccessResult CheckDestructorAccess(SourceLocation Loc,
CXXDestructorDecl *Dtor,
const PartialDiagnostic &PDiag);
+ AccessResult CheckDirectMemberAccess(SourceLocation Loc,
+ NamedDecl *D,
+ const PartialDiagnostic &PDiag);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
Expr *ObjectExpr,
Expr *ArgExpr,
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index 818d369..f0a38d5 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -495,6 +495,23 @@
return CheckAccess(*this, UseLoc, Entity);
}
+/// Checks direct (i.e. non-inherited) access to an arbitrary class
+/// member.
+Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
+ NamedDecl *Target,
+ const PartialDiagnostic &Diag) {
+ AccessSpecifier Access = Target->getAccess();
+ if (!getLangOptions().AccessControl ||
+ Access == AS_public)
+ return AR_accessible;
+
+ CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext());
+ AccessedEntity Entity(AccessedEntity::Member, NamingClass, Access, Target);
+ Entity.setDiag(Diag);
+ return CheckAccess(*this, UseLoc, Entity);
+}
+
+
/// Checks access to an overloaded member operator, including
/// conversion operators.
Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 1b3612d..c27b0d5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3862,8 +3862,14 @@
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
if (CXXMethodDecl *BaseAssignOpMethod =
getAssignOperatorMethod(CurrentLocation, MethodDecl->getParamDecl(0),
- BaseClassDecl))
+ BaseClassDecl)) {
+ CheckDirectMemberAccess(Base->getSourceRange().getBegin(),
+ BaseAssignOpMethod,
+ PartialDiagnostic(diag::err_access_assign_base)
+ << Base->getType());
+
MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod);
+ }
}
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
E = ClassDecl->field_end(); Field != E; ++Field) {
@@ -3875,8 +3881,14 @@
= cast<CXXRecordDecl>(FieldClassType->getDecl());
if (CXXMethodDecl *FieldAssignOpMethod =
getAssignOperatorMethod(CurrentLocation, MethodDecl->getParamDecl(0),
- FieldClassDecl))
+ FieldClassDecl)) {
+ CheckDirectMemberAccess(Field->getLocation(),
+ FieldAssignOpMethod,
+ PartialDiagnostic(diag::err_access_assign_field)
+ << Field->getDeclName() << Field->getType());
+
MarkDeclarationReferenced(CurrentLocation, FieldAssignOpMethod);
+ }
} else if (FieldType->isReferenceType()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
<< Context.getTagDeclType(ClassDecl) << 0 << Field->getDeclName();
@@ -3951,8 +3963,14 @@
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
if (CXXConstructorDecl *BaseCopyCtor =
- BaseClassDecl->getCopyConstructor(Context, TypeQuals))
+ BaseClassDecl->getCopyConstructor(Context, TypeQuals)) {
+ CheckDirectMemberAccess(Base->getSourceRange().getBegin(),
+ BaseCopyCtor,
+ PartialDiagnostic(diag::err_access_copy_base)
+ << Base->getType());
+
MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor);
+ }
}
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
FieldEnd = ClassDecl->field_end();
@@ -3964,8 +3982,14 @@
CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
if (CXXConstructorDecl *FieldCopyCtor =
- FieldClassDecl->getCopyConstructor(Context, TypeQuals))
+ FieldClassDecl->getCopyConstructor(Context, TypeQuals)) {
+ CheckDirectMemberAccess(Field->getLocation(),
+ FieldCopyCtor,
+ PartialDiagnostic(diag::err_access_copy_field)
+ << Field->getDeclName() << Field->getType());
+
MarkDeclarationReferenced(CurrentLocation, FieldCopyCtor);
+ }
}
}
CopyConstructor->setUsed();