[analyzer] Handle NTTP invocation in CallContext.getCalleeDecl()

This fixes a crash in MallocChecker for the situation when operator new (delete) is invoked via NTTP  and makes the behavior of CallContext.getCalleeDecl(Expr) identical to CallEvent.getDecl().

Reviewed By: vsavchenko

Differential Revision: https://reviews.llvm.org/D103025
This commit is contained in:
Tomasz Kamiński 2021-06-18 14:20:17 +03:00 committed by Valeriy Savchenko
parent fd569a11b5
commit cc2ef19556
2 changed files with 37 additions and 0 deletions

View File

@ -19,6 +19,10 @@ using namespace clang;
using namespace ento;
const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const {
const FunctionDecl *D = CE->getDirectCallee();
if (D)
return D;
const Expr *Callee = CE->getCallee();
SVal L = Pred->getSVal(Callee);
return L.getAsFunctionDecl();

View File

@ -421,3 +421,36 @@ void shouldNotReportLeak() {
Derived *p = (Derived *)allocate();
delete p;
}
template<void *allocate_fn(size_t)>
void* allocate_via_nttp(size_t n) {
return allocate_fn(n);
}
template<void deallocate_fn(void*)>
void deallocate_via_nttp(void* ptr) {
deallocate_fn(ptr);
}
void testNTTPNewNTTPDelete() {
void* p = allocate_via_nttp<::operator new>(10);
deallocate_via_nttp<::operator delete>(p);
} // no warn
void testNTTPNewDirectDelete() {
void* p = allocate_via_nttp<::operator new>(10);
::operator delete(p);
} // no warn
void testDirectNewNTTPDelete() {
void* p = ::operator new(10);
deallocate_via_nttp<::operator delete>(p);
}
void not_free(void*) {
}
void testLeakBecauseNTTPIsNotDeallocation() {
void* p = ::operator new(10);
deallocate_via_nttp<not_free>(p);
} // leak-warning{{Potential leak of memory pointed to by 'p'}}