Perform access control for the implicit base and member destructor calls
required when emitting a destructor definition.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98609 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index c5b719b..2675734 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -300,60 +300,38 @@
/// \brief The set of static functions seen so far that have not been used.
std::vector<FunctionDecl*> UnusedStaticFuncs;
- /// An enum describing the kind of diagnostics to use when checking
- /// access.
- enum AccessDiagnosticsKind {
- /// Suppress diagnostics.
- ADK_quiet,
-
- /// Use the normal diagnostics.
- ADK_normal,
-
- /// Use the diagnostics appropriate for checking a covariant
- /// return type.
- ADK_covariance
- };
-
class AccessedEntity {
public:
- enum Kind {
- /// A member declaration found through lookup. The target is the
- /// member.
- Member,
+ /// A member declaration found through lookup. The target is the
+ /// member.
+ enum MemberNonce { Member };
- /// A base-to-derived conversion. The target is the base class.
- BaseToDerivedConversion,
+ /// A hierarchy (base-to-derived or derived-to-base) conversion.
+ /// The target is the base class.
+ enum BaseNonce { Base };
- /// A derived-to-base conversion. The target is the base class.
- DerivedToBaseConversion
- };
+ bool isMemberAccess() const { return IsMember; }
- bool isMemberAccess() const { return K == Member; }
-
- static AccessedEntity makeMember(CXXRecordDecl *NamingClass,
- AccessSpecifier Access,
- NamedDecl *Target) {
- AccessedEntity E;
- E.K = Member;
- E.Access = Access;
- E.Target = Target;
- E.NamingClass = NamingClass;
- return E;
+ AccessedEntity(MemberNonce _,
+ CXXRecordDecl *NamingClass,
+ AccessSpecifier Access,
+ NamedDecl *Target)
+ : Access(Access), IsMember(true),
+ Target(Target), NamingClass(NamingClass),
+ Diag(0) {
}
- static AccessedEntity makeBaseClass(bool BaseToDerived,
- CXXRecordDecl *BaseClass,
- CXXRecordDecl *DerivedClass,
- AccessSpecifier Access) {
- AccessedEntity E;
- E.K = BaseToDerived ? BaseToDerivedConversion : DerivedToBaseConversion;
- E.Access = Access;
- E.Target = BaseClass;
- E.NamingClass = DerivedClass;
- return E;
+ AccessedEntity(BaseNonce _,
+ CXXRecordDecl *BaseClass,
+ CXXRecordDecl *DerivedClass,
+ AccessSpecifier Access)
+ : Access(Access), IsMember(false),
+ Target(BaseClass), NamingClass(DerivedClass),
+ Diag(0) {
}
- Kind getKind() const { return Kind(K); }
+ bool isQuiet() const { return Diag.getDiagID() == 0; }
+
AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
// These apply to member decls...
@@ -364,11 +342,32 @@
CXXRecordDecl *getBaseClass() const { return cast<CXXRecordDecl>(Target); }
CXXRecordDecl *getDerivedClass() const { return NamingClass; }
+ /// Sets a diagnostic to be performed. The diagnostic is given
+ /// four (additional) arguments:
+ /// %0 - 0 if the entity was private, 1 if protected
+ /// %1 - the DeclarationName of the entity
+ /// %2 - the TypeDecl type of the naming class
+ /// %3 - the TypeDecl type of the declaring class
+ void setDiag(const PartialDiagnostic &PDiag) {
+ assert(isQuiet() && "partial diagnostic already defined");
+ Diag = PDiag;
+ }
+ PartialDiagnostic &setDiag(unsigned DiagID) {
+ assert(isQuiet() && "partial diagnostic already defined");
+ assert(DiagID && "creating null diagnostic");
+ Diag = PartialDiagnostic(DiagID);
+ return Diag;
+ }
+ const PartialDiagnostic &getDiag() const {
+ return Diag;
+ }
+
private:
- unsigned K : 2;
unsigned Access : 2;
+ bool IsMember;
NamedDecl *Target;
CXXRecordDecl *NamingClass;
+ PartialDiagnostic Diag;
};
struct DelayedDiagnostic {
@@ -384,9 +383,16 @@
struct { NamedDecl *Decl; } DeprecationData;
/// Access control.
- AccessedEntity AccessData;
+ char AccessData[sizeof(AccessedEntity)];
};
+ void destroy() {
+ switch (Kind) {
+ case Access: getAccessData().~AccessedEntity(); break;
+ case Deprecation: break;
+ }
+ }
+
static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
NamedDecl *D) {
DelayedDiagnostic DD;
@@ -403,10 +409,16 @@
DD.Kind = Access;
DD.Triggered = false;
DD.Loc = Loc;
- DD.AccessData = Entity;
+ new (&DD.getAccessData()) AccessedEntity(Entity);
return DD;
}
+ AccessedEntity &getAccessData() {
+ return *reinterpret_cast<AccessedEntity*>(AccessData);
+ }
+ const AccessedEntity &getAccessData() const {
+ return *reinterpret_cast<const AccessedEntity*>(AccessData);
+ }
};
/// \brief The stack of diagnostics that were delayed due to being
@@ -2566,7 +2578,7 @@
SourceLocation Loc, SourceRange Range,
bool IgnoreAccess = false);
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
- AccessDiagnosticsKind ADK,
+ unsigned InaccessibleBaseID,
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name);
@@ -2614,18 +2626,19 @@
CXXConstructorDecl *D,
AccessSpecifier Access);
AccessResult CheckDestructorAccess(SourceLocation Loc,
- const RecordType *Record);
+ CXXDestructorDecl *Dtor,
+ const PartialDiagnostic &PDiag);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
Expr *ObjectExpr,
+ Expr *ArgExpr,
NamedDecl *D,
AccessSpecifier Access);
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
- bool IsBaseToDerived,
QualType Base, QualType Derived,
const CXXBasePath &Path,
+ unsigned DiagID,
bool ForceCheck = false,
- bool ForceUnprivileged = false,
- AccessDiagnosticsKind ADK = ADK_normal);
+ bool ForceUnprivileged = false);
void CheckLookupAccess(const LookupResult &R);