[cfe-commits] r98681 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/class.access/p4.cpp
John McCall
rjmccall at apple.com
Tue Mar 16 14:39:52 PDT 2010
Author: rjmccall
Date: Tue Mar 16 16:39:52 2010
New Revision: 98681
URL: http://llvm.org/viewvc/llvm-project?rev=98681&view=rev
Log:
Perform access control for the implicit calls to base and member destructors
that occur in constructors (on the unwind path).
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/class.access/p4.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=98681&r1=98680&r2=98681&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar 16 16:39:52 2010
@@ -2473,10 +2473,11 @@
bool IsImplicitConstructor,
bool AnyErrors);
- /// MarkBaseAndMemberDestructorsReferenced - Given a destructor decl,
- /// mark all its non-trivial member and base destructor declarations
- /// as referenced.
- void MarkBaseAndMemberDestructorsReferenced(CXXDestructorDecl *Destructor);
+ /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
+ /// mark all the non-trivial destructors of its members and bases as
+ /// referenced.
+ void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
+ CXXRecordDecl *Record);
/// ClassesWithUnmarkedVirtualMembers - Contains record decls whose virtual
/// members need to be marked as referenced at the end of the translation
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=98681&r1=98680&r2=98681&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 16 16:39:52 2010
@@ -4281,7 +4281,8 @@
DiagnoseInvalidJumps(Body);
if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
- MarkBaseAndMemberDestructorsReferenced(Destructor);
+ MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
+ Destructor->getParent());
// If any errors have occurred, clear out any temporaries that may have
// been leftover. This ensures that these temporaries won't be picked up for
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=98681&r1=98680&r2=98681&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 16 16:39:52 2010
@@ -1643,29 +1643,14 @@
Constructor->setNumBaseOrMemberInitializers(NumInitializers);
CXXBaseOrMemberInitializer **baseOrMemberInitializers =
new (Context) CXXBaseOrMemberInitializer*[NumInitializers];
-
+ memcpy(baseOrMemberInitializers, AllToInit.data(),
+ NumInitializers * sizeof(CXXBaseOrMemberInitializer*));
Constructor->setBaseOrMemberInitializers(baseOrMemberInitializers);
- for (unsigned Idx = 0; Idx < NumInitializers; ++Idx) {
- CXXBaseOrMemberInitializer *Member = AllToInit[Idx];
- baseOrMemberInitializers[Idx] = Member;
- if (!Member->isBaseInitializer())
- continue;
- const Type *BaseType = Member->getBaseClass();
- const RecordType *RT = BaseType->getAs<RecordType>();
- if (!RT)
- continue;
- CXXRecordDecl *BaseClassDecl =
- cast<CXXRecordDecl>(RT->getDecl());
-
- // We don't know if a dependent type will have an implicit destructor.
- if (BaseClassDecl->isDependentType())
- continue;
- if (BaseClassDecl->hasTrivialDestructor())
- continue;
- CXXDestructorDecl *DD = BaseClassDecl->getDestructor(Context);
- MarkDeclarationReferenced(Constructor->getLocation(), DD);
- }
+ // Constructors implicitly reference the base and member
+ // destructors.
+ MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(),
+ Constructor->getParent());
}
return HadError;
@@ -1848,9 +1833,10 @@
}
void
-Sema::MarkBaseAndMemberDestructorsReferenced(CXXDestructorDecl *Destructor) {
- // Ignore dependent destructors.
- if (Destructor->isDependentContext())
+Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
+ CXXRecordDecl *ClassDecl) {
+ // Ignore dependent contexts.
+ if (ClassDecl->isDependentContext())
return;
// FIXME: all the access-control diagnostics are positioned on the
@@ -1858,8 +1844,6 @@
// user might reasonably want to know why the destructor is being
// emitted, and we currently don't say.
- CXXRecordDecl *ClassDecl = Destructor->getParent();
-
// Non-static data members.
for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
E = ClassDecl->field_end(); I != E; ++I) {
@@ -1881,8 +1865,7 @@
<< Field->getDeclName()
<< FieldType);
- MarkDeclarationReferenced(Destructor->getLocation(),
- const_cast<CXXDestructorDecl*>(Dtor));
+ MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
}
llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
@@ -1910,8 +1893,7 @@
<< Base->getType()
<< Base->getSourceRange());
- MarkDeclarationReferenced(Destructor->getLocation(),
- const_cast<CXXDestructorDecl*>(Dtor));
+ MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
}
// Virtual bases.
@@ -1935,8 +1917,7 @@
PartialDiagnostic(diag::err_access_dtor_vbase)
<< VBase->getType());
- MarkDeclarationReferenced(Destructor->getLocation(),
- const_cast<CXXDestructorDecl*>(Dtor));
+ MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
}
}
@@ -3819,7 +3800,8 @@
DeclContext *PreviousContext = CurContext;
CurContext = Destructor;
- MarkBaseAndMemberDestructorsReferenced(Destructor);
+ MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
+ Destructor->getParent());
// FIXME: If CheckDestructor fails, we should emit a note about where the
// implicit destructor was needed.
Modified: cfe/trunk/test/CXX/class.access/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/p4.cpp?rev=98681&r1=98680&r2=98681&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/p4.cpp (original)
+++ cfe/trunk/test/CXX/class.access/p4.cpp Tue Mar 16 16:39:52 2010
@@ -112,9 +112,10 @@
A local; // expected-error {{variable of type 'test3::A' has private destructor}}
}
- template <unsigned N> class Base { ~Base(); }; // expected-note 8 {{declared private here}}
- class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 2 {{declared private here}}
- class Base3 : virtual Base<3> { public: ~Base3(); };
+ template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
+ class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
+ // expected-error {{base class 'Base<2>' has private destructor}}
+ class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}}
// These don't cause diagnostics because we don't need the destructor.
class Derived0 : Base<0> { ~Derived0(); };
@@ -130,11 +131,11 @@
~Derived2() {}
};
- class Derived3 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
- // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
- Base<0>, // expected-error {{base class 'Base<0>' has private destructor}}
- virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
- Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
+ class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \
+ // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}}
+ Base<0>, // expected-error 2 {{base class 'Base<0>' has private destructor}}
+ virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}}
+ Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}}
virtual Base3
{};
Derived3 d3;
More information about the cfe-commits
mailing list