aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/ProgramPoint.h197
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h9
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp30
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp38
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp24
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp36
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp27
21 files changed, 265 insertions, 185 deletions
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 322f0cb523..27d4ff13f0 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -19,6 +19,7 @@
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
@@ -71,9 +72,8 @@ private:
llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
- ProgramPoint();
-
protected:
+ ProgramPoint() {}
ProgramPoint(const void *P,
Kind k,
const LocationContext *l,
@@ -110,6 +110,29 @@ public:
getLocationContext(), tag);
}
+ /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
+ /// is of the desired type.
+ template<typename T>
+ T castAs() const {
+ assert(T::isKind(*this));
+ T t;
+ ProgramPoint& PP = t;
+ PP = *this;
+ return t;
+ }
+
+ /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+ /// this TypeLoc is not of the desired type.
+ template<typename T>
+ Optional<T> getAs() const {
+ if (!T::isKind(*this))
+ return None;
+ T t;
+ ProgramPoint& PP = t;
+ PP = *this;
+ return t;
+ }
+
Kind getKind() const {
unsigned x = Tag.getInt();
x <<= 2;
@@ -184,8 +207,11 @@ public:
return B->empty() ? CFGElement() : B->front();
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockEntranceKind;
+private:
+ friend class ProgramPoint;
+ BlockEntrance() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == BlockEntranceKind;
}
};
@@ -202,8 +228,11 @@ public:
return getBlock()->getTerminator();
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockExitKind;
+private:
+ friend class ProgramPoint;
+ BlockExit() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == BlockExitKind;
}
};
@@ -220,8 +249,12 @@ public:
template <typename T>
const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
+protected:
+ StmtPoint() {}
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &Location) {
+ unsigned k = Location.getKind();
return k >= PreStmtKind && k <= MaxPostStmtKind;
}
};
@@ -235,13 +268,17 @@ public:
const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PreStmtKind;
+private:
+ friend class ProgramPoint;
+ PreStmt() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PreStmtKind;
}
};
class PostStmt : public StmtPoint {
protected:
+ PostStmt() {}
PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
const ProgramPointTag *tag = 0)
: StmtPoint(S, data, k, L, tag) {}
@@ -255,8 +292,10 @@ public:
const ProgramPointTag *tag = 0)
: StmtPoint(S, NULL, PostStmtKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &Location) {
+ unsigned k = Location.getKind();
return k >= MinPostStmtKind && k <= MaxPostStmtKind;
}
};
@@ -268,19 +307,25 @@ public:
const ProgramPointTag *tag = 0)
: PostStmt(S, PostConditionKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostConditionKind;
+private:
+ friend class ProgramPoint;
+ PostCondition() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostConditionKind;
}
};
class LocationCheck : public StmtPoint {
protected:
+ LocationCheck() {}
LocationCheck(const Stmt *S, const LocationContext *L,
ProgramPoint::Kind K, const ProgramPointTag *tag)
: StmtPoint(S, NULL, K, L, tag) {}
- static bool classof(const ProgramPoint *location) {
- unsigned k = location->getKind();
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &location) {
+ unsigned k = location.getKind();
return k == PreLoadKind || k == PreStoreKind;
}
};
@@ -291,8 +336,11 @@ public:
const ProgramPointTag *tag = 0)
: LocationCheck(S, L, PreLoadKind, tag) {}
- static bool classof(const ProgramPoint *location) {
- return location->getKind() == PreLoadKind;
+private:
+ friend class ProgramPoint;
+ PreLoad() {}
+ static bool isKind(const ProgramPoint &location) {
+ return location.getKind() == PreLoadKind;
}
};
@@ -302,8 +350,11 @@ public:
const ProgramPointTag *tag = 0)
: LocationCheck(S, L, PreStoreKind, tag) {}
- static bool classof(const ProgramPoint *location) {
- return location->getKind() == PreStoreKind;
+private:
+ friend class ProgramPoint;
+ PreStore() {}
+ static bool isKind(const ProgramPoint &location) {
+ return location.getKind() == PreStoreKind;
}
};
@@ -313,8 +364,11 @@ public:
const ProgramPointTag *tag = 0)
: PostStmt(S, PostLoadKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLoadKind;
+private:
+ friend class ProgramPoint;
+ PostLoad() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostLoadKind;
}
};
@@ -331,16 +385,18 @@ public:
setData2(Loc);
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostStoreKind;
- }
-
/// \brief Returns the information about the location used in the store,
/// how it was uttered in the code.
const void *getLocationValue() const {
return getData2();
}
+private:
+ friend class ProgramPoint;
+ PostStore() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostStoreKind;
+ }
};
class PostLValue : public PostStmt {
@@ -349,8 +405,11 @@ public:
const ProgramPointTag *tag = 0)
: PostStmt(S, PostLValueKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLValueKind;
+private:
+ friend class ProgramPoint;
+ PostLValue() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostLValueKind;
}
};
@@ -362,8 +421,11 @@ public:
const ProgramPointTag *tag = 0)
: StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PreStmtPurgeDeadSymbolsKind;
+private:
+ friend class ProgramPoint;
+ PreStmtPurgeDeadSymbols() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
}
};
@@ -375,8 +437,11 @@ public:
const ProgramPointTag *tag = 0)
: StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostStmtPurgeDeadSymbolsKind;
+private:
+ friend class ProgramPoint;
+ PostStmtPurgeDeadSymbols() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
}
};
@@ -396,8 +461,11 @@ public:
return static_cast<const CFGBlock*>(getData2());
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockEdgeKind;
+private:
+ friend class ProgramPoint;
+ BlockEdge() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == BlockEdgeKind;
}
};
@@ -407,8 +475,11 @@ public:
const LocationContext *L)
: ProgramPoint(I, PostInitializerKind, L) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == PostInitializerKind;
+private:
+ friend class ProgramPoint;
+ PostInitializer() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostInitializerKind;
}
};
@@ -426,9 +497,13 @@ public:
return SourceLocation::getFromPtrEncoding(getData1());
}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() >= MinImplicitCallKind &&
- Location->getKind() <= MaxImplicitCallKind;
+protected:
+ ImplicitCallPoint() {}
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() >= MinImplicitCallKind &&
+ Location.getKind() <= MaxImplicitCallKind;
}
};
@@ -441,8 +516,11 @@ public:
const LocationContext *L, const ProgramPointTag *Tag = 0)
: ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == PreImplicitCallKind;
+private:
+ friend class ProgramPoint;
+ PreImplicitCall() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PreImplicitCallKind;
}
};
@@ -455,8 +533,11 @@ public:
const LocationContext *L, const ProgramPointTag *Tag = 0)
: ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == PostImplicitCallKind;
+private:
+ friend class ProgramPoint;
+ PostImplicitCall() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostImplicitCallKind;
}
};
@@ -476,8 +557,11 @@ public:
return static_cast<const StackFrameContext *>(getData2());
}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == CallEnterKind;
+private:
+ friend class ProgramPoint;
+ CallEnter() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == CallEnterKind;
}
};
@@ -496,8 +580,11 @@ public:
CallExitBegin(const StackFrameContext *L)
: ProgramPoint(0, CallExitBeginKind, L, 0) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == CallExitBeginKind;
+private:
+ friend class ProgramPoint;
+ CallExitBegin() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == CallExitBeginKind;
}
};
@@ -514,8 +601,11 @@ public:
return static_cast<const StackFrameContext *>(getData1());
}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == CallExitEndKind;
+private:
+ friend class ProgramPoint;
+ CallExitEnd() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == CallExitEndKind;
}
};
@@ -529,8 +619,11 @@ public:
const void *getData() const { return getData1(); }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == EpsilonKind;
+private:
+ friend class ProgramPoint;
+ EpsilonPoint() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == EpsilonKind;
}
};
@@ -544,7 +637,7 @@ public:
virtual StringRef getTagDescription() const = 0;
protected:
- /// Used to implement 'classof' in subclasses.
+ /// Used to implement 'isKind' in subclasses.
const void *getTagKind() { return TagKind; }
private:
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index ce495c9754..cda1366a43 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -185,7 +185,7 @@ public:
/// example, for finding variables that the given symbol was assigned to.
static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
ProgramPoint L = N->getLocation();
- if (const PostStore *PSL = dyn_cast<PostStore>(&L))
+ if (Optional<PostStore> PSL = L.getAs<PostStore>())
return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
return 0;
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 519924d141..82ac3d9ed0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -155,15 +155,10 @@ public:
const ProgramStateRef &getState() const { return State; }
template <typename T>
- const T* getLocationAs() const LLVM_LVALUE_FUNCTION {
- return dyn_cast<T>(&Location);
+ Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
+ return Location.getAs<T>();
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
- template <typename T>
- void getLocationAs() && LLVM_DELETED_FUNCTION;
-#endif
-
static void Profile(llvm::FoldingSetNodeID &ID,
const ProgramPoint &Loc,
const ProgramStateRef &state,
diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
index 0a12854db8..217d467e03 100644
--- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
@@ -60,7 +60,7 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
if (D != P.getLocationContext()->getDecl())
continue;
- if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+ if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
const CFGBlock *CB = BE->getBlock();
reachable.insert(CB);
}
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
index 051d60a33f..312bc749b1 100644
--- a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -44,7 +44,7 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
return;
// Get the index of the accessed element.
- DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+ DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
// Zero index is always in bound, this also passes ElementRegions created for
// pointer casts.
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index d0c4322d50..cc55e9f6ec 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -281,7 +281,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
DefinedOrUnknownSVal Size = Extent.castAs<DefinedOrUnknownSVal>();
// Get the index of the accessed element.
- DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+ DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true);
ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false);
diff --git a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
index 54c32f87e5..579ba9cf80 100644
--- a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
@@ -332,9 +332,9 @@ void IdempotentOperationChecker::checkPostStmt(const BinaryOperator *B,
// Add the ExplodedNode we just visited
BinaryOperatorData &Data = hash[B];
- const Stmt *predStmt
- = cast<StmtPoint>(C.getPredecessor()->getLocation()).getStmt();
-
+ const Stmt *predStmt =
+ C.getPredecessor()->getLocation().castAs<StmtPoint>().getStmt();
+
// Ignore implicit calls to setters.
if (!isa<BinaryOperator>(predStmt))
return;
@@ -582,16 +582,13 @@ IdempotentOperationChecker::pathWasCompletelyAnalyzed(AnalysisDeclContext *AC,
virtual bool visit(const WorkListUnit &U) {
ProgramPoint P = U.getNode()->getLocation();
const CFGBlock *B = 0;
- if (StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
+ if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
B = CBM->getBlock(SP->getStmt());
- }
- else if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+ } else if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
B = BE->getDst();
- }
- else if (BlockEntrance *BEnt = dyn_cast<BlockEntrance>(&P)) {
+ } else if (Optional<BlockEntrance> BEnt = P.getAs<BlockEntrance>()) {
B = BEnt->getBlock();
- }
- else if (BlockExit *BExit = dyn_cast<BlockExit>(&P)) {
+ } else if (Optional<BlockExit> BExit = P.getAs<BlockExit>()) {
B = BExit->getBlock();
}
if (!B)
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index 84cad8295c..2cd4afe718 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -526,9 +526,9 @@ BugReport *MacOSKeychainAPIChecker::
const ExplodedNode *AllocNode = getAllocationNode(N, AP.first, C);
const Stmt *AllocStmt = 0;
ProgramPoint P = AllocNode->getLocation();
- if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+ if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
AllocStmt = Exit->getCalleeContext()->getCallSite();
- else if (clang::PostStmt *PS = dyn_cast<clang::PostStmt>(&P))
+ else if (Optional<clang::PostStmt> PS = P.getAs<clang::PostStmt>())
AllocStmt = PS->getStmt();
if (AllocStmt)
@@ -602,8 +602,8 @@ PathDiagnosticPiece *MacOSKeychainAPIChecker::SecKeychainBugVisitor::VisitNode(
// (!ASPrev && AS) ~ We started tracking symbol in node N, it must be the
// allocation site.
- const CallExpr *CE = cast<CallExpr>(cast<StmtPoint>(N->getLocation())
- .getStmt());
+ const CallExpr *CE =
+ cast<CallExpr>(N->getLocation().castAs<StmtPoint>().getStmt());
const FunctionDecl *funDecl = CE->getDirectCallee();
assert(funDecl && "We do not support indirect function calls as of now.");
StringRef funName = funDecl->getName();
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 38722a2ed5..f412c049c7 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1117,9 +1117,9 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
ProgramPoint P = AllocNode->getLocation();
const Stmt *AllocationStmt = 0;
- if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+ if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
AllocationStmt = Exit->getCalleeContext()->getCallSite();
- else if (StmtPoint *SP = dyn_cast<StmtPoint>(&P))
+ else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
AllocationStmt = SP->getStmt();
if (AllocationStmt)
LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
@@ -1559,11 +1559,11 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
// Retrieve the associated statement.
ProgramPoint ProgLoc = N->getLocation();
- if (StmtPoint *SP = dyn_cast<StmtPoint>(&ProgLoc)) {
+ if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
S = SP->getStmt();
- } else if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&ProgLoc)) {
+ } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) {
S = Exit->getCalleeContext()->getCallSite();
- } else if (BlockEdge *Edge = dyn_cast<BlockEdge>(&ProgLoc)) {
+ } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) {
// If an assumption was made on a branch, it should be caught
// here by looking at the state transition.
S = Edge->getSrc()->getTerminator();
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 69191deec3..65bd033d9a 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1866,7 +1866,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
BugReport &BR) {
// FIXME: We will eventually need to handle non-statement-based events
// (__attribute__((cleanup))).
- if (!isa<StmtPoint>(N->getLocation()))
+ if (!N->getLocation().getAs<StmtPoint>())
return NULL;
// Check if the type state has changed.
@@ -1888,7 +1888,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
// This is the allocation site since the previous node had no bindings
// for this symbol.
if (!PrevT) {
- const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+ const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
if (isa<ObjCArrayLiteral>(S)) {
os << "NSArray literal is an object with a +0 retain count";
@@ -1978,7 +1978,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
if (const RetainSummary *Summ = SummaryLog.lookup(OrigNode)) {
// We only have summaries attached to nodes after evaluating CallExpr and
// ObjCMessageExprs.
- const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+ const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
// Iterate through the parameter expressions and see if the symbol
@@ -2027,7 +2027,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
// Specially handle CFMakeCollectable and friends.
if (contains(AEffects, MakeCollectable)) {
// Get the name of the function.
- const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+ const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
SVal X =
CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee(), LCtx);
const FunctionDecl *FD = X.getAsFunctionDecl();
@@ -2135,7 +2135,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
if (os.str().empty())
return 0; // We have nothing to say!
- const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+ const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str());
@@ -2312,10 +2312,10 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
// implicit call. (Currently there are no such allocations in Cocoa, though.)
const Stmt *AllocStmt;
ProgramPoint P = AllocNode->getLocation();
- if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+ if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
AllocStmt = Exit->getCalleeContext()->getCallSite();
else
- AllocStmt = cast<PostStmt>(P).getStmt();
+ AllocStmt = P.castAs<PostStmt>().getStmt();
assert(AllocStmt && "All allocations must come from explicit calls");
Location = PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
n->getLocationContext());
diff --git a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
index 59df516642..fe253b719b 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -46,7 +46,7 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
if (!ER)
return;
- DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+ DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
// Zero index is always in bound, this also passes ElementRegions created for
// pointer casts.
if (Idx.isZeroConstant())
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 54e40162e4..8235e68937 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -90,7 +90,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
ProgramPoint P = PrevN->getLocation();
ProgramStateRef St = N->getState();
- if (PostStmt *PS = dyn_cast<PostStmt>(&P))
+ if (Optional<PostStmt> PS = P.getAs<PostStmt>())
if (PS->getStmt() == Ex)
St = PrevN->getState();
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index c939d05df4..3b4aa239e0 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -76,7 +76,7 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G,
if (!PM)
PM = &LC->getParentMap();
- if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+ if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
const CFGBlock *CB = BE->getBlock();
reachable.insert(CB->getBlockID());
}
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index d43d525f76..8556089fe3 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -44,13 +44,13 @@ void BugReporterContext::anchor() {}
//===----------------------------------------------------------------------===//
static inline const Stmt *GetStmt(const ProgramPoint &P) {
- if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
+ if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
return SP->getStmt();
- else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+ if (Optional<BlockEdge> BE = P.getAs<BlockEdge>())
return BE->getSrc()->getTerminator();
- else if (const CallEnter *CE = dyn_cast<CallEnter>(&P))
+ if (Optional<CallEnter> CE = P.getAs<CallEnter>())
return CE->getCallExpr();
- else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P))
+ if (Optional<CallExitEnd> CEE = P.getAs<CallExitEnd>())
return CEE->getCalleeContext()->getCallSite();
return 0;
@@ -579,7 +579,7 @@ static bool GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
ProgramPoint P = N->getLocation();
do {
- if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
+ if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
PathDiagnosticCallPiece *C =
PathDiagnosticCallPiece::construct(N, *CE, SMgr);
GRBugReporter& BR = PDB.getBugReporter();
@@ -590,7 +590,7 @@ static bool GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
break;
}
- if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+ if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
// Flush all locations, and pop the active path.
bool VisitedEntireCall = PD.isWithinCall();
PD.popActivePath();
@@ -618,7 +618,7 @@ static bool GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
break;
}
- if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+ if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
const CFGBlock *Src = BE->getSrc();
const CFGBlock *Dst = BE->getDst();
const Stmt *T = Src->getTerminator();
@@ -1334,14 +1334,14 @@ static bool GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
ProgramPoint P = N->getLocation();
do {
- if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+ if (Optional<PostStmt> PS = P.getAs<PostStmt>()) {
if (const Expr *Ex = PS->getStmtAs<Expr>())
reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
N->getState().getPtr(), Ex,
N->getLocationContext());