]> granicus.if.org Git - clang/commitdiff
[analyzer] Implement basic path diagnostic pruning based on "interesting" symbols...
authorTed Kremenek <kremenek@apple.com>
Fri, 9 Mar 2012 01:13:14 +0000 (01:13 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 9 Mar 2012 01:13:14 +0000 (01:13 +0000)
Essentially, a bug centers around a story for various symbols and regions.  We should only include
the path diagnostic events that relate to those symbols and regions.

The pruning is done by associating a set of interesting symbols and regions with a BugReporter, which
can be modified at BugReport creation or by BugReporterVisitors.

This patch reduces the diagnostics emitted in several of our test cases.  I've vetted these as
having desired behavior.  The only regression is a missing null check diagnostic for the return
value of realloc() in test/Analysis/malloc-plist.c.  This will require some investigation to fix,
and I have added a FIXME to the test case.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152361 91177308-0d34-0410-b5e6-96231b3b80d8

25 files changed:
include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
lib/StaticAnalyzer/Checkers/CStringChecker.cpp
lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
lib/StaticAnalyzer/Checkers/MallocChecker.cpp
lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
lib/StaticAnalyzer/Core/BugReporter.cpp
lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
test/Analysis/malloc-plist.c
test/Analysis/plist-output-alternate.m
test/Analysis/plist-output.m

index 0978d86de46bbaa304c2f64906974734c923f3ae..b607fe8b2fc9ccf6be1d6c63544f53483f47e793 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/ADT/ImmutableList.h"
 #include "llvm/ADT/ImmutableSet.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/DenseSet.h"
 #include <list>
 
 namespace clang {
@@ -50,7 +51,7 @@ class BugType;
 /// This class provides an interface through which checkers can create
 /// individual bug reports.
 class BugReport {
-public:
+public:  
   class NodeResolver {
     virtual void anchor();
   public:
@@ -75,6 +76,19 @@ protected:
   const ExplodedNode *ErrorNode;
   SmallVector<SourceRange, 4> Ranges;
   ExtraTextList ExtraText;
+  
+  typedef llvm::DenseSet<SymbolRef> Symbols;
+  typedef llvm::DenseSet<const MemRegion *> Regions;
+
+  /// A set of symbols that are registered with this report as being
+  /// "interesting", and thus used to help decide which diagnostics
+  /// to include when constructing the final path diagnostic.
+  Symbols interestingSymbols;
+
+  /// A set of regions that are registered with this report as being
+  /// "interesting", and thus used to help decide which diagnostics
+  /// to include when constructing the final path diagnostic.
+  Regions interestingRegions;
 
   // Not the most efficient data structure, but we use an ImmutableList for the
   // Callbacks because it is safe to make additions to list during iteration.
@@ -121,6 +135,14 @@ public:
     return ShortDescription.empty() ? Description : ShortDescription;
   }
 
+  void markInteresting(SymbolRef sym);
+  void markInteresting(const MemRegion *R);
+  void markInteresting(SVal V);
+  
+  bool isInteresting(SymbolRef sym) const;
+  bool isInteresting(const MemRegion *R) const;
+  bool isInteresting(SVal V) const;
+  
   /// \brief This allows for addition of meta data to the diagnostic.
   ///
   /// Currently, only the HTMLDiagnosticClient knows how to display it. 
@@ -351,7 +373,6 @@ private:
 // FIXME: Get rid of GRBugReporter.  It's the wrong abstraction.
 class GRBugReporter : public BugReporter {
   ExprEngine& Eng;
-  llvm::SmallSet<SymbolRef, 10> NotableSymbols;
 public:
   GRBugReporter(BugReporterData& d, ExprEngine& eng)
     : BugReporter(d, GRBugReporterKind), Eng(eng) {}
@@ -373,14 +394,6 @@ public:
   virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic,
                      SmallVectorImpl<BugReport*> &bugReports);
 
-  void addNotableSymbol(SymbolRef Sym) {
-    NotableSymbols.insert(Sym);
-  }
-
-  bool isNotable(SymbolRef Sym) const {
-    return (bool) NotableSymbols.count(Sym);
-  }
-
   /// classof - Used by isa<>, cast<>, and dyn_cast<>.
   static bool classof(const BugReporter* R) {
     return R->getKind() == GRBugReporterKind;
@@ -399,16 +412,6 @@ public:
 
   ExplodedGraph &getGraph() { return BR.getGraph(); }
 
-  void addNotableSymbol(SymbolRef Sym) {
-    // FIXME: For now forward to GRBugReporter.
-    BR.addNotableSymbol(Sym);
-  }
-
-  bool isNotable(SymbolRef Sym) const {
-    // FIXME: For now forward to GRBugReporter.
-    return BR.isNotable(Sym);
-  }
-
   ProgramStateManager& getStateManager() {
     return BR.getStateManager();
   }
index 5434257dd44225f3feb9dc370e7d29f03fef2aa6..2357cbd09570c7c84b2d50c2fa5f0ebeb33ccaaf 100644 (file)
@@ -147,40 +147,49 @@ public:
                                        const ExplodedNode *N,
                                        const CFGBlock *srcBlk,
                                        const CFGBlock *dstBlk,
+                                       BugReport &R,
                                        BugReporterContext &BRC);
 
   PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
                                      bool tookTrue,
                                      BugReporterContext &BRC,
-                                     const LocationContext *LC);
+                                     BugReport &R,
+                                     const ExplodedNode *N);
 
   PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
                                      const DeclRefExpr *DR,
                                      const bool tookTrue,
                                      BugReporterContext &BRC,
-                                     const LocationContext *LC);
+                                     BugReport &R,
+                                     const ExplodedNode *N);
 
   PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
                                      const BinaryOperator *BExpr,
                                      const bool tookTrue,
                                      BugReporterContext &BRC,
-                                     const LocationContext *LC);
+                                     BugReport &R,
+                                     const ExplodedNode *N);
   
   PathDiagnosticPiece *VisitConditionVariable(StringRef LhsString,
                                               const Expr *CondVarExpr,
                                               const bool tookTrue,
                                               BugReporterContext &BRC,
-                                              const LocationContext *LC);
+                                              BugReport &R,
+                                              const ExplodedNode *N);
 
   bool patternMatch(const Expr *Ex,
                     llvm::raw_ostream &Out,
-                    BugReporterContext &BRC);
+                    BugReporterContext &BRC,
+                    BugReport &R,
+                    const ExplodedNode *N,
+                    llvm::Optional<bool> &prunable);
 };
   
 namespace bugreporter {
 
 BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
-                                                    const Stmt *S);
+                                                    const Stmt *S,
+                                                    BugReport *R);
 
 const Stmt *GetDerefExpr(const ExplodedNode *N);
 const Stmt *GetDenomExpr(const ExplodedNode *N);
index 245d5be93e658dcc132f61d63a6180e32bbc3944..e98d82bf22b01a72d1be17d59187ac8e20163bbf 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/Optional.h"
 #include <deque>
 #include <iterator>
 #include <string>
@@ -357,17 +358,27 @@ public:
 };
 
 class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
-  bool IsPrunable;
+  llvm::Optional<bool> IsPrunable;
 public:
   PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
                            StringRef s, bool addPosRange = true)
-    : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
-      IsPrunable(false) {}
+    : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
 
   ~PathDiagnosticEventPiece();
 
-  void setPrunable(bool isPrunable) { IsPrunable = isPrunable; }
-  bool isPrunable() const { return IsPrunable; }
+  /// Mark the diagnostic piece as being potentially prunable.  This
+  /// flag may have been previously set, at which point it will not
+  /// be reset unless one specifies to do so.
+  void setPrunable(bool isPrunable, bool override = false) {
+    if (IsPrunable.hasValue() && !override)
+     return;
+    IsPrunable = isPrunable;
+  }
+
+  /// Return true if the diagnostic piece is prunable.
+  bool isPrunable() const {
+    return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
+  }
   
   static inline bool classof(const PathDiagnosticPiece *P) {
     return P->getKind() == Event;
index 0b11a459ce4b9ca23bc86c18e96c3df9cf13ab47..ab66e9864fe279d3b6efd612c9e6eb75018492b3 100644 (file)
@@ -109,7 +109,7 @@ void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
         const Expr *arg = *I;
         R->addRange(arg->getSourceRange());
         R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
-                                                                   arg));
+                                                                   arg, R));
         // Emit the bug report.
         C.EmitReport(R);
       }
index 1af43d1a337e3b8d3b930ea4d16ec0679478953a..dd4235af5ef7de1e91b8427ae075814be55139a0 100644 (file)
@@ -411,7 +411,8 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
 
     BugReport *report = new BugReport(*BT, description, N);
     report->addRange(Arg->getSourceRange());
-    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Arg));
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Arg,
+                                                                    report));
     C.EmitReport(report);
     return;
   }
index 802103e39699ba123df8abf01e5ee93a65e660fb..639dd72e9d12d9954cc7325703fae651258d8d4f 100644 (file)
@@ -252,7 +252,8 @@ ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
     BugReport *report = new BugReport(*BT, os.str(), N);
 
     report->addRange(S->getSourceRange());
-    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S));
+    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S,
+                                                                    report));
     C.EmitReport(report);
     return NULL;
   }
index de48769d785264e3b4aa69a13a0a7af3056ea095..f6014317c83960e57d5d94237aa9cd8acc6735ed 100644 (file)
@@ -72,7 +72,7 @@ void CallAndMessageChecker::EmitBadCall(BugType *BT, CheckerContext &C,
 
   BugReport *R = new BugReport(*BT, BT->getName(), N);
   R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                               bugreporter::GetCalleeExpr(N)));
+                               bugreporter::GetCalleeExpr(N), R));
   C.EmitReport(R);
 }
 
@@ -111,7 +111,8 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
       BugReport *R = new BugReport(*BT, BT->getName(), N);
       R->addRange(argRange);
       if (argEx)
-        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx));
+        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx,
+                                                                   R));
       C.EmitReport(R);
     }
     return true;
@@ -262,7 +263,8 @@ void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
           new BugReport(*BT, BT->getName(), N);
         R->addRange(receiver->getSourceRange());
         R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                   receiver));
+                                                                   receiver,
+                                                                   R));
         C.EmitReport(R);
       }
       return;
@@ -308,7 +310,8 @@ void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
   if (const Expr *receiver = msg.getInstanceReceiver()) {
     report->addRange(receiver->getSourceRange());
     report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                    receiver));
+                                                                    receiver,
+                                                                    report));
   }
   C.EmitReport(report);
 }
index 7e4761cdf8f91c746c4aa2aa50981473cbe4241c..81a27451cbaab9b4df1c49cb8ad0325e8b238186 100644 (file)
@@ -34,28 +34,35 @@ public:
   void checkLocation(SVal location, bool isLoad, const Stmt* S,
                      CheckerContext &C) const;
 
-  static void AddDerefSource(raw_ostream &os,
+  static const MemRegion *AddDerefSource(raw_ostream &os,
                              SmallVectorImpl<SourceRange> &Ranges,
-                             const Expr *Ex, bool loadedFrom = false);
+                             const Expr *Ex, const ProgramState *state,
+                             const LocationContext *LCtx,
+                             bool loadedFrom = false);
 };
 } // end anonymous namespace
 
-void DereferenceChecker::AddDerefSource(raw_ostream &os,
-                                        SmallVectorImpl<SourceRange> &Ranges,
-                                        const Expr *Ex,
-                                        bool loadedFrom) {
+const MemRegion *
+DereferenceChecker::AddDerefSource(raw_ostream &os,
+                                   SmallVectorImpl<SourceRange> &Ranges,
+                                   const Expr *Ex,
+                                   const ProgramState *state,
+                                   const LocationContext *LCtx,
+                                   bool loadedFrom) {
   Ex = Ex->IgnoreParenLValueCasts();
+  const MemRegion *sourceR = 0;
   switch (Ex->getStmtClass()) {
     default:
-      return;
+      break;
     case Stmt::DeclRefExprClass: {
       const DeclRefExpr *DR = cast<DeclRefExpr>(Ex);
       if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
         os << " (" << (loadedFrom ? "loaded from" : "from")
            << " variable '" <<  VD->getName() << "')";
         Ranges.push_back(DR->getSourceRange());
+        sourceR = state->getLValue(VD, LCtx).getAsRegion();
       }
-      return;
+      break;
     }
     case Stmt::MemberExprClass: {
       const MemberExpr *ME = cast<MemberExpr>(Ex);
@@ -66,6 +73,7 @@ void DereferenceChecker::AddDerefSource(raw_ostream &os,
       break;
     }
   }
+  return sourceR;
 }
 
 void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
@@ -79,7 +87,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
       report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                        bugreporter::GetDerefExpr(N)));
+                                        bugreporter::GetDerefExpr(N), report));
       C.EmitReport(report);
     }
     return;
@@ -92,6 +100,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
     return;
 
   ProgramStateRef state = C.getState();
+  const LocationContext *LCtx = C.getLocationContext();
   ProgramStateRef notNullState, nullState;
   llvm::tie(notNullState, nullState) = state->assume(location);
 
@@ -115,13 +124,17 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
       // that syntactically caused the load.
       if (const Expr *expr = dyn_cast<Expr>(S))
         S = expr->IgnoreParenLValueCasts();
+      
+      const MemRegion *sourceR = 0;
 
       switch (S->getStmtClass()) {
         case Stmt::ArraySubscriptExprClass: {
           llvm::raw_svector_ostream os(buf);
           os << "Array access";
           const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
-          AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts());
+          sourceR =
+            AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
+                           state.getPtr(), LCtx);
           os << " results in a null pointer dereference";
           break;
         }
@@ -129,7 +142,9 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
           llvm::raw_svector_ostream os(buf);
           os << "Dereference of null pointer";
           const UnaryOperator *U = cast<UnaryOperator>(S);
-          AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(), true);
+          sourceR =
+            AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
+                           state.getPtr(), LCtx, true);
           break;
         }
         case Stmt::MemberExprClass: {
@@ -138,7 +153,9 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
             llvm::raw_svector_ostream os(buf);
             os << "Access to field '" << M->getMemberNameInfo()
                << "' results in a dereference of a null pointer";
-            AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(), true);
+            sourceR =
+              AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
+                             state.getPtr(), LCtx, true);
           }
           break;
         }
@@ -165,12 +182,17 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
                               N);
 
       report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                        bugreporter::GetDerefExpr(N)));
+                                        bugreporter::GetDerefExpr(N), report));
 
       for (SmallVectorImpl<SourceRange>::iterator
             I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
         report->addRange(*I);
 
+      if (sourceR) {
+        report->markInteresting(sourceR);
+        report->markInteresting(state->getRawSVal(loc::MemRegionVal(sourceR)));
+      }
+
       C.EmitReport(report);
       return;
     }
index ca71ca33a1604d4375e91e6c5be35cd0f03a7e1f..2627f0c982f04c556ef42f79dbbc39f11a311878 100644 (file)
@@ -43,8 +43,7 @@ void DivZeroChecker::reportBug(const char *Msg,
       new BugReport(*BT, Msg, N);
 
     R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                 bugreporter::GetDenomExpr(N)));
-
+                                 bugreporter::GetDenomExpr(N), R));
     C.EmitReport(R);
   }
 }
index b96bc66b6f79678450550636811774fed3552d44..1b8dd6874c87db99b4202de84cc1562f18fc7c61 100644 (file)
@@ -121,6 +121,12 @@ private:
                                    SValBuilder &Builder) const {
     return definitelyReturnedError(RetSym, State, Builder, true);
   }
+                                                 
+  /// Mark an AllocationPair interesting for diagnostic reporting.
+  void markInteresting(BugReport *R, const AllocationPair &AP) const {
+    R->markInteresting(AP.first);
+    R->markInteresting(AP.second->Region);
+  }
 
   /// The bug visitor which allows us to print extra diagnostics along the
   /// BugReport path. For example, showing the allocation site of the leaked
@@ -282,6 +288,7 @@ void MacOSKeychainAPIChecker::
   BugReport *Report = new BugReport(*BT, os.str(), N);
   Report->addVisitor(new SecKeychainBugVisitor(AP.first));
   Report->addRange(ArgExpr->getSourceRange());
+  markInteresting(Report, AP);
   C.EmitReport(Report);
 }
 
@@ -318,6 +325,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
           BugReport *Report = new BugReport(*BT, os.str(), N);
           Report->addVisitor(new SecKeychainBugVisitor(V));
           Report->addRange(ArgExpr->getSourceRange());
+          Report->markInteresting(AS->Region);
           C.EmitReport(Report);
         }
       }
@@ -369,6 +377,8 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
     BugReport *Report = new BugReport(*BT,
         "Trying to free data which has not been allocated.", N);
     Report->addRange(ArgExpr->getSourceRange());
+    if (AS)
+      Report->markInteresting(AS->Region);
     C.EmitReport(Report);
     return;
   }
@@ -432,6 +442,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
         "Only call free if a valid (non-NULL) buffer was returned.", N);
     Report->addVisitor(new SecKeychainBugVisitor(ArgSM));
     Report->addRange(ArgExpr->getSourceRange());
+    Report->markInteresting(AS->Region);
     C.EmitReport(Report);
     return;
   }
@@ -550,6 +561,7 @@ BugReport *MacOSKeychainAPIChecker::
 
   BugReport *Report = new BugReport(*BT, os.str(), N, LocUsedForUniqueing);
   Report->addVisitor(new SecKeychainBugVisitor(AP.first));
+  markInteresting(Report, AP);
   return Report;
 }
 
index c9f717059ea85969b963d21604b2d4c4387f3870..3f0d3d456e347f54011722ff73146cebb8cdf71c 100644 (file)
@@ -535,6 +535,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
       BugReport *R = new BugReport(*BT_DoubleFree, 
                         "Attempt to free released memory", N);
       R->addRange(ArgExpr->getSourceRange());
+      R->markInteresting(Sym);
       R->addVisitor(new MallocBugVisitor(Sym));
       C.EmitReport(R);
     }
@@ -667,6 +668,7 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
     }
     
     BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
+    R->markInteresting(MR);
     R->addRange(range);
     C.EmitReport(R);
   }
@@ -820,6 +822,7 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
 
   BugReport *R = new BugReport(*BT_Leak,
     "Memory is never released; potential memory leak", N, LocUsedForUniqueing);
+  R->markInteresting(Sym);
   R->addVisitor(new MallocBugVisitor(Sym));
   C.EmitReport(R);
 }
@@ -964,6 +967,7 @@ bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
                                    "Use of memory after it is freed",N);
       if (S)
         R->addRange(S->getSourceRange());
+      R->markInteresting(Sym);
       R->addVisitor(new MallocBugVisitor(Sym));
       C.EmitReport(R);
       return true;
index d70fdfd8e89d806edafe48d2d0f9019d9adcb943..25caf98b6d510829394032e36fee3addac8fb044 100644 (file)
@@ -50,7 +50,8 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
                                   "for @synchronized"));
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
+                                                                      report));
       C.EmitReport(report);
     }
     return;
@@ -73,7 +74,8 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
                                    "(no synchronization will occur)"));
         BugReport *report =
           new BugReport(*BT_null, BT_null->getDescription(), N);
-        report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
+        report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
+                                                                        report));
 
         C.EmitReport(report);
         return;
index f7dd6c2127aa90df497cc34efba0cfc50accc5f5..a59d1e4e4caeb416790aaa48c82926a110775b0e 100644 (file)
@@ -2165,9 +2165,7 @@ PathDiagnosticPiece*
 CFRefReportVisitor::getEndPath(BugReporterContext &BRC,
                                const ExplodedNode *EndN,
                                BugReport &BR) {
-  // Tell the BugReporterContext to report cases when the tracked symbol is
-  // assigned to different variables, etc.
-  BRC.addNotableSymbol(Sym);
+  BR.markInteresting(Sym);
   return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR);
 }
 
@@ -2178,7 +2176,7 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
 
   // Tell the BugReporterContext to report cases when the tracked symbol is
   // assigned to different variables, etc.
-  BRC.addNotableSymbol(Sym);
+  BR.markInteresting(Sym);
 
   // We are reporting a leak.  Walk up the graph to get to the first node where
   // the symbol appeared, and also get the first VarDecl that tracked object
index c83d63d00a33881a83b79cab2694daa8b822b171..7b1f0b139c116d3a88b11e254d40f7d092a720bb 100644 (file)
@@ -54,7 +54,8 @@ void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS,
     new BugReport(*BT, BT->getDescription(), N);
 
   report->addRange(RetE->getSourceRange());
-  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE));
+  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE,
+                                                                  report));
 
   C.EmitReport(report);
 }
index e826a114e7c4ce4d4d7e89ab12095a7d6074fee8..a30f6d53287f127fdf8d77122cc8a18fe65a4499 100644 (file)
@@ -99,7 +99,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
 
       // Emit the bug report.
       BugReport *R = new BugReport(*BT, BT->getDescription(), N);
-      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
+      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex, R));
       R->addRange(Ex->getSourceRange());
 
       Ctx.EmitReport(R);
index 3161a21c93107ebf4d773f2e4dfa5c84df509f3b..c3c9ed72345e890cbf808d0631a9430b49df2728 100644 (file)
@@ -76,10 +76,12 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
     BugReport *report = new BugReport(*BT, OS.str(), N);
     if (Ex) {
       report->addRange(Ex->getSourceRange());
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
+                                                                      report));
     }
     else
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, B));
+      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, B,
+                                                                      report));
     C.EmitReport(report);
   }
 }
index 9b9e4d5e36d518541d6f0ed0398f85de4b9b5232..0297c4eb14e9b33dc269f5314cb2b7898b4fef79 100644 (file)
@@ -43,7 +43,8 @@ UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
       BugReport *R = new BugReport(*BT, BT->getName(), N);
       R->addRange(A->getIdx()->getSourceRange());
       R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                 A->getIdx()));
+                                                                 A->getIdx(),
+                                                                 R));
       C.EmitReport(R);
     }
   }
index 840ae3d2ad50ad200d523c8d86476bb5ae5217a2..78f7fa61b288b91103d64c92216ac35757f85468 100644 (file)
@@ -78,7 +78,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
   BugReport *R = new BugReport(*BT, str, N);
   if (ex) {
     R->addRange(ex->getSourceRange());
-    R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex));
+    R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex, R));
   }
   C.EmitReport(R);
 }
index 2211940d652a0466ca964ec8bfdeb2667293457f..e68ab2a8b2a372ada415823d64e70d61da655e8a 100644 (file)
@@ -224,7 +224,8 @@ bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
   BugReport *report = new BugReport(*BT_mallocZero, os.str(), N);
 
   report->addRange(arg->getSourceRange());
-  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, arg));
+  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, arg,
+                                                                  report));
   C.EmitReport(report);
 
   return true;
index 72b68c58bf35ee67d8e172ff26d0496269cd511e..38c9cc1f333c3b8f9a32c0c229c3a4a841a3c04f 100644 (file)
@@ -69,7 +69,8 @@ void VLASizeChecker::reportBug(VLASize_Kind Kind,
 
   BugReport *report = new BugReport(*BT, os.str(), N);
   report->addRange(SizeE->getSourceRange());
-  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, SizeE));
+  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, SizeE,
+                                                                  report));
   C.EmitReport(report);
   return;
 }
index 53fedaf2a12d1a7b542401814446ef2f8a55c1f9..4ada636e8e93c1ad41ff8d0c318af8c5bae129b3 100644 (file)
@@ -148,8 +148,9 @@ static bool RemoveUneededCalls(PathPieces &pieces) {
         PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
         // We never throw away an event, but we do throw it away wholesale
         // as part of a path if we throw the entire path away.
-        if (!event->isPrunable())
-          containsSomethingInteresting = true;
+        if (event->isPrunable())
+          continue;
+        containsSomethingInteresting = true;
         break;
       }
       case PathDiagnosticPiece::ControlFlow:
@@ -376,190 +377,6 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
   return PathDiagnosticLocation(S, SMgr, LC);
 }
 
-//===----------------------------------------------------------------------===//
-// ScanNotableSymbols: closure-like callback for scanning Store bindings.
-//===----------------------------------------------------------------------===//
-
-static const VarDecl* GetMostRecentVarDeclBinding(const ExplodedNode *N,
-                                                  ProgramStateManager& VMgr,
-                                                  SVal X) {
-
-  for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
-
-    ProgramPoint P = N->getLocation();
-
-    if (!isa<PostStmt>(P))
-      continue;
-
-    const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(cast<PostStmt>(P).getStmt());
-
-    if (!DR)
-      continue;
-
-    SVal Y = N->getState()->getSVal(DR, N->getLocationContext());
-
-    if (X != Y)
-      continue;
-
-    const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
-
-    if (!VD)
-      continue;
-
-    return VD;
-  }
-
-  return 0;
-}
-
-namespace {
-class NotableSymbolHandler
-: public StoreManager::BindingsHandler {
-
-  SymbolRef Sym;
-  ProgramStateRef PrevSt;
-  const Stmt *S;
-  ProgramStateManager& VMgr;
-  const ExplodedNode *Pred;
-  PathDiagnostic& PD;
-  BugReporter& BR;
-
-public:
-
-  NotableSymbolHandler(SymbolRef sym,
-                       ProgramStateRef prevst,
-                       const Stmt *s,
-                       ProgramStateManager& vmgr,
-                       const ExplodedNode *pred,
-                       PathDiagnostic& pd,
-                       BugReporter& br)
-  : Sym(sym),
-    PrevSt(prevst),
-    S(s),
-    VMgr(vmgr),
-    Pred(pred),
-    PD(pd),
-    BR(br) {}
-
-  bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
-                     SVal V) {
-
-    SymbolRef ScanSym = V.getAsSymbol();
-
-    if (ScanSym != Sym)
-      return true;
-
-    // Check if the previous state has this binding.
-    SVal X = PrevSt->getSVal(loc::MemRegionVal(R));
-
-    if (X == V) // Same binding?
-      return true;
-
-    // Different binding.  Only handle assignments for now.  We don't pull
-    // this check out of the loop because we will eventually handle other
-    // cases.
-
-    VarDecl *VD = 0;
-
-    if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
-      if (!B->isAssignmentOp())
-        return true;
-
-      // What variable did we assign to?
-      DeclRefExpr *DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenCasts());
-
-      if (!DR)
-        return true;
-
-      VD = dyn_cast<VarDecl>(DR->getDecl());
-    }
-    else if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
-      // FIXME: Eventually CFGs won't have DeclStmts.  Right now we
-      //  assume that each DeclStmt has a single Decl.  This invariant
-      //  holds by construction in the CFG.
-      VD = dyn_cast<VarDecl>(*DS->decl_begin());
-    }
-
-    if (!VD)
-      return true;
-
-    // What is the most recently referenced variable with this binding?
-    const VarDecl *MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V);
-
-    if (!MostRecent)
-      return true;
-
-    // Create the diagnostic.
-    if (Loc::isLocType(VD->getType())) {
-      SmallString<64> buf;
-      llvm::raw_svector_ostream os(buf);
-      os << '\'' << *VD << "' now aliases '" << *MostRecent << '\'';
-      PathDiagnosticLocation L =
-        PathDiagnosticLocation::createBegin(S, BR.getSourceManager(),
-                                                   Pred->getLocationContext());
-      PD.getActivePath().push_front(new PathDiagnosticEventPiece(L, os.str()));
-    }
-
-    return true;
-  }
-};
-}
-
-static void HandleNotableSymbol(const ExplodedNode *N,
-                                const Stmt *S,
-                                SymbolRef Sym, BugReporter& BR,
-                                PathDiagnostic& PD) {
-
-  const ExplodedNode *Pred = N->pred_empty() ? 0 : *N->pred_begin();
-  ProgramStateRef PrevSt = Pred ? Pred->getState() : 0;
-
-  if (!PrevSt)
-    return;
-
-  // Look at the region bindings of the current state that map to the
-  // specified symbol.  Are any of them not in the previous state?
-  ProgramStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
-  NotableSymbolHandler H(Sym, PrevSt, S, VMgr, Pred, PD, BR);
-  cast<GRBugReporter>(BR).getStateManager().iterBindings(N->getState(), H);
-}
-
-namespace {
-class ScanNotableSymbols
-: public StoreManager::BindingsHandler {
-
-  llvm::SmallSet<SymbolRef, 10> AlreadyProcessed;
-  const ExplodedNode *N;
-  const Stmt *S;
-  GRBugReporter& BR;
-  PathDiagnostic& PD;
-
-public:
-  ScanNotableSymbols(const ExplodedNode *n, const Stmt *s,
-                     GRBugReporter& br, PathDiagnostic& pd)
-  : N(n), S(s), BR(br), PD(pd) {}
-
-  bool HandleBinding(StoreManager& SMgr, Store store,
-                     const MemRegion* R, SVal V) {
-
-    SymbolRef ScanSym = V.getAsSymbol();
-
-    if (!ScanSym)
-      return true;
-
-    if (!BR.isNotable(ScanSym))
-      return true;
-
-    if (AlreadyProcessed.count(ScanSym))
-      return true;
-
-    AlreadyProcessed.insert(ScanSym);
-
-    HandleNotableSymbol(N, S, ScanSym, BR, PD);
-    return true;
-  }
-};
-} // end anonymous namespace
-
 //===----------------------------------------------------------------------===//
 // "Minimal" path diagnostic generation algorithm.
 //===----------------------------------------------------------------------===//
@@ -866,13 +683,6 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
           PD.getActivePath().push_front(p);
       }
     }
-
-    if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
-      // Scan the region bindings, and see if a "notable" symbol has a new
-      // lval binding.
-      ScanNotableSymbols SNS(N, PS->getStmt(), PDB.getBugReporter(), PD);
-      PDB.getStateManager().iterBindings(N->getState(), SNS);
-    }
   }
 
   // After constructing the full PathDiagnostic, do a pass over it to compact
@@ -1400,6 +1210,50 @@ void BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
   }
 }
 
+void BugReport::markInteresting(SymbolRef sym) {
+  if (!sym)
+    return;
+  interestingSymbols.insert(sym);  
+}
+
+void BugReport::markInteresting(const MemRegion *R) {
+  if (!R)
+    return;
+  R = R->getBaseRegion();
+  interestingRegions.insert(R);
+  
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
+    interestingSymbols.insert(SR->getSymbol());
+}
+
+void BugReport::markInteresting(SVal V) {
+  markInteresting(V.getAsRegion());
+  markInteresting(V.getAsSymbol());
+}
+
+bool BugReport::isInteresting(SVal V) const {
+  return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol());
+}
+
+bool BugReport::isInteresting(SymbolRef sym) const {
+  if (!sym)
+    return false;
+  return interestingSymbols.count(sym);
+}
+
+bool BugReport::isInteresting(const MemRegion *R) const {
+  if (!R)
+    return false;
+  R = R->getBaseRegion();
+  bool b = interestingRegions.count(R);
+  if (b)
+    return true;
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
+    return interestingSymbols.count(SR->getSymbol());
+  return false;
+}
+  
+
 const Stmt *BugReport::getStmt() const {
   if (!ErrorNode)
     return 0;
index 1d29d5ff0a4cbcd3afa6d3e32a52ceff3823d54b..09a9b41eae248ac3ee0306deb36f556d0f8dd1b9 100644 (file)
@@ -287,7 +287,8 @@ TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
 
 BugReporterVisitor *
 bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
-                                             const Stmt *S) {
+                                             const Stmt *S,
+                                             BugReport *report) {
   if (!S || !N)
     return 0;
 
@@ -309,17 +310,19 @@ bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
   
   ProgramStateRef state = N->getState();
 
-  // Walk through lvalue-to-rvalue conversions.  
-  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
-    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
-      const VarRegion *R =
-        StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
-
-      // What did we load?
-      SVal V = state->getSVal(loc::MemRegionVal(R));
+  // Walk through lvalue-to-rvalue conversions.
+  const Expr *Ex = dyn_cast<Expr>(S);
+  if (Ex) {
+    Ex = Ex->IgnoreParenLValueCasts();
+    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
+      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+        const VarRegion *R =
+          StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
 
-      if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)
-          || V.isUndef()) {
+        // What did we load?
+        SVal V = state->getSVal(loc::MemRegionVal(R));
+        report->markInteresting(R);
+        report->markInteresting(V);
         return new FindLastStoreBRVisitor(V, R);
       }
     }
@@ -339,7 +342,7 @@ bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
     }
 
     if (R) {
-      assert(isa<SymbolicRegion>(R));
+      report->markInteresting(R);
       return new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
     }
   }
@@ -386,7 +389,7 @@ PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
   // The receiver was nil, and hence the method was skipped.
   // Register a BugReporterVisitor to issue a message telling us how
   // the receiver was null.
-  BR.addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Receiver));
+  BR.addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Receiver, &BR));
   // Issue a message saying that the method was skipped.
   PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
                                      N->getLocationContext());
@@ -439,7 +442,7 @@ PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
   PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
   if (PathDiagnosticEventPiece *ev =
       dyn_cast_or_null<PathDiagnosticEventPiece>(piece))
-    ev->setPrunable(true);
+    ev->setPrunable(true, /* override */ false);
   return piece;
 }
 
@@ -465,7 +468,7 @@ PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
   if (const BlockEdge *BE = dyn_cast<BlockEdge>(&progPoint)) {
     const CFGBlock *srcBlk = BE->getSrc();    
     if (const Stmt *term = srcBlk->getTerminator())
-      return VisitTerminator(term, N, srcBlk, BE->getDst(), BRC);
+      return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
     return 0;
   }
   
@@ -479,10 +482,10 @@ PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
     const ProgramPointTag *tag = PS->getTag();
     if (tag == tags.first)
       return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
-                           BRC, N->getLocationContext());
+                           BRC, BR, N);
     if (tag == tags.second)
       return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
-                           BRC, N->getLocationContext());
+                           BRC, BR, N);
                            
     return 0;
   }
@@ -495,6 +498,7 @@ ConditionBRVisitor::VisitTerminator(const Stmt *Term,
                                     const ExplodedNode *N,
                                     const CFGBlock *srcBlk,
                                     const CFGBlock *dstBlk,
+                                    BugReport &R,
                                     BugReporterContext &BRC) {
   const Expr *Cond = 0;
   
@@ -513,14 +517,15 @@ ConditionBRVisitor::VisitTerminator(const Stmt *Term,
   assert(srcBlk->succ_size() == 2);
   const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
   return VisitTrueTest(Cond->IgnoreParenNoopCasts(BRC.getASTContext()),
-                       tookTrue, BRC, N->getLocationContext());
+                       tookTrue, BRC, R, N);
 }
 
 PathDiagnosticPiece *
 ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
                                   bool tookTrue,
                                   BugReporterContext &BRC,
-                                  const LocationContext *LC) {
+                                  BugReport &R,
+                                  const ExplodedNode *N) {
   
   const Expr *Ex = Cond;
   
@@ -530,9 +535,11 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
       default:
         return 0;
       case Stmt::BinaryOperatorClass:
-        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC, LC);
+        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
+                             R, N);
       case Stmt::DeclRefExprClass:
-        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC, LC);
+        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
+                             R, N);
       case Stmt::UnaryOperatorClass: {
         const UnaryOperator *UO = cast<UnaryOperator>(Ex);
         if (UO->getOpcode() == UO_LNot) {
@@ -547,14 +554,31 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
 }
 
 bool ConditionBRVisitor::patternMatch(const Expr *Ex, llvm::raw_ostream &Out,
-                                      BugReporterContext &BRC) {
+                                      BugReporterContext &BRC,
+                                      BugReport &report,
+                                      const ExplodedNode *N,
+                                      llvm::Optional<bool> &prunable) {
   const Expr *OriginalExpr = Ex;
   Ex = Ex->IgnoreParenCasts();
 
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
     const bool quotes = isa<VarDecl>(DR->getDecl());
-    if (quotes)
+    if (quotes) {
       Out << '\'';
+      const LocationContext *LCtx = N->getLocationContext();
+      const ProgramState *state = N->getState().getPtr();
+      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
+                                                LCtx).getAsRegion()) {
+        if (report.isInteresting(R))
+          prunable = false;
+        else {
+          const ProgramState *state = N->getState().getPtr();
+          SVal V = state->getSVal(R);
+          if (report.isInteresting(V))
+            prunable = false;
+        }
+      }
+    }
     Out << DR->getDecl()->getDeclName().getAsString();
     if (quotes)
       Out << '\'';
@@ -588,15 +612,19 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
                                   const BinaryOperator *BExpr,
                                   const bool tookTrue,
                                   BugReporterContext &BRC,
-                                  const LocationContext *LC) {
+                                  BugReport &R,
+                                  const ExplodedNode *N) {
   
   bool shouldInvert = false;
+  llvm::Optional<bool> shouldPrune;
   
   SmallString<128> LhsString, RhsString;
   {
-    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);  
-    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC);
-    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC);
+    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
+    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
+                                       shouldPrune);
+    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
+                                       shouldPrune);
     
     shouldInvert = !isVarLHS && isVarRHS;    
   }
@@ -607,7 +635,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
     // For assignment operators, all that we care about is that the LHS
     // evaluates to "true" or "false".
     return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
-                                  BRC, LC);
+                                  BRC, R, N);
   }
 
   // For non-assignment operations, we require that we can understand
@@ -655,9 +683,13 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
   }
   
   Out << (shouldInvert ? LhsString : RhsString);
-
-  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LC);
-  return new PathDiagnosticEventPiece(Loc, Out.str());
+  const LocationContext *LCtx = N->getLocationContext();
+  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
+  PathDiagnosticEventPiece *event =
+    new PathDiagnosticEventPiece(Loc, Out.str());
+  if (shouldPrune.hasValue())
+    event->setPrunable(shouldPrune.getValue());
+  return event;
 }
 
 PathDiagnosticPiece *
@@ -665,7 +697,8 @@ ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
                                            const Expr *CondVarExpr,
                                            const bool tookTrue,
                                            BugReporterContext &BRC,
-                                           const LocationContext *LC) {
+                                           BugReport &report,
+                                           const ExplodedNode *N) {
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
   Out << "Assuming " << LhsString << " is ";
@@ -683,8 +716,22 @@ ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
   else
     return 0;
 
-  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LC);
-  return new PathDiagnosticEventPiece(Loc, Out.str());
+  const LocationContext *LCtx = N->getLocationContext();
+  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
+  PathDiagnosticEventPiece *event =
+    new PathDiagnosticEventPiece(Loc, Out.str());
+
+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+      const ProgramState *state = N->getState().getPtr();
+      if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
+        if (report.isInteresting(R))
+          event->setPrunable(false);
+      }
+    }
+  }
+  
+  return event;
 }
   
 PathDiagnosticPiece *
@@ -692,7 +739,8 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
                                   const DeclRefExpr *DR,
                                   const bool tookTrue,
                                   BugReporterContext &BRC,
-                                  const LocationContext *LC) {
+                                  BugReport &report,
+                                  const ExplodedNode *N) {
 
   const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
   if (!VD)
@@ -716,7 +764,21 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
   else
     return 0;
   
-  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LC);
-  return new PathDiagnosticEventPiece(Loc, Out.str());
+  const LocationContext *LCtx = N->getLocationContext();
+  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
+  PathDiagnosticEventPiece *event =
+    new PathDiagnosticEventPiece(Loc, Out.str());
+  
+  const ProgramState *state = N->getState().getPtr();
+  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
+    if (report.isInteresting(R))
+      event->setPrunable(false);
+    else {
+      SVal V = state->getSVal(R);
+      if (report.isInteresting(V))
+        event->setPrunable(false);
+    }
+  }
+  return event;
 }
 
index ceb444361c83eb7f6e44c80786cc29f0194a2de1..9d71d714fb0ae041ddaefce316a1040037168299 100644 (file)
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-output=plist -o - %s | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-output=plist -o %t %s
+// RUN: FileCheck --input-file %t %s
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
@@ -23,6 +24,8 @@ void reallocDiagnostics() {
     char * buf = malloc(100);
     char * tmp;
     tmp = (char*)realloc(buf, 0x1000000);
+    // FIXME: we need a diagnostic for the null check.
+    // This requires propagating "interesting" for 'tmp'.
     if (!tmp) {
         return;// expected-warning {{leak}}
     }
@@ -30,8 +33,20 @@ void reallocDiagnostics() {
     free(buf);
 }
 
+void *wrapper() {
+  void *x = malloc(100);
+  // This is intentionally done to test diagnostic emission.
+  if (x)
+    return x;
+  return 0;
+}
+
+void test_wrapper() {
+  void *buf = wrapper();
+  (void) buf;
+}
+
 // CHECK: <?xml version="1.0" encoding="UTF-8"?>
-// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 // CHECK: <plist version="1.0">
 // CHECK: <dict>
 // CHECK:  <key>files</key>
@@ -50,12 +65,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -63,12 +78,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -77,34 +92,6 @@ void reallocDiagnostics() {
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
-// CHECK:      <key>kind</key><string>event</string>
-// CHECK:      <key>location</key>
-// CHECK:      <dict>
-// CHECK:       <key>line</key><integer>9</integer>
-// CHECK:       <key>col</key><integer>9</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>9</integer>
-// CHECK:          <key>col</key><integer>9</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:         <dict>
-// CHECK:          <key>line</key><integer>9</integer>
-// CHECK:          <key>col</key><integer>14</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:        </array>
-// CHECK:      </array>
-// CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;in&apos; is &gt; 5</string>
-// CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;in&apos; is &gt; 5</string>
-// CHECK:     </dict>
-// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -112,12 +99,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -125,12 +112,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -146,12 +133,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -159,12 +146,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>27</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -176,7 +163,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>10</integer>
+// CHECK:       <key>line</key><integer>11</integer>
 // CHECK:       <key>col</key><integer>18</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -184,12 +171,12 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>line</key><integer>11</integer>
 // CHECK:          <key>col</key><integer>18</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>line</key><integer>11</integer>
 // CHECK:          <key>col</key><integer>27</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -208,12 +195,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>11</integer>
 // CHECK:            <key>col</key><integer>27</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -221,12 +208,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>13</integer>
+// CHECK:            <key>line</key><integer>14</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>13</integer>
+// CHECK:            <key>line</key><integer>14</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -238,7 +225,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>13</integer>
+// CHECK:       <key>line</key><integer>14</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -246,12 +233,12 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>13</integer>
+// CHECK:          <key>line</key><integer>14</integer>
 // CHECK:          <key>col</key><integer>5</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>13</integer>
+// CHECK:          <key>line</key><integer>14</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -268,7 +255,7 @@ void reallocDiagnostics() {
 // CHECK:    <key>type</key><string>Memory leak</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>13</integer>
+// CHECK:    <key>line</key><integer>14</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -284,12 +271,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>line</key><integer>18</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>line</key><integer>18</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -297,12 +284,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -318,12 +305,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -331,12 +318,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>30</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -348,7 +335,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>line</key><integer>19</integer>
 // CHECK:       <key>col</key><integer>9</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -356,12 +343,12 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>line</key><integer>19</integer>
 // CHECK:          <key>col</key><integer>9</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>line</key><integer>19</integer>
 // CHECK:          <key>col</key><integer>30</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -380,12 +367,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>30</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -393,12 +380,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>20</integer>
+// CHECK:            <key>line</key><integer>21</integer>
 // CHECK:            <key>col</key><integer>1</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>20</integer>
+// CHECK:            <key>line</key><integer>21</integer>
 // CHECK:            <key>col</key><integer>1</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -410,7 +397,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>20</integer>
+// CHECK:       <key>line</key><integer>21</integer>
 // CHECK:       <key>col</key><integer>1</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -425,7 +412,7 @@ void reallocDiagnostics() {
 // CHECK:    <key>type</key><string>Memory leak</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>20</integer>
+// CHECK:    <key>line</key><integer>21</integer>
 // CHECK:    <key>col</key><integer>1</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -441,12 +428,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -454,12 +441,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>28</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -471,7 +458,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>23</integer>
+// CHECK:       <key>line</key><integer>24</integer>
 // CHECK:       <key>col</key><integer>18</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -479,12 +466,12 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>line</key><integer>24</integer>
 // CHECK:          <key>col</key><integer>18</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>line</key><integer>24</integer>
 // CHECK:          <key>col</key><integer>28</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -503,12 +490,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>28</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -516,12 +503,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -537,12 +524,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -550,12 +537,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>40</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -567,7 +554,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>25</integer>
+// CHECK:       <key>line</key><integer>26</integer>
 // CHECK:       <key>col</key><integer>18</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -575,12 +562,12 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>25</integer>
+// CHECK:          <key>line</key><integer>26</integer>
 // CHECK:          <key>col</key><integer>18</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>25</integer>
+// CHECK:          <key>line</key><integer>26</integer>
 // CHECK:          <key>col</key><integer>40</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -599,12 +586,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>18</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>line</key><integer>26</integer>
 // CHECK:            <key>col</key><integer>40</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -612,12 +599,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -629,7 +616,7 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>26</integer>
+// CHECK:       <key>line</key><integer>29</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -637,12 +624,12 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>26</integer>
+// CHECK:          <key>line</key><integer>29</integer>
 // CHECK:          <key>col</key><integer>5</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>26</integer>
+// CHECK:          <key>line</key><integer>29</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -661,12 +648,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -674,12 +661,12 @@ void reallocDiagnostics() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>9</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>12</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -688,10 +675,44 @@ void reallocDiagnostics() {
 // CHECK:       </array>
 // 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>29</integer>
+// CHECK:            <key>col</key><integer>9</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>12</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>30</integer>
+// CHECK:            <key>col</key><integer>9</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>col</key><integer>14</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>26</integer>
+// CHECK:       <key>line</key><integer>30</integer>
 // CHECK:       <key>col</key><integer>9</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -699,22 +720,36 @@ void reallocDiagnostics() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>26</integer>
+// CHECK:          <key>line</key><integer>30</integer>
 // CHECK:          <key>col</key><integer>9</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>26</integer>
-// CHECK:          <key>col</key><integer>12</integer>
+// CHECK:          <key>line</key><integer>30</integer>
+// CHECK:          <key>col</key><integer>14</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:        </array>
 // CHECK:      </array>
 // CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;tmp&apos; is null</string>
+// CHECK:      <string>Memory is never released; potential memory leak</string>
 // CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;tmp&apos; is null</string>
+// CHECK: <string>Memory is never released; potential memory leak</string>
 // CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK:    <key>category</key><string>Memory Error</string>
+// CHECK:    <key>type</key><string>Memory leak</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>30</integer>
+// CHECK:    <key>col</key><integer>9</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
 // CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
@@ -723,26 +758,26 @@ void reallocDiagnostics() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
-// CHECK:            <key>col</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>26</integer>
-// CHECK:            <key>col</key><integer>12</integer>
+// CHECK:            <key>line</key><integer>45</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>27</integer>
-// CHECK:            <key>col</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>27</integer>
-// CHECK:            <key>col</key><integer>14</integer>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:          </array>
@@ -753,26 +788,340 @@ void reallocDiagnostics() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>27</integer>
-// CHECK:       <key>col</key><integer>9</integer>
+// CHECK:       <key>line</key><integer>45</integer>
+// CHECK:       <key>col</key><integer>15</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>27</integer>
-// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>15</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>27</integer>
-// CHECK:          <key>col</key><integer>14</integer>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>23</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:        </array>
 // CHECK:      </array>
 // CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling &apos;wrapper&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling &apos;wrapper&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>36</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call to &apos;wrapper&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call to &apos;wrapper&apos;</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>36</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>col</key><integer>1</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>37</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>col</key><integer>3</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>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</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>37</integer>
+// CHECK:            <key>col</key><integer>13</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>col</key><integer>23</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>37</integer>
+// CHECK:       <key>col</key><integer>13</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>37</integer>
+// CHECK:          <key>col</key><integer>13</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>37</integer>
+// CHECK:          <key>col</key><integer>23</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Memory is allocated</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Memory is allocated</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>37</integer>
+// CHECK:            <key>col</key><integer>13</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>col</key><integer>23</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>39</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>39</integer>
+// CHECK:            <key>col</key><integer>3</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>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>39</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>39</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>39</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>39</integer>
+// CHECK:            <key>col</key><integer>7</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>39</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>39</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>39</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming &apos;x&apos; is non-null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming &apos;x&apos; is non-null</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>39</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>39</integer>
+// CHECK:            <key>col</key><integer>7</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>40</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>40</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>45</integer>
+// CHECK:       <key>col</key><integer>15</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>45</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>23</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning to &apos;test_wrapper&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning to &apos;test_wrapper&apos;</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>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>23</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>47</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>1</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>47</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>extended_message</key>
 // CHECK:      <string>Memory is never released; potential memory leak</string>
 // CHECK:      <key>message</key>
 // CHECK: <string>Memory is never released; potential memory leak</string>
@@ -783,8 +1132,8 @@ void reallocDiagnostics() {
 // CHECK:    <key>type</key><string>Memory leak</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>27</integer>
-// CHECK:    <key>col</key><integer>9</integer>
+// CHECK:    <key>line</key><integer>47</integer>
+// CHECK:    <key>col</key><integer>1</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
 // CHECK:   </dict>
index d619a7aa3894cf1565d44a767f17970e4b71d312..750c309e06ed26fdfe2fb0b511e2cde217fdd689 100644 (file)
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o %t %s
+// RUN: FileCheck --input-file %t %s
 
 void test_null_init(void) {
   int *p = 0;
@@ -57,7 +58,6 @@ void rdar8331641(int x) {
 }
 
 // CHECK: <?xml version="1.0" encoding="UTF-8"?>
-// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 // CHECK: <plist version="1.0">
 // CHECK: <dict>
 // CHECK:  <key>files</key>
@@ -76,12 +76,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>line</key><integer>5</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>line</key><integer>5</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -89,12 +89,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>line</key><integer>6</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>line</key><integer>6</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -106,7 +106,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>5</integer>
+// CHECK:       <key>line</key><integer>6</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -114,12 +114,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>5</integer>
+// CHECK:          <key>line</key><integer>6</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>5</integer>
+// CHECK:          <key>line</key><integer>6</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -136,7 +136,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>5</integer>
+// CHECK:    <key>line</key><integer>6</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -152,12 +152,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -165,12 +165,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>11</integer>
+// CHECK:            <key>line</key><integer>12</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>11</integer>
+// CHECK:            <key>line</key><integer>12</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -182,7 +182,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>11</integer>
+// CHECK:       <key>line</key><integer>12</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -190,12 +190,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>11</integer>
+// CHECK:          <key>line</key><integer>12</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>11</integer>
+// CHECK:          <key>line</key><integer>12</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -212,7 +212,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>11</integer>
+// CHECK:    <key>line</key><integer>12</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -228,12 +228,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>15</integer>
+// CHECK:            <key>line</key><integer>16</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>15</integer>
+// CHECK:            <key>line</key><integer>16</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -241,12 +241,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>line</key><integer>19</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -258,7 +258,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>line</key><integer>19</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -266,12 +266,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>line</key><integer>19</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>line</key><integer>19</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -288,7 +288,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>18</integer>
+// CHECK:    <key>line</key><integer>19</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -304,12 +304,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -317,12 +317,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -334,7 +334,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>22</integer>
+// CHECK:       <key>line</key><integer>23</integer>
 // CHECK:       <key>col</key><integer>7</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -342,12 +342,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>22</integer>
+// CHECK:          <key>line</key><integer>23</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>22</integer>
+// CHECK:          <key>line</key><integer>23</integer>
 // CHECK:          <key>col</key><integer>8</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -366,12 +366,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -379,12 +379,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>24</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -396,7 +396,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>23</integer>
+// CHECK:       <key>line</key><integer>24</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -404,12 +404,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>line</key><integer>24</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>line</key><integer>24</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -426,7 +426,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>23</integer>
+// CHECK:    <key>line</key><integer>24</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -442,12 +442,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -455,12 +455,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -469,34 +469,6 @@ void rdar8331641(int x) {
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
-// CHECK:      <key>kind</key><string>event</string>
-// CHECK:      <key>location</key>
-// CHECK:      <dict>
-// CHECK:       <key>line</key><integer>28</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>28</integer>
-// CHECK:          <key>col</key><integer>7</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:         <dict>
-// CHECK:          <key>line</key><integer>28</integer>
-// CHECK:          <key>col</key><integer>8</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:        </array>
-// CHECK:      </array>
-// CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;q&apos; is null</string>
-// CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;q&apos; is null</string>
-// CHECK:     </dict>
-// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -504,12 +476,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -517,12 +489,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>30</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>30</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -538,12 +510,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>30</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>30</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -551,12 +523,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>line</key><integer>31</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>line</key><integer>31</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -568,7 +540,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>30</integer>
+// CHECK:       <key>line</key><integer>31</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -576,12 +548,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>30</integer>
+// CHECK:          <key>line</key><integer>31</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>30</integer>
+// CHECK:          <key>line</key><integer>31</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -598,7 +570,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>30</integer>
+// CHECK:    <key>line</key><integer>31</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -614,12 +586,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>line</key><integer>36</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>line</key><integer>36</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -627,12 +599,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>line</key><integer>36</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>line</key><integer>36</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -648,12 +620,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>line</key><integer>36</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>35</integer>
+// CHECK:            <key>line</key><integer>36</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -661,12 +633,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>38</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>38</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -678,7 +650,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>37</integer>
+// CHECK:       <key>line</key><integer>38</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -686,12 +658,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>37</integer>
+// CHECK:          <key>line</key><integer>38</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>37</integer>
+// CHECK:          <key>line</key><integer>38</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -708,7 +680,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>37</integer>
+// CHECK:    <key>line</key><integer>38</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -724,12 +696,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>line</key><integer>53</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>line</key><integer>53</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -737,12 +709,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -758,12 +730,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -771,12 +743,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>23</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>82</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -788,7 +760,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>53</integer>
+// CHECK:       <key>line</key><integer>54</integer>
 // CHECK:       <key>col</key><integer>23</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -796,12 +768,12 @@ void rdar8331641(int x) {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>53</integer>
+// CHECK:          <key>line</key><integer>54</integer>
 // CHECK:          <key>col</key><integer>23</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>53</integer>
+// CHECK:          <key>line</key><integer>54</integer>
 // CHECK:          <key>col</key><integer>82</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -820,12 +792,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>23</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>53</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>82</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -833,12 +805,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -854,12 +826,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -867,12 +839,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -881,34 +853,6 @@ void rdar8331641(int x) {
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
-// CHECK:      <key>kind</key><string>event</string>
-// CHECK:      <key>location</key>
-// CHECK:      <dict>
-// CHECK:       <key>line</key><integer>54</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>54</integer>
-// CHECK:          <key>col</key><integer>7</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:         <dict>
-// CHECK:          <key>line</key><integer>54</integer>
-// CHECK:          <key>col</key><integer>7</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:        </array>
-// CHECK:      </array>
-// CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;x&apos; is 0</string>
-// CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;x&apos; is 0</string>
-// CHECK:     </dict>
-// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -916,12 +860,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>54</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -929,12 +873,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -950,12 +894,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -963,12 +907,12 @@ void rdar8331641(int x) {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>58</integer>
 // CHECK:            <key>col</key><integer>1</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>58</integer>
 // CHECK:            <key>col</key><integer>1</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -980,7 +924,7 @@ void rdar8331641(int x) {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>57</integer>
+// CHECK:       <key>line</key><integer>58</integer>
 // CHECK:       <key>col</key><integer>1</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -995,7 +939,7 @@ void rdar8331641(int x) {
 // CHECK:    <key>type</key><string>Leak</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>57</integer>
+// CHECK:    <key>line</key><integer>58</integer>
 // CHECK:    <key>col</key><integer>1</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
index 691d6e60f23acbd3f625f837570b29481891af1a..375d2342075b5bec0406a50336ec801749fc8e99 100644 (file)
@@ -24,9 +24,10 @@ void test_null_cond(int *p) {
     *p = 0xDEADBEEF;
   }
 }
-
+  
 void test_null_cond_transitive(int *q) {
   if (!q) {
+    // FIXME: we need a diagnostic saying that p is initialized to 0
     int *p = q;
     *p = 0xDEADBEEF;
   }
@@ -80,7 +81,6 @@ int test_cond_assign() {
 @end
 
 // CHECK: <?xml version="1.0" encoding="UTF-8"?>
-// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 // CHECK: <plist version="1.0">
 // CHECK: <dict>
 // CHECK:  <key>files</key>
@@ -492,34 +492,6 @@ int test_cond_assign() {
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
-// CHECK:      <key>kind</key><string>event</string>
-// CHECK:      <key>location</key>
-// CHECK:      <dict>
-// CHECK:       <key>line</key><integer>29</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>29</integer>
-// CHECK:          <key>col</key><integer>7</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:         <dict>
-// CHECK:          <key>line</key><integer>29</integer>
-// CHECK:          <key>col</key><integer>8</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:        </array>
-// CHECK:      </array>
-// CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;q&apos; is null</string>
-// CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;q&apos; is null</string>
-// CHECK:     </dict>
-// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -540,12 +512,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>line</key><integer>31</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>line</key><integer>31</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -561,12 +533,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>line</key><integer>31</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>30</integer>
+// CHECK:            <key>line</key><integer>31</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -574,12 +546,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>31</integer>
+// CHECK:            <key>line</key><integer>32</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>31</integer>
+// CHECK:            <key>line</key><integer>32</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -591,7 +563,7 @@ int test_cond_assign() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>31</integer>
+// CHECK:       <key>line</key><integer>32</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -599,12 +571,12 @@ int test_cond_assign() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>31</integer>
+// CHECK:          <key>line</key><integer>32</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>31</integer>
+// CHECK:          <key>line</key><integer>32</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -621,7 +593,7 @@ int test_cond_assign() {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>31</integer>
+// CHECK:    <key>line</key><integer>32</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -637,12 +609,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -650,12 +622,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -671,12 +643,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -684,12 +656,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>38</integer>
+// CHECK:            <key>line</key><integer>39</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>38</integer>
+// CHECK:            <key>line</key><integer>39</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -701,7 +673,7 @@ int test_cond_assign() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>38</integer>
+// CHECK:       <key>line</key><integer>39</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -709,12 +681,12 @@ int test_cond_assign() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>38</integer>
+// CHECK:          <key>line</key><integer>39</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>38</integer>
+// CHECK:          <key>line</key><integer>39</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -731,7 +703,7 @@ int test_cond_assign() {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>38</integer>
+// CHECK:    <key>line</key><integer>39</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -747,12 +719,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>line</key><integer>44</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>line</key><integer>44</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -760,12 +732,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>line</key><integer>44</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>line</key><integer>44</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -774,34 +746,6 @@ int test_cond_assign() {
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
-// CHECK:      <key>kind</key><string>event</string>
-// CHECK:      <key>location</key>
-// CHECK:      <dict>
-// CHECK:       <key>line</key><integer>43</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>43</integer>
-// CHECK:          <key>col</key><integer>7</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:         <dict>
-// CHECK:          <key>line</key><integer>43</integer>
-// CHECK:          <key>col</key><integer>12</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:        </array>
-// CHECK:      </array>
-// CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;a&apos; is not equal to 0</string>
-// CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;a&apos; is not equal to 0</string>
-// CHECK:     </dict>
-// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -809,12 +753,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>line</key><integer>44</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>line</key><integer>44</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -822,12 +766,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -843,12 +787,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -856,12 +800,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -870,34 +814,6 @@ int test_cond_assign() {
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
-// CHECK:      <key>kind</key><string>event</string>
-// CHECK:      <key>location</key>
-// CHECK:      <dict>
-// CHECK:       <key>line</key><integer>46</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>46</integer>
-// CHECK:          <key>col</key><integer>7</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:         <dict>
-// CHECK:          <key>line</key><integer>46</integer>
-// CHECK:          <key>col</key><integer>12</integer>
-// CHECK:          <key>file</key><integer>0</integer>
-// CHECK:         </dict>
-// CHECK:        </array>
-// CHECK:      </array>
-// CHECK:      <key>extended_message</key>
-// CHECK:      <string>Assuming &apos;b&apos; is equal to 0</string>
-// CHECK:      <key>message</key>
-// CHECK: <string>Assuming &apos;b&apos; is equal to 0</string>
-// CHECK:     </dict>
-// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -905,12 +821,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>line</key><integer>47</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -918,12 +834,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>line</key><integer>50</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>line</key><integer>50</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -939,12 +855,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>line</key><integer>50</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>line</key><integer>50</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -952,12 +868,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>line</key><integer>51</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>line</key><integer>51</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -969,7 +885,7 @@ int test_cond_assign() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>50</integer>
+// CHECK:       <key>line</key><integer>51</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -977,12 +893,12 @@ int test_cond_assign() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>line</key><integer>51</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>line</key><integer>51</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -999,7 +915,7 @@ int test_cond_assign() {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>50</integer>
+// CHECK:    <key>line</key><integer>51</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -1015,12 +931,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>line</key><integer>56</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>line</key><integer>56</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1028,12 +944,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1049,12 +965,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1062,12 +978,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1079,7 +995,7 @@ int test_cond_assign() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>56</integer>
+// CHECK:       <key>line</key><integer>57</integer>
 // CHECK:       <key>col</key><integer>7</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -1087,12 +1003,12 @@ int test_cond_assign() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>line</key><integer>57</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>line</key><integer>57</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -1111,12 +1027,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1124,12 +1040,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>line</key><integer>59</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>line</key><integer>59</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1145,12 +1061,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>line</key><integer>59</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>line</key><integer>59</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1158,12 +1074,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>line</key><integer>59</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>line</key><integer>59</integer>
 // CHECK:            <key>col</key><integer>11</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1175,7 +1091,7 @@ int test_cond_assign() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>58</integer>
+// CHECK:       <key>line</key><integer>59</integer>
 // CHECK:       <key>col</key><integer>10</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -1183,12 +1099,12 @@ int test_cond_assign() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>line</key><integer>59</integer>
 // CHECK:          <key>col</key><integer>11</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>line</key><integer>59</integer>
 // CHECK:          <key>col</key><integer>11</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -1205,7 +1121,7 @@ int test_cond_assign() {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>58</integer>
+// CHECK:    <key>line</key><integer>59</integer>
 // CHECK:    <key>col</key><integer>10</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -1221,12 +1137,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1234,12 +1150,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1255,12 +1171,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1268,12 +1184,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1289,12 +1205,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1302,12 +1218,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>77</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>77</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1323,12 +1239,12 @@ int test_cond_assign() {
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>77</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>77</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1336,12 +1252,12 @@ int test_cond_assign() {
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>77</integer>
+// CHECK:            <key>line</key><integer>78</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>77</integer>
+// CHECK:            <key>line</key><integer>78</integer>
 // CHECK:            <key>col</key><integer>6</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1353,7 +1269,7 @@ int test_cond_assign() {
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>77</integer>
+// CHECK:       <key>line</key><integer>78</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -1361,12 +1277,12 @@ int test_cond_assign() {
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>77</integer>
+// CHECK:          <key>line</key><integer>78</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>77</integer>
+// CHECK:          <key>line</key><integer>78</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -1383,7 +1299,7 @@ int test_cond_assign() {
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>77</integer>
+// CHECK:    <key>line</key><integer>78</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -1392,3 +1308,4 @@ int test_cond_assign() {
 // CHECK: </dict>
 // CHECK: </plist>
 
+