diff options
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 13 | ||||
-rw-r--r-- | test/Analysis/dtor.cpp | 25 |
2 files changed, 33 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 62c288dad4..4431c03d49 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -286,10 +286,15 @@ bool ExprEngine::inlineCall(const CallEvent &Call, // These are always at least possible to inline. break; case CE_CXXConstructor: - case CE_CXXDestructor: - // Do not inline constructors until we can really model destructors. - // This is unfortunate, but basically necessary for smart pointers and such. - return false; + case CE_CXXDestructor: { + // Only inline constructors and destructors if we built the CFGs for them + // properly. + const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext(); + if (!ADC->getCFGBuildOptions().AddImplicitDtors || + !ADC->getCFGBuildOptions().AddInitializers) + return false; + break; + } case CE_CXXAllocator: // Do not inline allocators until we model deallocators. // This is unfortunate, but basically necessary for smart pointers and such. diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp index 8d63cc47be..5a14f3025d 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -cfg-add-initializers -verify %s class A { public: @@ -11,3 +11,26 @@ public: int main() { A a; } + + +typedef __typeof(sizeof(int)) size_t; +void *malloc(size_t); +void free(void *); + +class SmartPointer { + void *X; +public: + SmartPointer(void *x) : X(x) {} + ~SmartPointer() { + free(X); + } +}; + +void testSmartPointer() { + char *mem = (char*)malloc(4); + { + SmartPointer Deleter(mem); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} |