llvm-capstone/clang/test/Analysis/NewDelete-custom.cpp
Artem Dergachev a396df3472 [analyzer] Enable c++-allocator-inlining by default.
This allows the analyzer to analyze ("inline") custom operator new() calls and,
even more importantly, inline constructors of objects that were allocated
by any operator new() - not necessarily a custom one.

All changes in the tests in the current commit are intended improvements,
even if they didn't carry any explicit FIXME flag.

It is possible to restore the old behavior via

  -analyzer-config c++-allocator-inlining=false

(this flag is supported by scan-build as well, and it can be into a clang
--analyze invocation via -Xclang .. -Xclang ..). There is no intention to
remove the old behavior for now.

Differential Revision: https://reviews.llvm.org/D42219
rdar://problem/12180598

llvm-svn: 323373
2018-01-24 20:59:40 +00:00

80 lines
2.4 KiB
C++

// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -analyzer-config c++-allocator-inlining=false -fblocks -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -analyzer-config c++-allocator-inlining=false -DLEAKS=1 -fblocks -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -DALLOCATOR_INLINING=1 -fblocks -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS=1 -DALLOCATOR_INLINING=1 -fblocks -verify %s
#include "Inputs/system-header-simulator-cxx.h"
#if !(LEAKS && !ALLOCATOR_INLINING)
// expected-no-diagnostics
#endif
void *allocator(std::size_t size);
void *operator new[](std::size_t size) throw() { return allocator(size); }
void *operator new(std::size_t size) throw() { return allocator(size); }
void *operator new(std::size_t size, const std::nothrow_t &nothrow) throw() { return allocator(size); }
void *operator new(std::size_t, double d);
class C {
public:
void *operator new(std::size_t);
};
void testNewMethod() {
void *p1 = C::operator new(0); // no warn
C *p2 = new C; // no warn
C *c3 = ::new C;
}
#if LEAKS && !ALLOCATOR_INLINING
// expected-warning@-2{{Potential leak of memory pointed to by 'c3'}}
#endif
void testOpNewArray() {
void *p = operator new[](0); // call is inlined, no warn
}
void testNewExprArray() {
int *p = new int[0];
}
#if LEAKS && !ALLOCATOR_INLINING
// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
#endif
//----- Custom non-placement operators
void testOpNew() {
void *p = operator new(0); // call is inlined, no warn
}
void testNewExpr() {
int *p = new int;
}
#if LEAKS && !ALLOCATOR_INLINING
// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
#endif
//----- Custom NoThrow placement operators
void testOpNewNoThrow() {
void *p = operator new(0, std::nothrow); // call is inlined, no warn
}
void testNewExprNoThrow() {
int *p = new(std::nothrow) int;
}
#if LEAKS && !ALLOCATOR_INLINING
// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
#endif
//----- Custom placement operators
void testOpNewPlacement() {
void *p = operator new(0, 0.1); // no warn
}
void testNewExprPlacement() {
int *p = new(0.1) int; // no warn
}