Make sure CheckDestructor gets called on dllimported classes if the vtable is used (PR27319)

llvm-svn: 266242
This commit is contained in:
Hans Wennborg 2016-04-13 20:21:15 +00:00
parent 236e7444dd
commit 3480435fa8
2 changed files with 25 additions and 7 deletions

View File

@ -13314,13 +13314,20 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
// the deleting destructor is emitted with the vtable, not with the
// destructor definition as in the Itanium ABI.
// If it has a definition, we do the check at that point instead.
if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
Class->hasUserDeclaredDestructor() &&
!Class->getDestructor()->isDefined() &&
!Class->getDestructor()->isDeleted()) {
CXXDestructorDecl *DD = Class->getDestructor();
ContextRAII SavedContext(*this, DD);
CheckDestructor(DD);
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
if (Class->hasUserDeclaredDestructor() &&
!Class->getDestructor()->isDefined() &&
!Class->getDestructor()->isDeleted()) {
CXXDestructorDecl *DD = Class->getDestructor();
ContextRAII SavedContext(*this, DD);
CheckDestructor(DD);
} else if (Class->hasAttr<DLLImportAttr>()) {
// We always synthesize vtables on the import side. To make sure
// CheckDestructor gets called, mark the destructor referenced.
assert(Class->getDestructor() &&
"The destructor has always been declared on a dllimport class");
MarkFunctionReferenced(Loc, Class->getDestructor());
}
}
}

View File

@ -743,6 +743,17 @@ namespace PR21366 {
inline void S::outOfClassInlineMethod() {}
}
namespace PR27319 {
// Make sure we don't assert due to not having checked for operator delete on
// the destructor.
template <typename> struct A {
virtual ~A() = default;
};
extern template struct __declspec(dllimport) A<int>;
void f() { new A<int>(); }
// MO1-DAG: @"\01??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*]
}
// MS ignores DLL attributes on partial specializations.
template <typename T> struct PartiallySpecializedClassTemplate {};
template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };