diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8de3d33d085e..08c4f50091f7 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3299,6 +3299,12 @@ void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr()) 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 diff --git a/clang/test/SemaCXX/destructor.cpp b/clang/test/SemaCXX/destructor.cpp index 31ee60a718ad..69d44f5c8ae4 100644 --- a/clang/test/SemaCXX/destructor.cpp +++ b/clang/test/SemaCXX/destructor.cpp @@ -8,6 +8,11 @@ #pragma clang system_header namespace dnvd { + +struct SystemB { + virtual void foo(); +}; + template 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(new VF()); use(*vf); } + { + simple_ptr sb(new SystemB()); + use(*sb); + } + } void warn1() {