-//=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
+//===- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ----------===//
//
// The LLVM Compiler Infrastructure
//
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "PrettyStackTraceLocationContext.h"
-#include "clang/AST/CharUnits.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
#include "clang/AST/ParentMap.h"
-#include "clang/Analysis/CFGStmtMap.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
-#include "clang/Basic/Builtins.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/ImmutableSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
-
-#ifndef NDEBUG
-#include "llvm/Support/GraphWriter.h"
-#endif
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
using namespace clang;
using namespace ento;
-using llvm::APSInt;
#define DEBUG_TYPE "ExprEngine"
STATISTIC(NumTimesRetriedWithoutInlining,
"The # of times we re-evaluated a call without inlining");
-typedef llvm::ImmutableMap<std::pair<const CXXBindTemporaryExpr *,
- const StackFrameContext *>,
- const CXXTempObjectRegion *>
- InitializedTemporariesMap;
+using InitializedTemporariesMap =
+ llvm::ImmutableMap<std::pair<const CXXBindTemporaryExpr *,
+ const StackFrameContext *>,
+ const CXXTempObjectRegion *>;
// Keeps track of whether CXXBindTemporaryExpr nodes have been evaluated.
// The StackFrameContext assures that nested calls due to inlined recursive
REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedTemporaries,
InitializedTemporariesMap)
-typedef llvm::ImmutableMap<std::pair<const MaterializeTemporaryExpr *,
- const StackFrameContext *>,
- const CXXTempObjectRegion *>
- TemporaryMaterializationMap;
+using TemporaryMaterializationMap =
+ llvm::ImmutableMap<std::pair<const MaterializeTemporaryExpr *,
+ const StackFrameContext *>,
+ const CXXTempObjectRegion *>;
// Keeps track of temporaries that will need to be materialized later.
// The StackFrameContext assures that nested calls due to inlined recursive
REGISTER_TRAIT_WITH_PROGRAMSTATE(TemporaryMaterializations,
TemporaryMaterializationMap)
-typedef llvm::ImmutableMap<std::pair<const CXXNewExpr *,
- const LocationContext *>,
- SVal>
- CXXNewAllocatorValuesMap;
+using CXXNewAllocatorValuesMap =
+ llvm::ImmutableMap<std::pair<const CXXNewExpr *, const LocationContext *>,
+ SVal>;
// Keeps track of return values of various operator new() calls between
// evaluation of the inlined operator new(), through the constructor call,
static const char* TagProviderName = "ExprEngine";
-ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
- bool gcEnabled, SetOfConstDecls *VisitedCalleesIn,
+ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU,
+ AnalysisManager &mgr, bool gcEnabled,
+ SetOfConstDecls *VisitedCalleesIn,
FunctionSummariesTy *FS,
InliningModes HowToInlineIn)
- : CTU(CTU), AMgr(mgr),
- AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
- Engine(*this, FS, mgr.getAnalyzerOptions()),
- G(Engine.getGraph()),
- StateMgr(getContext(), mgr.getStoreManagerCreator(),
- mgr.getConstraintManagerCreator(), G.getAllocator(),
- this),
- SymMgr(StateMgr.getSymbolManager()),
- svalBuilder(StateMgr.getSValBuilder()),
- currStmtIdx(0), currBldrCtx(nullptr),
- ObjCNoRet(mgr.getASTContext()),
- ObjCGCEnabled(gcEnabled), BR(mgr, *this),
- VisitedCallees(VisitedCalleesIn),
- HowToInline(HowToInlineIn)
-{
+ : CTU(CTU), AMgr(mgr),
+ AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
+ Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
+ StateMgr(getContext(), mgr.getStoreManagerCreator(),
+ mgr.getConstraintManagerCreator(), G.getAllocator(),
+ this),
+ SymMgr(StateMgr.getSymbolManager()),
+ svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
+ ObjCGCEnabled(gcEnabled), BR(mgr, *this),
+ VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) {
unsigned TrimInterval = mgr.options.getGraphTrimInterval();
if (TrimInterval != 0) {
// Enable eager node reclaimation when constructing the ExplodedGraph.
// FIXME: It would be nice if we had a more general mechanism to add
// such preconditions. Some day.
do {
-
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// Precondition: the first argument of 'main' is an integer guaranteed
// to be > 0.
const IdentifierInfo *II = FD->getIdentifier();
const ParmVarDecl *PD = FD->getParamDecl(0);
QualType T = PD->getType();
- const BuiltinType *BT = dyn_cast<BuiltinType>(T);
+ const auto *BT = dyn_cast<BuiltinType>(T);
if (!BT || !BT->isInteger())
break;
}
break;
}
- while (0);
+ while (false);
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
// Precondition: 'self' is always non-null upon entry to an Objective-C
// method.
const ImplicitParamDecl *SelfD = MD->getSelfDecl();
}
}
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
if (!MD->isStatic()) {
// Precondition: 'this' is always non-null upon entry to the
// top-level function. This is our starting assumption for
// into that region. This is not correct, but it is better than nothing.
bool FoundOriginalMaterializationRegion = false;
const TypedValueRegion *TR = nullptr;
- if (const MaterializeTemporaryExpr *MT =
- dyn_cast<MaterializeTemporaryExpr>(Result)) {
+ if (const auto *MT = dyn_cast<MaterializeTemporaryExpr>(Result)) {
auto Key = std::make_pair(MT, LC->getCurrentStackFrame());
if (const CXXTempObjectRegion *const *TRPtr =
State->get<TemporaryMaterializations>(Key)) {
const Stmt *S,
const ExplodedNode *Pred,
const LocationContext *LC) {
-
// Are we never purging state values?
if (AMgr.options.AnalysisPurgeOpt == PurgeNone)
return false;
// environment, the store, and the constraints cleaned up but have the
// user-supplied states as the predecessors.
StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx);
- for (ExplodedNodeSet::const_iterator
- I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
- ProgramStateRef CheckerState = (*I)->getState();
+ for (const auto I : CheckedSet) {
+ ProgramStateRef CheckerState = I->getState();
// The constraint manager has not been cleaned up yet, so clean up now.
CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
// generate a transition to that state.
ProgramStateRef CleanedCheckerSt =
StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
- Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K);
+ Bldr.generateNode(DiagnosticStmt, I, CleanedCheckerSt, &cleanupTag, K);
}
}
}
// Visit the statement.
ExplodedNodeSet Dst;
- for (ExplodedNodeSet::iterator I = CleanedStates.begin(),
- E = CleanedStates.end(); I != E; ++I) {
+ for (const auto I : CleanedStates) {
ExplodedNodeSet DstI;
// Visit the statement.
- Visit(currStmt, *I, DstI);
+ Visit(currStmt, I, DstI);
Dst.insert(DstI);
}
"Error evaluating initializer");
// We don't clean up dead bindings here.
- const StackFrameContext *stackFrame =
- cast<StackFrameContext>(Pred->getLocationContext());
- const CXXConstructorDecl *decl =
- cast<CXXConstructorDecl>(stackFrame->getDecl());
+ const auto *stackFrame = cast<StackFrameContext>(Pred->getLocationContext());
+ const auto *decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
ProgramStateRef State = Pred->getState();
SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame));
if (BMI->isAnyMemberInitializer()) {
// Constructors build the object directly in the field,
// but non-objects must be copied in from the initializer.
- if (auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
+ if (const auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
assert(BMI->getInit()->IgnoreImplicit() == CtorExpr);
(void)CtorExpr;
// The field was directly constructed, so there is no need to bind.
PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame);
ExplodedNodeSet Dst;
NodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
- for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
- ExplodedNode *N = *I;
- Bldr.generateNode(PP, N->getState(), N);
- }
+ for (const auto I : Tmp)
+ Bldr.generateNode(PP, I->getState(), I);
// Enqueue the new nodes onto the work list.
Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
const LocationContext *LCtx = Pred->getLocationContext();
- const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
+ const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
LCtx->getCurrentStackFrame());
SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
ProgramStateRef State = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
- const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
+ const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
LCtx->getCurrentStackFrame());
SVal FieldVal =
}
namespace {
+
class CollectReachableSymbolsCallback final : public SymbolVisitor {
InvalidatedSymbols Symbols;
public:
explicit CollectReachableSymbolsCallback(ProgramStateRef State) {}
+
const InvalidatedSymbols &getSymbols() const { return Symbols; }
bool VisitSymbol(SymbolRef Sym) override {
return true;
}
};
-} // end anonymous namespace
+
+} // namespace
void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet &DstTop) {
case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
- case Stmt::CapturedStmtClass:
- {
+ case Stmt::CapturedStmtClass: {
const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
Engine.addAbortedBlock(node, currBldrCtx->getBlock());
break;
StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
const Expr *ArgE;
- if (const CXXDefaultArgExpr *DefE = dyn_cast<CXXDefaultArgExpr>(S))
+ if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
ArgE = DefE->getExpr();
- else if (const CXXDefaultInitExpr *DefE = dyn_cast<CXXDefaultInitExpr>(S))
+ else if (const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
ArgE = DefE->getExpr();
else
llvm_unreachable("unknown constant wrapper kind");
bool IsTemporary = false;
- if (const MaterializeTemporaryExpr *MTE =
- dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
+ if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
ArgE = MTE->GetTemporaryExpr();
IsTemporary = true;
}
ConstantVal = UnknownVal();
const LocationContext *LCtx = Pred->getLocationContext();
- for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end();
- I != E; ++I) {
- ProgramStateRef State = (*I)->getState();
+ for (const auto I : PreVisit) {
+ ProgramStateRef State = I->getState();
State = State->BindExpr(S, LCtx, *ConstantVal);
if (IsTemporary)
State = createTemporaryRegionIfNeeded(State, LCtx,
cast<Expr>(S),
cast<Expr>(S));
- Bldr2.generateNode(S, *I, State);
+ Bldr2.generateNode(S, I, State);
}
getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
ExplodedNodeSet Tmp;
StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
- const Expr *Ex = cast<Expr>(S);
+ const auto *Ex = cast<Expr>(S);
QualType resultType = Ex->getType();
- for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end();
- it != et; ++it) {
- ExplodedNode *N = *it;
+ for (const auto N : preVisit) {
const LocationContext *LCtx = N->getLocationContext();
SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
resultType,
break;
case Stmt::BinaryOperatorClass: {
- const BinaryOperator* B = cast<BinaryOperator>(S);
+ const auto *B = cast<BinaryOperator>(S);
if (B->isLogicalOp()) {
Bldr.takeNodes(Pred);
VisitLogicalExpr(B, Pred, Dst);
}
case Stmt::CXXOperatorCallExprClass: {
- const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S);
+ const auto *OCE = cast<CXXOperatorCallExpr>(S);
// For instance method operators, make sure the 'this' argument has a
// valid region.
const Decl *Callee = OCE->getCalleeDecl();
- if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
+ if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
if (MD->isInstance()) {
ProgramStateRef State = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
// FALLTHROUGH
LLVM_FALLTHROUGH;
}
+
case Stmt::CallExprClass:
case Stmt::CXXMemberCallExprClass:
- case Stmt::UserDefinedLiteralClass: {
+ case Stmt::UserDefinedLiteralClass:
Bldr.takeNodes(Pred);
VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
Bldr.addNodes(Dst);
break;
- }
- case Stmt::CXXCatchStmtClass: {
+ case Stmt::CXXCatchStmtClass:
Bldr.takeNodes(Pred);
VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
Bldr.addNodes(Dst);
break;
- }
case Stmt::CXXTemporaryObjectExprClass:
- case Stmt::CXXConstructExprClass: {
+ case Stmt::CXXConstructExprClass:
Bldr.takeNodes(Pred);
VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
Bldr.addNodes(Dst);
break;
- }
case Stmt::CXXNewExprClass: {
Bldr.takeNodes(Pred);
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
ExplodedNodeSet PostVisit;
- for (ExplodedNodeSet::iterator i = PreVisit.begin(),
- e = PreVisit.end(); i != e ; ++i) {
- VisitCXXNewExpr(cast<CXXNewExpr>(S), *i, PostVisit);
- }
+ for (const auto i : PreVisit)
+ VisitCXXNewExpr(cast<CXXNewExpr>(S), i, PostVisit);
getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
Bldr.addNodes(Dst);
case Stmt::CXXDeleteExprClass: {
Bldr.takeNodes(Pred);
ExplodedNodeSet PreVisit;
- const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
+ const auto *CDE = cast<CXXDeleteExpr>(S);
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
- for (ExplodedNodeSet::iterator i = PreVisit.begin(),
- e = PreVisit.end(); i != e ; ++i)
- VisitCXXDeleteExpr(CDE, *i, Dst);
+ for (const auto i : PreVisit)
+ VisitCXXDeleteExpr(CDE, i, Dst);
Bldr.addNodes(Dst);
break;
case Stmt::ChooseExprClass: { // __builtin_choose_expr
Bldr.takeNodes(Pred);
- const ChooseExpr *C = cast<ChooseExpr>(S);
+ const auto *C = cast<ChooseExpr>(S);
VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
Bldr.addNodes(Dst);
break;
case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass: { // '?' operator
Bldr.takeNodes(Pred);
- const AbstractConditionalOperator *C
- = cast<AbstractConditionalOperator>(S);
+ const auto *C = cast<AbstractConditionalOperator>(S);
VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
Bldr.addNodes(Dst);
break;
case Stmt::DeclRefExprClass: {
Bldr.takeNodes(Pred);
- const DeclRefExpr *DE = cast<DeclRefExpr>(S);
+ const auto *DE = cast<DeclRefExpr>(S);
VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
Bldr.addNodes(Dst);
break;
case Stmt::CXXFunctionalCastExprClass:
case Stmt::ObjCBridgedCastExprClass: {
Bldr.takeNodes(Pred);
- const CastExpr *C = cast<CastExpr>(S);
+ const auto *C = cast<CastExpr>(S);
ExplodedNodeSet dstExpr;
VisitCast(C, C->getSubExpr(), Pred, dstExpr);
case Expr::MaterializeTemporaryExprClass: {
Bldr.takeNodes(Pred);
- const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S);
+ const auto *MTE = cast<MaterializeTemporaryExpr>(S);
ExplodedNodeSet dstPrevisit;
getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
ExplodedNodeSet dstExpr;
- for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
- e = dstPrevisit.end(); i != e ; ++i) {
- CreateCXXTemporaryObject(MTE, *i, dstExpr);
- }
+ for (const auto i : dstPrevisit)
+ CreateCXXTemporaryObject(MTE, i, dstExpr);
getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
Bldr.addNodes(Dst);
break;
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
ExplodedNodeSet PostVisit;
- for (ExplodedNode *Node : PreVisit)
+ for (const auto Node : PreVisit)
VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
Bldr.addNodes(Dst);
break;
}
+
case Stmt::UnaryExprOrTypeTraitExprClass:
Bldr.takeNodes(Pred);
VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
break;
case Stmt::StmtExprClass: {
- const StmtExpr *SE = cast<StmtExpr>(S);
+ const auto *SE = cast<StmtExpr>(S);
if (SE->getSubStmt()->body_empty()) {
// Empty statement expression.
break;
}
- if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
+ if (const auto *LastExpr =
+ dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
ProgramStateRef state = Pred->getState();
Bldr.generateNode(SE, Pred,
state->BindExpr(SE, Pred->getLocationContext(),
case Stmt::UnaryOperatorClass: {
Bldr.takeNodes(Pred);
- const UnaryOperator *U = cast<UnaryOperator>(S);
+ const auto *U = cast<UnaryOperator>(S);
if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) {
ExplodedNodeSet Tmp;
VisitUnaryOperator(U, Pred, Tmp);
case Stmt::PseudoObjectExprClass: {
Bldr.takeNodes(Pred);
ProgramStateRef state = Pred->getState();
- const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
+ const auto *PE = cast<PseudoObjectExpr>(S);
if (const Expr *Result = PE->getResultExpr()) {
SVal V = state->getSVal(Result, Pred->getLocationContext());
Bldr.generateNode(S, Pred,
const LocationContext *LCtx,
ASTContext &Ctx) {
- const Expr *Ex = dyn_cast<Expr>(Condition);
+ const auto *Ex = dyn_cast<Expr>(Condition);
if (!Ex)
return UnknownVal();
uint64_t bits = 0;
bool bitsInit = false;
- while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
+ while (const auto *CE = dyn_cast<CastExpr>(Ex)) {
QualType T = CE->getType();
if (!T->isIntegralOrEnumerationType())
#ifndef NDEBUG
static const Stmt *getRightmostLeaf(const Stmt *Condition) {
while (Condition) {
- const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition);
+ const auto *BO = dyn_cast<BinaryOperator>(Condition);
if (!BO || !BO->isLogicalOp()) {
return Condition;
}
// space.
static const Stmt *ResolveCondition(const Stmt *Condition,
const CFGBlock *B) {
- if (const Expr *Ex = dyn_cast<Expr>(Condition))
+ if (const auto *Ex = dyn_cast<Expr>(Condition))
Condition = Ex->IgnoreParens();
- const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition);
+ const auto *BO = dyn_cast<BinaryOperator>(Condition);
if (!BO || !BO->isLogicalOp())
return Condition;
return;
}
- if (const Expr *Ex = dyn_cast<Expr>(Condition))
+ if (const auto *Ex = dyn_cast<Expr>(Condition))
Condition = Ex->IgnoreParens();
Condition = ResolveCondition(Condition, BldCtx.getBlock());
return;
BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
- for (NodeBuilder::iterator I = CheckersOutSet.begin(),
- E = CheckersOutSet.end(); E != I; ++I) {
- ExplodedNode *PredI = *I;
-
+ for (const auto PredI : CheckersOutSet) {
if (PredI->isSink())
continue;
if (X.isUnknownOrUndef()) {
// Give it a chance to recover from unknown.
- if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
+ if (const auto *Ex = dyn_cast<Expr>(Condition)) {
if (Ex->getType()->isIntegralOrEnumerationType()) {
// Try to recover some path-sensitivity. Right now casts of symbolic
// integers that promote their values are currently not tracked well.
void ExprEngine::processStaticInitializer(const DeclStmt *DS,
NodeBuilderContext &BuilderCtx,
ExplodedNode *Pred,
- clang::ento::ExplodedNodeSet &Dst,
+ ExplodedNodeSet &Dst,
const CFGBlock *DstT,
const CFGBlock *DstF) {
PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
currBldrCtx = &BuilderCtx;
- const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
+ const auto *VD = cast<VarDecl>(DS->getSingleDecl());
ProgramStateRef state = Pred->getState();
bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF);
/// processIndirectGoto - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a computed goto jump.
void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
-
ProgramStateRef state = builder.getState();
SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
// (3) We have no clue about the label. Dispatch to all targets.
//
- typedef IndirectGotoNodeBuilder::iterator iterator;
+ using iterator = IndirectGotoNodeBuilder::iterator;
if (Optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) {
const LabelDecl *L = LV->getLabel();
// This is really a catch-all. We don't support symbolics yet.
// FIXME: Implement dispatch for symbolic pointers.
- for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
+ for (iterator I = builder.begin(), E = builder.end(); I != E; ++I)
builder.generateNode(I, state);
}
removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead);
// Notify checkers.
- for (ExplodedNodeSet::iterator I = AfterRemovedDead.begin(),
- E = AfterRemovedDead.end(); I != E; ++I) {
- getCheckerManager().runCheckersForEndFunction(BC, Dst, *I, *this);
- }
+ for (const auto I : AfterRemovedDead)
+ getCheckerManager().runCheckersForEndFunction(BC, Dst, I, *this);
} else {
getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this);
}
/// ProcessSwitch - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a switch statement.
void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
- typedef SwitchNodeBuilder::iterator iterator;
+ using iterator = SwitchNodeBuilder::iterator;
+
ProgramStateRef state = builder.getState();
const Expr *CondE = builder.getCondition();
SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext());
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
// C permits "extern void v", and if you cast the address to a valid type,
// you can even do things with it. We simply pretend
assert(Ex->isGLValue() || VD->getType()->isVoidType());
ProgramPoint::PostLValueKind);
return;
}
- if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
+ if (const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
assert(!Ex->isGLValue());
SVal V = svalBuilder.makeIntVal(ED->getInitVal());
Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
return;
}
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
SVal V = svalBuilder.getFunctionPointer(FD);
Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
ProgramPoint::PostLValueKind);
/// VisitMemberExpr - Transfer function for member expressions.
void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
-
// FIXME: Prechecks eventually go in ::Visit().
ExplodedNodeSet CheckedSet;
getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, M, *this);
// Handle static member variables and enum constants accessed via
// member syntax.
if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
- for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
- I != E; ++I) {
- VisitCommonDeclRefExpr(M, Member, *I, EvalSet);
- }
+ for (const auto I : CheckedSet)
+ VisitCommonDeclRefExpr(M, Member, I, EvalSet);
} else {
StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
ExplodedNodeSet Tmp;
- for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
- I != E; ++I) {
- ProgramStateRef state = (*I)->getState();
- const LocationContext *LCtx = (*I)->getLocationContext();
+ for (const auto I : CheckedSet) {
+ ProgramStateRef state = I->getState();
+ const LocationContext *LCtx = I->getLocationContext();
Expr *BaseExpr = M->getBase();
// Handle C++ method calls.
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(Member)) {
if (MD->isInstance())
state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
SVal MDVal = svalBuilder.getFunctionPointer(MD);
state = state->BindExpr(M, LCtx, MDVal);
- Bldr.generateNode(M, *I, state);
+ Bldr.generateNode(M, I, state);
continue;
}
state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
- FieldDecl *field = cast<FieldDecl>(Member);
+ const auto *field = cast<FieldDecl>(Member);
SVal L = state->getLValue(field, baseExprVal);
if (M->isGLValue() || M->getType()->isArrayType()) {
// pointers as soon as they are used.
if (!M->isGLValue()) {
assert(M->getType()->isArrayType());
- const ImplicitCastExpr *PE =
- dyn_cast<ImplicitCastExpr>((*I)->getParentMap().getParentIgnoreParens(M));
+ const auto *PE =
+ dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
llvm_unreachable("should always be wrapped in ArrayToPointerDecay");
}
L = UnknownVal();
}
- Bldr.generateNode(M, *I, state->BindExpr(M, LCtx, L), nullptr,
+ Bldr.generateNode(M, I, state->BindExpr(M, LCtx, L), nullptr,
ProgramPoint::PostLValueKind);
} else {
- Bldr.takeNodes(*I);
- evalLoad(Tmp, M, M, *I, state, L);
+ Bldr.takeNodes(I);
+ evalLoad(Tmp, M, M, I, state, L);
Bldr.addNodes(Tmp);
}
}
ExplodedNodeSet AfterInvalidateSet;
StmtNodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx);
- for (ExplodedNodeSet::iterator I = AfterPreSet.begin(), E = AfterPreSet.end();
- I != E; ++I) {
- ProgramStateRef State = (*I)->getState();
- const LocationContext *LCtx = (*I)->getLocationContext();
+ for (const auto I : AfterPreSet) {
+ ProgramStateRef State = I->getState();
+ const LocationContext *LCtx = I->getLocationContext();
SmallVector<SVal, 8> ValuesToInvalidate;
for (unsigned SI = 0, Count = AE->getNumSubExprs(); SI != Count; SI++) {
SVal ResultVal = UnknownVal();
State = State->BindExpr(AE, LCtx, ResultVal);
- Bldr.generateNode(AE, *I, State, nullptr,
+ Bldr.generateNode(AE, I, State, nullptr,
ProgramPoint::PostStmtKind);
}
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &ITraits) {
-
if (!Invalidated || Invalidated->empty())
return State;
// If the symbols were invalidated by a call, we want to find out which ones
// were invalidated directly due to being arguments to the call.
InvalidatedSymbols SymbolsDirectlyInvalidated;
- for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
- E = ExplicitRegions.end(); I != E; ++I) {
- if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>())
+ for (const auto I : ExplicitRegions) {
+ if (const SymbolicRegion *R = I->StripCasts()->getAs<SymbolicRegion>())
SymbolsDirectlyInvalidated.insert(R->getSymbol());
}
InvalidatedSymbols SymbolsIndirectlyInvalidated;
- for (InvalidatedSymbols::const_iterator I=Invalidated->begin(),
- E = Invalidated->end(); I!=E; ++I) {
- SymbolRef sym = *I;
+ for (const auto &sym : *Invalidated) {
if (SymbolsDirectlyInvalidated.count(sym))
continue;
SymbolsIndirectlyInvalidated.insert(sym);
ExplodedNode *Pred,
SVal location, SVal Val,
bool atDeclInit, const ProgramPoint *PP) {
-
const LocationContext *LC = Pred->getLocationContext();
PostStmt PS(StoreE, LC);
if (!PP)
return;
}
- for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
- I!=E; ++I) {
- ExplodedNode *PredI = *I;
+ for (const auto PredI : CheckedSet) {
ProgramStateRef state = PredI->getState();
state = processPointerEscapedOnBind(state, location, Val, LC);
if (location.isUndef())
return;
- for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
- evalBind(Dst, StoreE, *NI, location, Val, false);
+ for (const auto I : Tmp)
+ evalBind(Dst, StoreE, I, location, Val, false);
}
void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
ProgramStateRef state,
SVal location,
const ProgramPointTag *tag,
- QualType LoadTy)
-{
+ QualType LoadTy) {
assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc.");
// Are we loading from a region? This actually results in two loads; one
// to fetch the address of the referenced value and one to fetch the
// referenced value.
- if (const TypedValueRegion *TR =
+ if (const auto *TR =
dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
QualType ValTy = TR->getValueType();
getContext().getPointerType(RT->getPointeeType()));
// Perform the load from the referenced value.
- for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
- state = (*I)->getState();
- location = state->getSVal(BoundEx, (*I)->getLocationContext());
- evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy);
+ for (const auto I : Tmp) {
+ state = I->getState();
+ location = state->getSVal(BoundEx, I->getLocationContext());
+ evalLoadCommon(Dst, NodeEx, BoundEx, I, state, location, tag, LoadTy);
}
return;
}
return;
// Proceed with the load.
- for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
- state = (*NI)->getState();
- const LocationContext *LCtx = (*NI)->getLocationContext();
+ for (const auto I : Tmp) {
+ state = I->getState();
+ const LocationContext *LCtx = I->getLocationContext();
SVal V = UnknownVal();
if (location.isValid()) {
V = state->getSVal(location.castAs<Loc>(), LoadTy);
}
- Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
+ Bldr.generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx, V), tag,
ProgramPoint::PostLoadKind);
}
}
const Expr *Ex) {
StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);
- for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
- ExplodedNode *Pred = *I;
+ for (const auto Pred : Src) {
// Test if the previous node was as the same expression. This can happen
// when the expression fails to evaluate to anything meaningful and
// (as an optimization) we don't generate a node.
for (const Expr *O : A->outputs()) {
SVal X = state->getSVal(O, Pred->getLocationContext());
- assert (!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef.
+ assert(!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef.
if (Optional<Loc> LV = X.getAs<Loc>())
state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
static SourceManager* GraphPrintSourceManager;
namespace llvm {
-template<>
-struct DOTGraphTraits<ExplodedNode*> :
- public DefaultDOTGraphTraits {
- DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+template<>
+struct DOTGraphTraits<ExplodedNode*> : public DefaultDOTGraphTraits {
+ DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
// FIXME: Since we do not cache error nodes in ExprEngine now, this does not
// work.
static std::string getNodeAttributes(const ExplodedNode *N, void*) {
- return "";
+ return {};
}
// De-duplicate some source location pretty-printing.
}
static std::string getNodeLabel(const ExplodedNode *N, void*){
-
std::string sbuf;
llvm::raw_string_ostream Out(sbuf);
ProgramPoint Loc = N->getLocation();
switch (Loc.getKind()) {
- case ProgramPoint::BlockEntranceKind: {
+ case ProgramPoint::BlockEntranceKind:
Out << "Block Entrance: B"
<< Loc.castAs<BlockEntrance>().getBlock()->getBlockID();
break;
- }
case ProgramPoint::BlockExitKind:
- assert (false);
+ assert(false);
break;
case ProgramPoint::CallEnterKind:
const Stmt *Label = E.getDst()->getLabel();
if (Label) {
- if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
+ if (const auto *C = dyn_cast<CaseStmt>(Label)) {
Out << "\\lcase ";
LangOptions LO; // FIXME.
if (C->getLHS())
Out << ":";
}
else {
- assert (isa<DefaultStmt>(Label));
+ assert(isa<DefaultStmt>(Label));
Out << "\\ldefault:";
}
}
return Out.str();
}
};
-} // end llvm namespace
+
+} // namespace llvm
#endif
void ExprEngine::ViewGraph(bool trim) {
#ifndef NDEBUG
if (trim) {
- std::vector<const ExplodedNode*> Src;
+ std::vector<const ExplodedNode *> Src;
// Flush any outstanding reports to make sure we cover all the nodes.
// This does not cause them to get displayed.
- for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
- const_cast<BugType*>(*I)->FlushReports(BR);
+ for (const auto I : BR)
+ const_cast<BugType *>(I)->FlushReports(BR);
// Iterate through the reports and get their nodes.
for (BugReporter::EQClasses_iterator
EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
- ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode());
+ const auto *N = const_cast<ExplodedNode *>(EI->begin()->getErrorNode());
if (N) Src.push_back(N);
}