[cfe-commits] r162718 - in /cfe/trunk: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp test/Analysis/inlining/path-notes.c

Jordan Rose jordan_rose at apple.com
Mon Aug 27 17:50:42 PDT 2012


Author: jrose
Date: Mon Aug 27 19:50:42 2012
New Revision: 162718

URL: http://llvm.org/viewvc/llvm-project?rev=162718&view=rev
Log:
[analyzer] If the last store into a region came from a function, step into it.

Previously, if we were tracking stores to a variable 'x', and came across this:

x = foo();

...we would simply emit a note here and stop. Now, we'll step into 'foo' and
continue tracking the returned value from there.

<rdar://problem/12114689>

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/trunk/test/Analysis/inlining/path-notes.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=162718&r1=162717&r2=162718&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Mon Aug 27 19:50:42 2012
@@ -20,6 +20,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "llvm/ADT/SmallString.h"
 
 using namespace clang;
@@ -110,6 +111,133 @@
 }
 
 
+namespace {
+/// Emits an extra note at the return statement of an interesting stack frame.
+///
+/// The returned value is marked as an interesting value, and if it's null,
+/// adds a visitor to track where it became null.
+///
+/// This visitor is intended to be used when another visitor discovers that an
+/// interesting value comes from an inlined function call.
+class ReturnVisitor : public BugReporterVisitorImpl<ReturnVisitor> {
+  const StackFrameContext *StackFrame;
+  bool Satisfied;
+public:
+  ReturnVisitor(const StackFrameContext *Frame)
+    : StackFrame(Frame), Satisfied(false) {}
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+    static int Tag = 0;
+    ID.AddPointer(&Tag);
+    ID.AddPointer(StackFrame);
+  }
+
+  /// Adds a ReturnVisitor if the given statement represents a call that was
+  /// inlined.
+  ///
+  /// This will search back through the ExplodedGraph, starting from the given
+  /// node, looking for when the given statement was processed. If it turns out
+  /// the statement is a call that was inlined, we add the visitor to the
+  /// bug report, so it can print a note later.
+  static void addVisitorIfNecessary(const ExplodedNode *Node, const Stmt *S,
+                                    BugReport &BR) {
+    if (!CallEvent::isCallStmt(S))
+      return;
+    
+    // First, find when we processed the statement.
+    do {
+      if (const CallExitEnd *CEE = Node->getLocationAs<CallExitEnd>())
+        if (CEE->getCalleeContext()->getCallSite() == S)
+          break;
+      if (const StmtPoint *SP = Node->getLocationAs<StmtPoint>())
+        if (SP->getStmt() == S)
+          break;
+
+      Node = Node->getFirstPred();
+    } while (Node);
+
+    // Next, step over any post-statement checks.
+    while (Node && isa<PostStmt>(Node->getLocation()))
+      Node = Node->getFirstPred();
+
+    // Finally, see if we inlined the call.
+    if (Node)
+      if (const CallExitEnd *CEE = Node->getLocationAs<CallExitEnd>())
+        if (CEE->getCalleeContext()->getCallSite() == S)
+          BR.addVisitor(new ReturnVisitor(CEE->getCalleeContext()));
+
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) {
+    if (Satisfied)
+      return 0;
+
+    // Only print a message at the interesting return statement.
+    if (N->getLocationContext() != StackFrame)
+      return 0;
+
+    const StmtPoint *SP = N->getLocationAs<StmtPoint>();
+    if (!SP)
+      return 0;
+
+    const ReturnStmt *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
+    if (!Ret)
+      return 0;
+
+    // Okay, we're at the right return statement, but do we have the return
+    // value available?
+    ProgramStateRef State = N->getState();
+    SVal V = State->getSVal(Ret, StackFrame);
+    if (V.isUnknownOrUndef())
+      return 0;
+
+    // Don't print any more notes after this one.
+    Satisfied = true;
+
+    // Build an appropriate message based on the return value.
+    SmallString<64> Msg;
+    llvm::raw_svector_ostream Out(Msg);
+
+    const Expr *RetE = Ret->getRetValue();
+    assert(RetE && "Tracking a return value for a void function");
+    RetE = RetE->IgnoreParenCasts();
+
+    // See if we know that the return value is 0.
+    ProgramStateRef StNonZero, StZero;
+    llvm::tie(StNonZero, StZero) = State->assume(cast<DefinedSVal>(V));
+    if (StZero && !StNonZero) {
+      // If we're returning 0, we should track where that 0 came from.
+      bugreporter::addTrackNullOrUndefValueVisitor(N, RetE, &BR);
+
+      if (isa<Loc>(V)) {
+        if (RetE->getType()->isObjCObjectPointerType())
+          Out << "Returning nil";
+        else
+          Out << "Returning null pointer";
+      } else {
+        Out << "Returning zero";
+      }
+    } else {
+      // FIXME: We can probably do better than this.
+      BR.markInteresting(V);
+      Out << "Value returned here";
+    }
+
+    // FIXME: We should have a more generalized location printing mechanism.
+    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
+      if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
+        Out << " (loaded from '" << *DD << "')";
+
+    PathDiagnosticLocation L(Ret, BRC.getSourceManager(), StackFrame);
+    return new PathDiagnosticEventPiece(L, Out.str());
+  }
+};
+} // end anonymous namespace
+
+
 void FindLastStoreBRVisitor ::Profile(llvm::FoldingSetNodeID &ID) const {
   static int tag = 0;
   ID.AddPointer(&tag);
@@ -133,6 +261,7 @@
       return NULL;
 
     const ExplodedNode *Node = N, *Last = N;
+    const Expr *InitE = 0;
 
     // Now look for the store of V.
     for ( ; Node ; Node = Node->getFirstPred()) {
@@ -142,14 +271,26 @@
             if (DS->getSingleDecl() == VR->getDecl()) {
               // Record the last seen initialization point.
               Last = Node;
+              InitE = VR->getDecl()->getInit();
               break;
             }
       }
 
       // Does the region still bind to value V?  If not, we are done
       // looking for store sites.
-      if (Node->getState()->getSVal(R) != V)
+      SVal Current = Node->getState()->getSVal(R);
+      if (Current != V) {
+        // If this is an assignment expression, we can track the value
+        // being assigned.
+        if (const StmtPoint *SP = Last->getLocationAs<StmtPoint>()) {
+          const Stmt *S = SP->getStmt();
+          if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(S))
+            if (BO->isAssignmentOp())
+              InitE = BO->getRHS();
+        }
+
         break;
+      }
 
       Last = Node;
     }
@@ -160,6 +301,13 @@
     }
 
     StoreSite = Last;
+
+    // If the value that was stored came from an inlined call, make sure we
+    // step into the call.
+    if (InitE) {
+      InitE = InitE->IgnoreParenCasts();
+      ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE, BR);
+    }
   }
 
   if (StoreSite != N)
@@ -303,50 +451,6 @@
   return NULL;
 }
 
-namespace {
-class ReturnNullVisitor : public BugReporterVisitorImpl<ReturnNullVisitor> {
-  const ExplodedNode *ReturnNode;
-public:
-  ReturnNullVisitor(const ExplodedNode *N) : ReturnNode(N) {}
-
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
-    static int Tag = 0;
-    ID.AddPointer(&Tag);
-    ID.Add(*ReturnNode);
-  }
-
-  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                 const ExplodedNode *PrevN,
-                                 BugReporterContext &BRC,
-                                 BugReport &BR) {
-    // Only print a message at the interesting return statement.
-    if (ReturnNode != BRC.getNodeResolver().getOriginalNode(N))
-      return 0;
-
-    StmtPoint SP = cast<StmtPoint>(ReturnNode->getLocation());
-    const ReturnStmt *Ret = cast<ReturnStmt>(SP.getStmt());
-    PathDiagnosticLocation L(Ret, BRC.getSourceManager(),
-                             N->getLocationContext());
-
-    SmallString<64> Msg;
-    llvm::raw_svector_ostream Out(Msg);
-
-    if (Loc::isLocType(Ret->getRetValue()->getType()))
-      Out << "Returning null pointer";
-    else
-      Out << "Returning zero";
-
-    // FIXME: We should have a more generalized printing mechanism.
-    const Expr *RetE = Ret->getRetValue()->IgnoreParenCasts();
-    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
-      if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
-        Out << " (loaded from '" << *DD << "')";
-
-    return new PathDiagnosticEventPiece(L, Out.str());
-  }
-};
-} // end anonymous namespace
-
 void bugreporter::addTrackNullOrUndefValueVisitor(const ExplodedNode *N,
                                                   const Stmt *S,
                                                   BugReport *report) {
@@ -421,39 +525,10 @@
       report->addVisitor(new TrackConstraintBRVisitor(loc::MemRegionVal(Base),
                                                       false));
     }
-  } else if (isa<loc::ConcreteInt>(V)) {
-    // Otherwise, if it's a null constant, we want to know where it came from.
-    // In particular, if it came from an inlined function call,
-    // we need to make sure that function isn't pruned in our output.
-    
-    // Walk backwards to just before the post-statement checks.
-    ProgramPoint PP = N->getLocation();
-    while (N && isa<PostStmt>(PP = N->getLocation()))
-      N = N->getFirstPred();
-
-    // If we found an inlined call before the post-statement checks, look
-    // for a return statement within the call.
-    if (N && isa<CallExitEnd>(PP)) {
-      // Walk backwards within the inlined function until we find a statement.
-      // This will look through multiple levels of inlining, but stop if the
-      // last thing that happened was an empty function being inlined.
-      // FIXME: This may not work in the presence of destructors.
-      do {
-        N = N->getFirstPred();
-        PP = N->getLocation();
-      } while (!isa<StmtPoint>(PP) && !isa<CallEnter>(PP));
-
-      // If the last statement we found is a 'return <expr>', make sure we
-      // show this return...and recursively track the value being returned.
-      if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) {
-        if (const ReturnStmt *Ret = SP->getStmtAs<ReturnStmt>()) {
-          if (const Expr *RetE = Ret->getRetValue()) {
-            report->addVisitor(new ReturnNullVisitor(N));
-            addTrackNullOrUndefValueVisitor(N, RetE, report);
-          }
-        }
-      }
-    }
+  } else {
+    // Otherwise, if the value came from an inlined function call,
+    // we should at least make sure that function isn't pruned in our output.
+    ReturnVisitor::addVisitorIfNecessary(N, S, *report);
   }
 }
 

Modified: cfe/trunk/test/Analysis/inlining/path-notes.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/path-notes.c?rev=162718&r1=162717&r2=162718&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/path-notes.c (original)
+++ cfe/trunk/test/Analysis/inlining/path-notes.c Mon Aug 27 19:50:42 2012
@@ -80,17 +80,19 @@
 }
 
 void testInitZero() {
-  // FIXME: <rdar://problem/12114689> Diagnostics: Need to step into the function whose result is assigned to an interesting region
   int *a = getZero();
-  // expected-note at -1 {{Variable 'a' initialized to a null pointer value}}
+  // expected-note at -1 {{Calling 'getZero'}}
+  // expected-note at -2 {{Returning from 'getZero'}}
+  // expected-note at -3 {{Variable 'a' initialized to a null pointer value}}
   *a = 1; // expected-warning{{Dereference of null pointer}}
   // expected-note at -1 {{Dereference of null pointer (loaded from variable 'a')}}
 }
 
 void testStoreZero(int *a) {
-  // FIXME: <rdar://problem/12114689> Diagnostics: Need to step into the function whose result is assigned to an interesting region
   a = getZero();
-  // expected-note at -1 {{Null pointer value stored to 'a'}}
+  // expected-note at -1 {{Calling 'getZero'}}
+  // expected-note at -2 {{Returning from 'getZero'}}
+  // expected-note at -3 {{Null pointer value stored to 'a'}}
   *a = 1; // expected-warning{{Dereference of null pointer}}
   // expected-note at -1 {{Dereference of null pointer (loaded from variable 'a')}}
 }
@@ -2028,12 +2030,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2041,12 +2043,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>12</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2055,6 +2057,204 @@
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>83</integer>
+// CHECK:       <key>col</key><integer>12</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>83</integer>
+// CHECK:          <key>col</key><integer>12</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>83</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling 'getZero'</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling 'getZero'</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>60</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call from 'testInitZero'</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call from 'testInitZero'</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>60</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>60</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>61</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>61</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>61</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable 'p' initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable 'p' initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>64</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning null pointer (loaded from 'p')</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning null pointer (loaded from 'p')</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>83</integer>
+// CHECK:       <key>col</key><integer>12</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>83</integer>
+// CHECK:          <key>col</key><integer>12</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>83</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning from 'getZero'</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning from 'getZero'</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -2062,12 +2262,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2075,12 +2275,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>12</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2096,12 +2296,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>12</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2109,12 +2309,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2126,7 +2326,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>84</integer>
+// CHECK:       <key>line</key><integer>83</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -2134,12 +2334,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>84</integer>
+// CHECK:          <key>line</key><integer>83</integer>
 // CHECK:          <key>col</key><integer>3</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>84</integer>
+// CHECK:          <key>line</key><integer>83</integer>
 // CHECK:          <key>col</key><integer>8</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -2159,12 +2359,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>84</integer>
+// CHECK:            <key>line</key><integer>83</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2172,12 +2372,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>86</integer>
+// CHECK:            <key>line</key><integer>87</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>86</integer>
+// CHECK:            <key>line</key><integer>87</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2189,7 +2389,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>86</integer>
+// CHECK:       <key>line</key><integer>87</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -2197,12 +2397,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>86</integer>
+// CHECK:          <key>line</key><integer>87</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>86</integer>
+// CHECK:          <key>line</key><integer>87</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -2220,10 +2420,10 @@
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>issue_context_kind</key><string>function</string>
 // CHECK:   <key>issue_context</key><string>testInitZero</string>
-// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>issue_hash</key><integer>5</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>86</integer>
+// CHECK:    <key>line</key><integer>87</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -2266,6 +2466,204 @@
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>92</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>92</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>92</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling 'getZero'</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling 'getZero'</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>60</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call from 'testStoreZero'</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call from 'testStoreZero'</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>60</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>60</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>61</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>61</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>61</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable 'p' initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable 'p' initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>61</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>64</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning null pointer (loaded from 'p')</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning null pointer (loaded from 'p')</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>92</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>92</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>92</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning from 'getZero'</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning from 'getZero'</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -2383,12 +2781,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>line</key><integer>96</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>line</key><integer>96</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -2400,7 +2798,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>94</integer>
+// CHECK:       <key>line</key><integer>96</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -2408,12 +2806,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>94</integer>
+// CHECK:          <key>line</key><integer>96</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>94</integer>
+// CHECK:          <key>line</key><integer>96</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -2431,10 +2829,10 @@
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>issue_context_kind</key><string>function</string>
 // CHECK:   <key>issue_context</key><string>testStoreZero</string>
-// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>issue_hash</key><integer>5</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>94</integer>
+// CHECK:    <key>line</key><integer>96</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>





More information about the cfe-commits mailing list