Suppress -Wdelete-non-virtual-dtor warnings about classes defined in system headers.

r312167 made it so that we emit Wdelete-non-virtual-dtor from delete statements
that are in system headers (e.g. std::unique_ptr). That works great on Linux
and macOS, but on Windows there are non-final classes that are defined in
system headers that have virtual methods but non-virtual destructors and yet
get deleted through a base class pointer (e.g. ATL::CAccessToken::CRevert). So
paddle back a bit and don't emit the warning if it's about a class defined in a
system header.

https://reviews.llvm.org/D37324

llvm-svn: 312216
This commit is contained in:
Nico Weber 2017-08-31 06:17:08 +00:00
parent a22742be5a
commit bf2260ca62
2 changed files with 17 additions and 0 deletions

View File

@ -3299,6 +3299,12 @@ void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc,
if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr<FinalAttr>()) if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr<FinalAttr>())
return; return;
// If the superclass is in a system header, there's nothing that can be done.
// The `delete` (where we emit the warning) can be in a system header,
// what matters for this warning is where the deleted type is defined.
if (getSourceManager().isInSystemHeader(PointeeRD->getLocation()))
return;
QualType ClassType = dtor->getThisType(Context)->getPointeeType(); QualType ClassType = dtor->getThisType(Context)->getPointeeType();
if (PointeeRD->isAbstract()) { if (PointeeRD->isAbstract()) {
// If the class is abstract, we warn by default, because we're // If the class is abstract, we warn by default, because we're

View File

@ -8,6 +8,11 @@
#pragma clang system_header #pragma clang system_header
namespace dnvd { namespace dnvd {
struct SystemB {
virtual void foo();
};
template <typename T> template <typename T>
class simple_ptr { class simple_ptr {
public: public:
@ -249,6 +254,7 @@ private:
}; };
void use(B&); void use(B&);
void use(SystemB&);
void use(VB&); void use(VB&);
void nowarnstack() { void nowarnstack() {
@ -399,6 +405,11 @@ void nowarn1() {
simple_ptr<VF> vf(new VF()); simple_ptr<VF> vf(new VF());
use(*vf); use(*vf);
} }
{
simple_ptr<SystemB> sb(new SystemB());
use(*sb);
}
} }
void warn1() { void warn1() {