]> granicus.if.org Git - clang/commitdiff
Suppress -Wdelete-non-virtual-dtor warnings about classes defined in system headers.
authorNico Weber <nicolasweber@gmx.de>
Thu, 31 Aug 2017 06:17:08 +0000 (06:17 +0000)
committerNico Weber <nicolasweber@gmx.de>
Thu, 31 Aug 2017 06:17:08 +0000 (06:17 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@312216 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
test/SemaCXX/destructor.cpp

index 8de3d33d085e7904000355e1a86a63fdc83ab0a9..08c4f50091f7ec8495f1750926a427122755e358 100644 (file)
@@ -3299,6 +3299,12 @@ void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc,
   if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr<FinalAttr>())
     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();
   if (PointeeRD->isAbstract()) {
     // If the class is abstract, we warn by default, because we're
index 31ee60a718adc42b4e6924ef363051d214d140e0..69d44f5c8ae4d7619723cf03c103f463971543f2 100644 (file)
@@ -8,6 +8,11 @@
 
 #pragma clang system_header
 namespace dnvd {
+
+struct SystemB {
+  virtual void foo();
+};
+
 template <typename T>
 class simple_ptr {
 public:
@@ -249,6 +254,7 @@ private:
 };
 
 void use(B&);
+void use(SystemB&);
 void use(VB&);
 
 void nowarnstack() {
@@ -399,6 +405,11 @@ void nowarn1() {
     simple_ptr<VF> vf(new VF());
     use(*vf);
   }
+  {
+    simple_ptr<SystemB> sb(new SystemB());
+    use(*sb);
+  }
+
 }
 
 void warn1() {