diff options
author | Nico Weber <nicolasweber@gmx.de> | 2016-01-15 21:45:31 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2016-01-15 21:45:31 +0000 |
commit | 5a9259caa9b78d098ace55703db69beadacdfcce (patch) | |
tree | 55224854401d1238e30fba380483c43ed9a63ee5 /clang/lib/Sema/SemaOverload.cpp | |
parent | 851da71c8fec4ab7d5a3461d486ddbf83fcc91ec (diff) | |
download | bcm5719-llvm-5a9259caa9b78d098ace55703db69beadacdfcce.tar.gz bcm5719-llvm-5a9259caa9b78d098ace55703db69beadacdfcce.zip |
Make -Wdelete-non-virtual-dtor warn on explicit `a->~A()` dtor calls too.
-Wdelete-non-virtual-dtor warns if A is a type with virtual functions but
without virtual dtor has its constructor called via `delete a`. This makes the
warning also fire if the dtor is called via `a->~A()`. This would've found a
security bug in Chromium at compile time. Fixes PR26137.
To fix the warning, add a virtual destructor, make the class final, or remove
its other virtual methods. If you want to silence the warning, there's also
a fixit that shows how:
test.cc:12:3: warning: destructor called on 'B' ... [-Wdelete-non-virtual-dtor]
b->~B();
^
test.cc:12:6: note: qualify call to silence this warning
b->~B();
^
B::
http://reviews.llvm.org/D16206
llvm-svn: 257939
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index d6a0ff7dc3d..c9293fa4c82 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -12236,6 +12236,17 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, << MD->getDeclName(); } } + + if (CXXDestructorDecl *DD = + dyn_cast<CXXDestructorDecl>(TheCall->getMethodDecl())) { + // a->A::f() doesn't go through the vtable, except in AppleKext mode. + bool CallCanBeVirtual = !cast<MemberExpr>(NakedMemExpr)->hasQualifier() || + getLangOpts().AppleKext; + CheckVirtualDtorCall(DD, MemExpr->getLocStart(), /*IsDelete=*/false, + CallCanBeVirtual, /*WarnOnNonAbstractTypes=*/true, + MemExpr->getMemberLoc()); + } + return MaybeBindToTemporary(TheCall); } |