aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-15 19:11:43 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-15 19:11:43 +0000
commit63bc186d6ac0b44ba4ec6fccb5f471b05c79b666 (patch)
tree9002c9a95686003fd8a0ed2875fe5b114d4c4bde
parentf34a5791c5c9df0348714e275adb09b8cf858460 (diff)
[analyzer] Report leaks at the closing brace of a function body.
This fixes a few cases where we'd emit path notes like this: +---+ 1| v p = malloc(len); ^ |2 +---+ In general this should make path notes more consistent and more correct, especially in cases where the leak happens on the false branch of an if that jumps directly to the end of the function. There are a couple places where the leak is reported farther away from the cause; these are usually cases where there are several levels of nested braces before the end of the function. This still matches our current behavior for when there /is/ a statement after all the braces, though. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168070 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp22
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp12
-rw-r--r--test/Analysis/coverage.c24
-rw-r--r--test/Analysis/keychainAPI.m4
-rw-r--r--test/Analysis/malloc-annotations.c8
-rw-r--r--test/Analysis/malloc-interprocedural.c20
-rw-r--r--test/Analysis/malloc-plist.c150
-rw-r--r--test/Analysis/malloc.c59
-rw-r--r--test/Analysis/malloc.cpp4
-rw-r--r--test/Analysis/plist-output-alternate.m67
-rw-r--r--test/Analysis/retain-release.m4
-rw-r--r--test/Analysis/simple-stream-checks.c4
-rw-r--r--test/Analysis/stackaddrleak.c12
14 files changed, 180 insertions, 213 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index c6689f8536..5c14eaf284 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1673,6 +1673,9 @@ PathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const {
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
return PathDiagnosticLocation::createOperatorLoc(B, SM);
+ if (isa<PostStmtPurgeDeadSymbols>(ErrorNode->getLocation()))
+ return PathDiagnosticLocation::createEnd(S, SM, LC);
+
return PathDiagnosticLocation::createBegin(S, SM, LC);
}
} else {
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index a98e8b4922..426d48dae2 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -177,14 +177,15 @@ void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC,
return;
}
- // Here, we call the Symbol Reaper with 0 stack context telling it to clean up
- // everything on the stack. We use LastStmt as a diagnostic statement, with
- // which the program point will be associated. However, we only want to use
- // LastStmt as a reference for what to clean up if it's a ReturnStmt;
- // otherwise, everything is dead.
+ // Here, we destroy the current location context. We use the current
+ // function's entire body as a diagnostic statement, with which the program
+ // point will be associated. However, we only want to use LastStmt as a
+ // reference for what to clean up if it's a ReturnStmt; otherwise, everything
+ // is dead.
SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
- removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt),
- Pred->getLocationContext(), LastSt,
+ const LocationContext *LCtx = Pred->getLocationContext();
+ removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
+ LCtx->getAnalysisDeclContext()->getBody(),
ProgramPoint::PostStmtPurgeDeadSymbolsKind);
}
@@ -289,9 +290,10 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
currBldrCtx = &Ctx;
// Here, we call the Symbol Reaper with 0 statement and callee location
// context, telling it to clean up everything in the callee's context
- // (and its children). We use LastSt as a diagnostic statement, which
- // which the program point will be associated.
- removeDead(BindedRetNode, CleanedNodes, 0, calleeCtx, LastSt,
+ // (and its children). We use the callee's function body as a diagnostic
+ // statement, with which the program point will be associated.
+ removeDead(BindedRetNode, CleanedNodes, 0, calleeCtx,
+ calleeCtx->getAnalysisDeclContext()->getBody(),
ProgramPoint::PostStmtPurgeDeadSymbolsKind);
currBldrCtx = 0;
} else {
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 2ebadcaa23..cfe35251a9 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -588,6 +588,8 @@ PathDiagnosticLocation
}
else if (const StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
S = SP->getStmt();
+ if (isa<PostStmtPurgeDeadSymbols>(P))
+ return PathDiagnosticLocation::createEnd(S, SMng, P.getLocationContext());
}
else if (const PostImplicitCall *PIE = dyn_cast<PostImplicitCall>(&P)) {
return PathDiagnosticLocation(PIE->getLocation(), SMng);
@@ -619,12 +621,16 @@ PathDiagnosticLocation
while (NI) {
ProgramPoint P = NI->getLocation();
- if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P))
+ if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P)) {
S = PS->getStmt();
- else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+ if (isa<PostStmtPurgeDeadSymbols>(P))
+ return PathDiagnosticLocation::createEnd(S, SM,
+ NI->getLocationContext());
+ break;
+ } else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
S = BE->getSrc()->getTerminator();
- if (S)
break;
+ }
NI = NI->succ_empty() ? 0 : *(NI->succ_begin());
}
diff --git a/test/Analysis/coverage.c b/test/Analysis/coverage.c
index 66f0a5e385..38e84e17ce 100644
--- a/test/Analysis/coverage.c
+++ b/test/Analysis/coverage.c
@@ -32,27 +32,27 @@ static void function_which_doesnt_give_up_nested(int *x, int *y) {
void coverage1(int *x) {
function_which_gives_up(x);
- char *m = (char*)malloc(12); // expected-warning {{potential leak}}
-}
+ char *m = (char*)malloc(12);
+} // expected-warning {{potential leak}}
void coverage2(int *x) {
if (x) {
function_which_gives_up(x);
- char *m = (char*)malloc(12);// expected-warning {{potential leak}}
+ char *m = (char*)malloc(12);
}
-}
+} // expected-warning {{potential leak}}
void coverage3(int *x) {
x++;
function_which_gives_up(x);
- char *m = (char*)malloc(12);// expected-warning {{potential leak}}
-}
+ char *m = (char*)malloc(12);
+} // expected-warning {{potential leak}}
void coverage4(int *x) {
*x += another_function(x);
function_which_gives_up(x);
- char *m = (char*)malloc(12);// expected-warning {{potential leak}}
-}
+ char *m = (char*)malloc(12);
+} // expected-warning {{potential leak}}
void coverage5(int *x) {
for (int i = 0; i<7; ++i)
@@ -65,8 +65,8 @@ void coverage6(int *x) {
for (int i = 0; i<3; ++i) {
function_which_gives_up(x);
}
- char *m = (char*)malloc(12); // expected-warning {{potential leak}}
-}
+ char *m = (char*)malloc(12);
+} // expected-warning {{potential leak}}
int coverage7_inline(int *i) {
function_which_doesnt_give_up(&i);
@@ -77,8 +77,8 @@ void coverage8(int *x) {
int y;
function_which_doesnt_give_up_nested(x, &y);
y = (*x)/y; // expected-warning {{Division by zero}}
- char *m = (char*)malloc(12); // expected-warning {{potential leak}}
-}
+ char *m = (char*)malloc(12);
+} // expected-warning {{potential leak}}
void function_which_gives_up_settonull(int **x) {
*x = 0;
diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m
index fe6c61d1e8..6eca8003d9 100644
--- a/test/Analysis/keychainAPI.m
+++ b/test/Analysis/keychainAPI.m
@@ -76,9 +76,9 @@ void errRetVal() {
UInt32 length;
void *outData;
st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
- if (st == GenericError) // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
+ if (st == GenericError)
SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}}
-}
+} // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
// If null is passed in, the data is not allocated, so no need for the matching free.
void fooDoNotReportNull() {
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index 2a078b6f82..3a260c3aef 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -63,8 +63,8 @@ void af1() {
}
void af1_b() {
- int *p = my_malloc(12); // expected-warning{{Memory is never released; potential leak}}
-}
+ int *p = my_malloc(12);
+} // expected-warning{{Memory is never released; potential leak}}
void af1_c() {
myglobalpointer = my_malloc(12); // no-warning
@@ -72,8 +72,8 @@ void af1_c() {
void af1_d() {
struct stuff mystuff;
- mystuff.somefield = my_malloc(12); // expected-warning{{Memory is never released; potential leak}}
-}
+ mystuff.somefield = my_malloc(12);
+} // expected-warning{{Memory is never released; potential leak}}
// Test that we can pass out allocated memory via pointer-to-pointer.
void af1_e(void **pp) {
diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c
index 79cbf247dd..3c7bab6717 100644
--- a/test/Analysis/malloc-interprocedural.c
+++ b/test/Analysis/malloc-interprocedural.c
@@ -31,8 +31,8 @@ static void my_free1(void *p) {
static void test1() {
void *data = 0;
- my_malloc1(&data, 4); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
-}
+ my_malloc1(&data, 4);
+} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
static void test11() {
void *data = 0;
@@ -44,8 +44,8 @@ static void testUniqueingByallocationSiteInTopLevelFunction() {
void *data = my_malloc2(1, 4);
data = 0;
int x = 5;// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
- data = my_malloc2(1, 4);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
-}
+ data = my_malloc2(1, 4);
+} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
static void test3() {
void *data = my_malloc2(1, 4);
@@ -122,10 +122,14 @@ char *strndup(const char *str, size_t n) {
}
void useStrndup(size_t n) {
- if (n == 0)
+ if (n == 0) {
(void)strndup(0, 20); // no-warning
- else if (n < 5)
+ return;
+ } else if (n < 5) {
(void)strndup("hi there", n); // no-warning
- else
- (void)strndup("hi there", n); // expected-warning{{leak}}
+ return;
+ } else {
+ (void)strndup("hi there", n);
+ return; // expected-warning{{leak}}
+ }
}
diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c
index a99e34f426..b9ba45c2e1 100644
--- a/test/Analysis/malloc-plist.c
+++ b/test/Analysis/malloc-plist.c
@@ -517,13 +517,13 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -534,8 +534,8 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
@@ -550,11 +550,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>myArrayAllocation</string>
-// CHECK-NEXT: <key>issue_hash</key><integer>3</integer>
+// CHECK-NEXT: <key>issue_hash</key><integer>4</integer>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>21</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -1301,13 +1301,13 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>45</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>45</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -1318,8 +1318,8 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>45</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
@@ -1334,11 +1334,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>test_wrapper</string>
-// CHECK-NEXT: <key>issue_hash</key><integer>2</integer>
+// CHECK-NEXT: <key>issue_hash</key><integer>3</integer>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>45</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -2636,40 +2636,6 @@ void use_function_with_leak7() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>26</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2682,13 +2648,13 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -2699,8 +2665,8 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
@@ -2715,11 +2681,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>use_ret</string>
-// CHECK-NEXT: <key>issue_hash</key><integer>2</integer>
+// CHECK-NEXT: <key>issue_hash</key><integer>3</integer>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -3049,13 +3015,13 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>104</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>line</key><integer>104</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -3066,8 +3032,8 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>104</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
@@ -3082,11 +3048,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak1</string>
-// CHECK-NEXT: <key>issue_hash</key><integer>1</integer>
+// CHECK-NEXT: <key>issue_hash</key><integer>2</integer>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>103</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>104</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
@@ -4482,11 +4448,45 @@ void use_function_with_leak7() {
// CHECK-NEXT: <string>Returned allocated memory</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>169</integer>
+// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>169</integer>
+// CHECK-NEXT: <key>col</key><integer>23</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>169</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
@@ -4501,11 +4501,11 @@ void use_function_with_leak7() {
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>use_function_with_leak7</string>
-// CHECK-NEXT: <key>issue_hash</key><integer>1</integer>
+// CHECK-NEXT: <key>issue_hash</key><integer>2</integer>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>169</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 76dd3a8fda..03fc38a73f 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -102,8 +102,8 @@ void reallocSizeZero5() {
}
void reallocPtrZero1() {
- char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}}
-}
+ char *r = realloc(0, 12);
+} // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}}
void reallocPtrZero2() {
char *r = realloc(0, 12);
@@ -128,12 +128,12 @@ void reallocRadar6337483_1() {
void reallocRadar6337483_2() {
char *buf = malloc(100);
char *buf2 = (char*)realloc(buf, 0x1000000);
- if (!buf2) { // expected-warning {{Memory is never released; potential leak}}
+ if (!buf2) {
;
} else {
free(buf2);
}
-}
+} // expected-warning {{Memory is never released; potential leak}}
void reallocRadar6337483_3() {
char * buf = malloc(100);
@@ -186,8 +186,8 @@ void reallocfRadar6337483_3() {
}
void reallocfPtrZero1() {
- char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential leak}}
-}
+ char *r = reallocf(0, 12);
+} // expected-warning {{Memory is never released; potential leak}}
// This case tests that storing malloc'ed memory to a static variable which is
@@ -384,13 +384,13 @@ void mallocBindFreeUse() {
void mallocEscapeMalloc() {
int *p = malloc(12);
myfoo(p);
- p = malloc(12); // expected-warning{{Memory is never released; potential leak}}
-}
+ p = malloc(12);
+} // expected-warning{{Memory is never released; potential leak}}
void mallocMalloc() {
int *p = malloc(12);
- p = malloc(12); // expected-warning {{Memory is never released; potential leak}}
-}
+ p = malloc(12);
+} // expected-warning {{Memory is never released; potential leak}}
void mallocFreeMalloc() {
int *p = malloc(12);
@@ -454,8 +454,8 @@ void mallocFailedOrNotLeak() {
void mallocAssignment() {
char *p = malloc(12);
- p = fooRetPtr(); // expected-warning {{leak}}
-}
+ p = fooRetPtr();
+} // expected-warning {{leak}}
int vallocTest() {
char *mem = valloc(12);
@@ -624,8 +624,8 @@ void mallocAssert(int *g) {
void doNotInvalidateWhenPassedToSystemCalls(char *s) {
char *p = malloc(12);
strlen(p);
- strcpy(p, s); // expected-warning {{leak}}
-}
+ strcpy(p, s);
+} // expected-warning {{leak}}
// Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p.
void symbolLostWithStrcpy(char *s) {
@@ -671,8 +671,8 @@ int *specialMallocWithStruct() {
// Test various allocation/deallocation functions.
void testStrdup(const char *s, unsigned validIndex) {
char *s2 = strdup(s);
- s2[validIndex + 1] = 'b';// expected-warning {{Memory is never released; potential leak}}
-}
+ s2[validIndex + 1] = 'b';
+} // expected-warning {{Memory is never released; potential leak}}
int testStrndup(const char *s, unsigned validIndex, unsigned size) {
char *s2 = strndup(s, size);
@@ -780,10 +780,11 @@ void radar10978247_positive(int myValueSize) {
buffer = malloc(myValueSize);
// do stuff with the buffer
- if (buffer == stackBuffer) // expected-warning {{leak}}
+ if (buffer == stackBuffer)
return;
-}
-
+ else
+ return; // expected-warning {{leak}}
+}
// <rdar://problem/11269741> Previously this triggered a false positive
// because malloc() is known to return uninitialized memory and the binding
// of 'o' to 'p->n' was not getting propertly handled. Now we report a leak.
@@ -819,8 +820,8 @@ void radar11270219(void) {
void radar_11358224_test_double_assign_ints_positive_2()
{
void *ptr = malloc(16);
- ptr = ptr; // expected-warning {{leak}}
-}
+ ptr = ptr;
+} // expected-warning {{leak}}
// Assume that functions which take a function pointer can free memory even if
// they are defined in system headers and take the const pointer to the
@@ -834,8 +835,8 @@ void r11160612_1() {
// Null is passed as callback.
void r11160612_2() {
char *x = malloc(12);
- const_ptr_and_callback(0, x, 12, 0); // expected-warning {{leak}}
-}
+ const_ptr_and_callback(0, x, 12, 0);
+} // expected-warning {{leak}}
// Callback is passed to a function defined in a system header.
void r11160612_4() {
@@ -935,14 +936,14 @@ int cmpHeapAllocationToUnknown() {
void localArrayTest() {
char *p = (char*)malloc(12);
char *ArrayL[12];
- ArrayL[0] = p; // expected-warning {{leak}}
-}
+ ArrayL[0] = p;
+} // expected-warning {{leak}}
void localStructTest() {
StructWithPtr St;
StructWithPtr *pSt = &St;
- pSt->memP = malloc(12); // expected-warning{{Memory is never released; potential leak}}
-}
+ pSt->memP = malloc(12);
+} // expected-warning{{Memory is never released; potential leak}}
// Test double assignment through integers.
static long glob;
@@ -955,8 +956,8 @@ void test_double_assign_ints()
void test_double_assign_ints_positive()
{
void *ptr = malloc(16);
- (void*)(long)(unsigned long)ptr; // expected-warning {{unused}} expected-warning {{leak}}
-}
+ (void*)(long)(unsigned long)ptr; // expected-warning {{unused}}
+} // expected-warning {{leak}}
void testCGContextNoLeak()
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index 220d74625b..58b94ea774 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -8,8 +8,8 @@ void *calloc(size_t nmemb, size_t size);
void checkThatMallocCheckerIsRunning() {
- malloc(4); // expected-warning{{leak}}
-}
+ malloc(4);
+} // expected-warning{{leak}}
// Test for radar://11110132.
struct Foo {
diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m
index 7bb81bed1c..423574d781 100644
--- a/test/Analysis/plist-output-alternate.m
+++ b/test/Analysis/plist-output-alternate.m
@@ -1199,40 +1199,6 @@ void rdar8331641(int x) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>57</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>57</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>