aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaAccess.cpp17
-rw-r--r--lib/Sema/SemaDeclCXX.cpp32
3 files changed, 48 insertions, 4 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2675734eca..4c258448da 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2628,6 +2628,9 @@ public:
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 818d369f74..f0a38d5970 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -495,6 +495,23 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
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 1b3612d1c7..c27b0d5013 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3862,8 +3862,14 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
= 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 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
= 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 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
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 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
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();