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