#include "llvm/ADT/ImmutableList.h"
#include "llvm/ADT/ImmutableSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/DenseSet.h"
#include <list>
namespace clang {
/// This class provides an interface through which checkers can create
/// individual bug reports.
class BugReport {
-public:
+public:
class NodeResolver {
virtual void anchor();
public:
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.
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.
// 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) {}
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;
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();
}
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);
#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>
};
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;
const Expr *arg = *I;
R->addRange(arg->getSourceRange());
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
- arg));
+ arg, R));
// Emit the bug report.
C.EmitReport(R);
}
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;
}
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;
}
BugReport *R = new BugReport(*BT, BT->getName(), N);
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetCalleeExpr(N)));
+ bugreporter::GetCalleeExpr(N), R));
C.EmitReport(R);
}
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;
new BugReport(*BT, BT->getName(), N);
R->addRange(receiver->getSourceRange());
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- receiver));
+ receiver,
+ R));
C.EmitReport(R);
}
return;
if (const Expr *receiver = msg.getInstanceReceiver()) {
report->addRange(receiver->getSourceRange());
report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- receiver));
+ receiver,
+ report));
}
C.EmitReport(report);
}
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);
break;
}
}
+ return sourceR;
}
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;
return;
ProgramStateRef state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
ProgramStateRef notNullState, nullState;
llvm::tie(notNullState, nullState) = state->assume(location);
// 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;
}
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: {
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;
}
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;
}
new BugReport(*BT, Msg, N);
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetDenomExpr(N)));
-
+ bugreporter::GetDenomExpr(N), R));
C.EmitReport(R);
}
}
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
BugReport *Report = new BugReport(*BT, os.str(), N);
Report->addVisitor(new SecKeychainBugVisitor(AP.first));
Report->addRange(ArgExpr->getSourceRange());
+ markInteresting(Report, AP);
C.EmitReport(Report);
}
BugReport *Report = new BugReport(*BT, os.str(), N);
Report->addVisitor(new SecKeychainBugVisitor(V));
Report->addRange(ArgExpr->getSourceRange());
+ Report->markInteresting(AS->Region);
C.EmitReport(Report);
}
}
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;
}
"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;
}
BugReport *Report = new BugReport(*BT, os.str(), N, LocUsedForUniqueing);
Report->addVisitor(new SecKeychainBugVisitor(AP.first));
+ markInteresting(Report, AP);
return Report;
}
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);
}
}
BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
+ R->markInteresting(MR);
R->addRange(range);
C.EmitReport(R);
}
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);
}
"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;
"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;
"(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;
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);
}
// 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
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);
}
// 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);
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);
}
}
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);
}
}
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);
}
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;
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;
}
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:
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.
//===----------------------------------------------------------------------===//
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
}
}
+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;
BugReporterVisitor *
bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
- const Stmt *S) {
+ const Stmt *S,
+ BugReport *report) {
if (!S || !N)
return 0;
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);
}
}
}
if (R) {
- assert(isa<SymbolicRegion>(R));
+ report->markInteresting(R);
return new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
}
}
// 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());
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;
}
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;
}
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;
}
const ExplodedNode *N,
const CFGBlock *srcBlk,
const CFGBlock *dstBlk,
+ BugReport &R,
BugReporterContext &BRC) {
const Expr *Cond = 0;
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;
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) {
}
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 << '\'';
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;
}
// 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
}
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 *
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 ";
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 *
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)
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;
}
-// 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);
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}}
}
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>
// 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>
// 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>
// 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 'in' is > 5</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'in' is > 5</string>
-// CHECK: </dict>
-// CHECK: <dict>
// CHECK: <key>kind</key><string>control</string>
// CHECK: <key>edges</key>
// CHECK: <array>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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 'tmp' is null</string>
+// CHECK: <string>Memory is never released; potential memory leak</string>
// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'tmp' 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>
// 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>
// 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 'wrapper'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Calling 'wrapper'</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 'wrapper'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Entered call to 'wrapper'</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 'x' is non-null</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Assuming 'x' 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 'test_wrapper'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Returning to 'test_wrapper'</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>
// 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>
-// 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;
}
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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 'q' is null</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'q' is null</string>
-// CHECK: </dict>
-// CHECK: <dict>
// CHECK: <key>kind</key><string>control</string>
// CHECK: <key>edges</key>
// CHECK: <array>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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 'x' is 0</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'x' is 0</string>
-// CHECK: </dict>
-// CHECK: <dict>
// CHECK: <key>kind</key><string>control</string>
// CHECK: <key>edges</key>
// CHECK: <array>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
*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;
}
@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>
// 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 'q' is null</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'q' is null</string>
-// CHECK: </dict>
-// CHECK: <dict>
// CHECK: <key>kind</key><string>control</string>
// CHECK: <key>edges</key>
// CHECK: <array>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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 'a' is not equal to 0</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'a' is not equal to 0</string>
-// CHECK: </dict>
-// CHECK: <dict>
// CHECK: <key>kind</key><string>control</string>
// CHECK: <key>edges</key>
// CHECK: <array>
// 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>
// 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>
// 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>
// 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>
// 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 'b' is equal to 0</string>
-// CHECK: <key>message</key>
-// CHECK: <string>Assuming 'b' is equal to 0</string>
-// CHECK: </dict>
-// CHECK: <dict>
// CHECK: <key>kind</key><string>control</string>
// CHECK: <key>edges</key>
// CHECK: <array>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// 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>
// CHECK: </dict>
// CHECK: </plist>
+