]> granicus.if.org Git - clang/commitdiff
[analyzer] Report leaks at the closing brace of a function body.
authorJordan Rose <jordan_rose@apple.com>
Thu, 15 Nov 2012 19:11:43 +0000 (19:11 +0000)
committerJordan Rose <jordan_rose@apple.com>
Thu, 15 Nov 2012 19:11:43 +0000 (19:11 +0000)
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

14 files changed:
lib/StaticAnalyzer/Core/BugReporter.cpp
lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
lib/StaticAnalyzer/Core/PathDiagnostic.cpp
test/Analysis/coverage.c
test/Analysis/keychainAPI.m
test/Analysis/malloc-annotations.c
test/Analysis/malloc-interprocedural.c
test/Analysis/malloc-plist.c
test/Analysis/malloc.c
test/Analysis/malloc.cpp
test/Analysis/plist-output-alternate.m
test/Analysis/retain-release.m
test/Analysis/simple-stream-checks.c
test/Analysis/stackaddrleak.c

index c6689f8536dc2812475c51bfd4e40c587914b22e..5c14eaf284781e25aee67316699645910cb00af8 100644 (file)
@@ -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 {
index a98e8b4922860e812483d52b193e8abc60b8b725..426d48dae2bb1a171f9dbbf1edae603e0a10a051 100644 (file)
@@ -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 {
index 2ebadcaa23810f1be18f4dad7a94c8380d638640..cfe35251a91ec2fc63807d76d788c81648889478 100644 (file)
@@ -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());
   }
 
index 66f0a5e385b9b9ed1f2fa1201a83a63410bf62cb..38e84e17cee00070d7a4c3ed224341ceee3777bc 100644 (file)
@@ -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;
index fe6c61d1e824e0dfbc16641859c78859b3cf373e..6eca8003d93774857ddc58f8175e840194f152d0 100644 (file)
@@ -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() {
index 2a078b6f8277e18fc701fe629862be1c8c29e876..3a260c3aefd4b7229ef79637b877c2787352c826 100644 (file)
@@ -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) {
index 79cbf247dd949feed2c3fedbf1c68e92626690f3..3c7bab6717c2d55a66b6fc9e9979cb1a195a05a1 100644 (file)
@@ -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}}
+  }
 }
index a99e34f4264d5b470ddcea49aa94751ecfaa64a7..b9ba45c2e11014311348b02ed564cbb4e7f2f0c6 100644 (file)
@@ -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>
index 76dd3a8fda33d6c2314be101898a1d5e94a24116..03fc38a73f00b7438c32a993af07407828d97fad 100644 (file)
@@ -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}}
+}\v
 // <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()
index 220d74625bc0b388f00188e59bc0861f8c989e0c..58b94ea774a4dcd0fd8107e9655d2e5d2a91d4bd 100644 (file)
@@ -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 {
index 7bb81bed1c5fae2396b61f073c4f7c8d3f7f2bff..423574d7819b88fe70a08f27f2c42a9d753e5415 100644 (file)
@@ -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>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// 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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>57</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -1266,13 +1232,13 @@ void rdar8331641(int x) {
 // CHECK-NEXT:         <key>end</key>
 // 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>line</key><integer>58</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>57</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>58</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -1283,25 +1249,10 @@ void rdar8331641(int x) {
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>57</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>line</key><integer>58</integer>
+// CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// 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>14</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;value&apos; is not referenced later in this execution path and has a retain count of +1</string>
@@ -1314,11 +1265,11 @@ void rdar8331641(int x) {
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar8331641</string>
-// CHECK-NEXT:   <key>issue_hash</key><integer>5</integer>
+// CHECK-NEXT:   <key>issue_hash</key><integer>6</integer>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>57</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>line</key><integer>58</integer>
+// CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
index eb2554f8897ddedcdbb19e26e09bbdbd822b97f5..ef2566b9616b48a378bef0f98e6bce48160e9882 100644 (file)
@@ -474,8 +474,8 @@ void f13_autorelease() {
 void f13_autorelease_b() {
   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
   [(id) A autorelease];
-  [(id) A autorelease]; // expected-warning{{Object sent -autorelease too many times}}
-}
+  [(id) A autorelease];
+} // expected-warning{{Object sent -autorelease too many times}}
 
 CFMutableArrayRef f13_autorelease_c() {
   CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
index 2f09e5dd20e4457180177bab0979a65f3fb20e7a..74794cc664a4ac41582378d8e77bc95ea55e84cc 100644 (file)
@@ -44,8 +44,8 @@ void CloseOnlyOnValidFileHandle() {
 }
 
 void leakOnEnfOfPath1(int *Data) {
-  FILE *F = fopen("myfile.txt", "w");// expected-warning {{Opened file is never closed; potential resource leak}}
-}
+  FILE *F = fopen("myfile.txt", "w");
+} // expected-warning {{Opened file is never closed; potential resource leak}}
 
 void leakOnEnfOfPath2(int *Data) {
   FILE *F = fopen("myfile.txt", "w");
index ada0cc10690575ddb8b379a8c7438d4b651b9fdb..10564faff38ac3d32306eb3ce93ed2889591545c 100644 (file)
@@ -4,8 +4,8 @@ char const *p;
 
 void f0() {
   char const str[] = "This will change";
-  p = str; // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
-}
+  p = str;
+}  // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
 
 void f1() {
   char const str[] = "This will change";
@@ -14,8 +14,8 @@ void f1() {
 }
 
 void f2() {
-  p = (const char *) __builtin_alloca(12);  // expected-warning{{Address of stack memory allocated by call to alloca() on line 17 is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
-}
+  p = (const char *) __builtin_alloca(12);
+} // expected-warning{{Address of stack memory allocated by call to alloca() on line 17 is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
 
 // PR 7383 - previosly the stack address checker would crash on this example
 //  because it would attempt to do a direct load from 'pr7383_list'. 
@@ -30,5 +30,5 @@ void test_multi_return() {
   static int *a, *b;
   int x;
   a = &x;
-  b = &x; // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'b' upon returning}}
-}
+  b = &x;
+} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'b' upon returning}}