diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-28 20:52:13 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-28 20:52:13 +0000 |
commit | 632e5022f68fcae3b68bbc90538a60f3ba20229f (patch) | |
tree | 0a43cdf55be32401809988403ae64382e56240d2 /test | |
parent | 82778af78a7337498e6bcfc81c75cee29d329915 (diff) |
[analyzer] When we look for the last stmt in a function, skip implicit dtors.
When exiting a function, the analyzer looks for the last statement in the
function to see if it's a return statement (and thus bind the return value).
However, the search for "the last statement" was accepting statements that
were in implicitly-generated inlined functions (i.e. destructors). So we'd
go and get the statement from the destructor, and then say "oh look, this
function had no explicit return...guess there's no return value". And /that/
led to the value being returned being declared dead, and all our leak
checkers complaining.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162791 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/Analysis/dtor.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp index 1f45925561..d6f66c3845 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s void clang_analyzer_eval(bool); +void clang_analyzer_checkInlined(bool); class A { public: @@ -102,7 +103,7 @@ void testMultipleInheritance3() { // Remove dead bindings... doSomething(); // destructor called here - // expected-warning@27 {{Attempt to free released memory}} + // expected-warning@28 {{Attempt to free released memory}} } } @@ -227,3 +228,26 @@ namespace DestructorVirtualCalls { clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} } } + + +namespace DestructorsShouldNotAffectReturnValues { + class Dtor { + public: + ~Dtor() { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + } + }; + + void *allocate() { + Dtor d; + return malloc(4); // no-warning + } + + void test() { + // At one point we had an issue where the statements inside an + // inlined destructor kept us from finding the return statement, + // leading the analyzer to believe that the malloc'd memory had leaked. + void *p = allocate(); + free(p); // no-warning + } +} |