-//===- CallEvent.h - Wrapper for all function and method calls ----*- C++ -*--//
+//===- CallEvent.h - Wrapper for all function and method calls --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_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/Analysis/AnalysisDeclContext.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <limits>
#include <utility>
namespace clang {
+
+class LocationContext;
class ProgramPoint;
class ProgramPointTag;
+class StackFrameContext;
namespace ento {
};
class CallEvent;
-class CallEventManager;
/// This class represents a description of a function call using the number of
/// arguments and the name of the function.
class CallDescription {
friend CallEvent;
- mutable IdentifierInfo *II;
- mutable bool IsLookupDone;
+
+ mutable IdentifierInfo *II = nullptr;
+ mutable bool IsLookupDone = false;
StringRef FuncName;
unsigned RequiredArgs;
public:
- const static unsigned NoArgRequirement = ~0;
+ const static unsigned NoArgRequirement = std::numeric_limits<unsigned>::max();
+
/// \brief Constructs a CallDescription object.
///
/// @param FuncName The name of the function that will be matched.
/// call. Omit this parameter to match every occurance of call with a given
/// name regardless the number of arguments.
CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
- : II(nullptr), IsLookupDone(false), FuncName(FuncName),
- RequiredArgs(RequiredArgs) {}
+ : FuncName(FuncName), RequiredArgs(RequiredArgs) {}
/// \brief Get the name of the function that this object matches.
StringRef getFunctionName() const { return FuncName; }
class RuntimeDefinition {
/// The Declaration of the function which could be called at runtime.
/// NULL if not available.
- const Decl *D;
+ const Decl *D = nullptr;
/// The region representing an object (ObjC/C++) on which the method is
/// called. With dynamic dispatch, the method definition depends on the
/// runtime type of this object. NULL when the DynamicTypeInfo is
/// precise.
- const MemRegion *R;
+ const MemRegion *R = nullptr;
public:
- RuntimeDefinition(): D(nullptr), R(nullptr) {}
- RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
+ RuntimeDefinition() = default;
+ RuntimeDefinition(const Decl *InD): D(InD) {}
RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
+
const Decl *getDecl() { return D; }
/// \brief Check if the definition we have is precise.
/// Use the "Data" and "Location" fields instead.
class CallEvent {
public:
- typedef CallEventKind Kind;
+ using Kind = CallEventKind;
private:
ProgramStateRef State;
const LocationContext *LCtx;
llvm::PointerUnion<const Expr *, const Decl *> Origin;
- void operator=(const CallEvent &) = delete;
-
protected:
// This is user data for subclasses.
const void *Data;
SourceLocation Location;
private:
- mutable unsigned RefCount;
-
template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo;
+
+ mutable unsigned RefCount = 0;
+
void Retain() const { ++RefCount; }
void Release() const;
friend class CallEventManager;
CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
- : State(std::move(state)), LCtx(lctx), Origin(E), RefCount(0) {}
+ : State(std::move(state)), LCtx(lctx), Origin(E) {}
CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
- : State(std::move(state)), LCtx(lctx), Origin(D), RefCount(0) {}
+ : State(std::move(state)), LCtx(lctx), Origin(D) {}
// DO NOT MAKE PUBLIC
CallEvent(const CallEvent &Original)
- : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
- Data(Original.Data), Location(Original.Location), RefCount(0) {}
+ : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
+ Data(Original.Data), Location(Original.Location) {}
/// Copies this CallEvent, with vtable intact, into a new block of memory.
virtual void cloneTo(void *Dest) const = 0;
return getState()->getSVal(S, getLocationContext());
}
-
- typedef SmallVectorImpl<SVal> ValueList;
+ using ValueList = SmallVectorImpl<SVal>;
/// \brief Used to specify non-argument regions that will be invalidated as a
/// result of this call.
RegionAndSymbolInvalidationTraits *ETraits) const {}
public:
- virtual ~CallEvent() {}
+ CallEvent &operator=(const CallEvent &) = delete;
+ virtual ~CallEvent() = default;
/// \brief Returns the kind of call this is.
virtual Kind getKind() const = 0;
// Special case for implicitly-declared global operator new/delete.
// These should be considered system functions.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
return false;
// FIXME: Move this down to AnyFunctionCall once checkers have more
// precise callbacks.
const IdentifierInfo *getCalleeIdentifier() const {
- const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl());
+ const auto *ND = dyn_cast_or_null<NamedDecl>(getDecl());
if (!ND)
return nullptr;
return ND->getIdentifier();
ProgramStateRef invalidateRegions(unsigned BlockCount,
ProgramStateRef Orig = nullptr) const;
- typedef std::pair<Loc, SVal> FrameBindingTy;
- typedef SmallVectorImpl<FrameBindingTy> BindingsTy;
+ using FrameBindingTy = std::pair<Loc, SVal>;
+ using BindingsTy = SmallVectorImpl<FrameBindingTy>;
/// Populates the given SmallVector with the bindings in the callee's stack
/// frame at the start of this call.
/// Remember that the number of formal parameters may not match the number
/// of arguments for all calls. However, the first parameter will always
/// correspond with the argument value returned by \c getArgSVal(0).
- virtual ArrayRef<ParmVarDecl*> parameters() const = 0;
+ virtual ArrayRef<ParmVarDecl *> parameters() const = 0;
- typedef llvm::mapped_iterator<ArrayRef<ParmVarDecl*>::iterator, GetTypeFn>
- param_type_iterator;
+ using param_type_iterator =
+ llvm::mapped_iterator<ArrayRef<ParmVarDecl *>::iterator, GetTypeFn>;
/// Returns an iterator over the types of the call's formal parameters.
///
void dump() const;
};
-
/// \brief Represents a call to any sort of function that might have a
/// FunctionDecl.
class AnyFunctionCall : public CallEvent {
protected:
AnyFunctionCall(const Expr *E, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(E, St, LCtx) {}
+ : CallEvent(E, St, LCtx) {}
AnyFunctionCall(const Decl *D, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(D, St, LCtx) {}
- AnyFunctionCall(const AnyFunctionCall &Other) : CallEvent(Other) {}
+ : CallEvent(D, St, LCtx) {}
+ AnyFunctionCall(const AnyFunctionCall &Other) = default;
public:
// This function is overridden by subclasses, but they must return
protected:
SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
- SimpleFunctionCall(const SimpleFunctionCall &Other)
- : AnyFunctionCall(Other) {}
+ : AnyFunctionCall(CE, St, LCtx) {}
+ SimpleFunctionCall(const SimpleFunctionCall &Other) = default;
+
void cloneTo(void *Dest) const override {
new (Dest) SimpleFunctionCall(*this);
}
protected:
BlockCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(CE, St, LCtx) {}
+ : CallEvent(CE, St, LCtx) {}
+ BlockCall(const BlockCall &Other) = default;
- BlockCall(const BlockCall &Other) : CallEvent(Other) {}
void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
void getExtraInvalidatedValues(ValueList &Values,
/// it is written.
class CXXInstanceCall : public AnyFunctionCall {
protected:
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
-
CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
+ : AnyFunctionCall(CE, St, LCtx) {}
CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(D, St, LCtx) {}
-
+ : AnyFunctionCall(D, St, LCtx) {}
+ CXXInstanceCall(const CXXInstanceCall &Other) = default;
- CXXInstanceCall(const CXXInstanceCall &Other) : AnyFunctionCall(Other) {}
+ void getExtraInvalidatedValues(ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const override;
public:
/// \brief Returns the expression representing the implicit 'this' object.
protected:
CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
+ : CXXInstanceCall(CE, St, LCtx) {}
+ CXXMemberCall(const CXXMemberCall &Other) = default;
- CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
public:
protected:
CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
+ : CXXInstanceCall(CE, St, LCtx) {}
+ CXXMemberOperatorCall(const CXXMemberOperatorCall &Other) = default;
- CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
- : CXXInstanceCall(Other) {}
void cloneTo(void *Dest) const override {
new (Dest) CXXMemberOperatorCall(*this);
}
unsigned getNumArgs() const override {
return getOriginExpr()->getNumArgs() - 1;
}
+
const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index + 1);
}
friend class CallEventManager;
protected:
- typedef llvm::PointerIntPair<const MemRegion *, 1, bool> DtorDataTy;
+ using DtorDataTy = llvm::PointerIntPair<const MemRegion *, 1, bool>;
/// Creates an implicit destructor.
///
CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
const MemRegion *Target, bool IsBaseDestructor,
ProgramStateRef St, const LocationContext *LCtx)
- : CXXInstanceCall(DD, St, LCtx) {
+ : CXXInstanceCall(DD, St, LCtx) {
Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
Location = Trigger->getLocEnd();
}
- CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
+ CXXDestructorCall(const CXXDestructorCall &Other) = default;
+
void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
public:
/// \param LCtx The location context at this point in the program.
CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target,
ProgramStateRef St, const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {
+ : AnyFunctionCall(CE, St, LCtx) {
Data = Target;
}
- CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
+ CXXConstructorCall(const CXXConstructorCall &Other) = default;
+
void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
void getExtraInvalidatedValues(ValueList &Values,
protected:
CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(E, St, LCtx) {}
+ : AnyFunctionCall(E, St, LCtx) {}
+ CXXAllocatorCall(const CXXAllocatorCall &Other) = default;
- CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
public:
protected:
ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(Msg, St, LCtx) {
+ : CallEvent(Msg, St, LCtx) {
Data = nullptr;
}
- ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
+ ObjCMethodCall(const ObjCMethodCall &Other) = default;
+
void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
void getExtraInvalidatedValues(ValueList &Values,
virtual const ObjCMessageExpr *getOriginExpr() const {
return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
}
+
const ObjCMethodDecl *getDecl() const override {
return getOriginExpr()->getMethodDecl();
}
+
unsigned getNumArgs() const override {
return getOriginExpr()->getNumArgs();
}
+
const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
}
bool isInstanceMessage() const {
return getOriginExpr()->isInstanceMessage();
}
+
ObjCMethodFamily getMethodFamily() const {
return getOriginExpr()->getMethodFamily();
}
+
Selector getSelector() const {
return getOriginExpr()->getSelector();
}
}
};
-
/// \brief Manages the lifetime of CallEvent objects.
///
/// CallEventManager provides a way to create arbitrary CallEvents "on the
llvm::BumpPtrAllocator &Alloc;
SmallVector<void *, 8> Cache;
- typedef SimpleFunctionCall CallEventTemplateTy;
+
+ using CallEventTemplateTy = SimpleFunctionCall;
void reclaim(const void *Memory) {
Cache.push_back(const_cast<void *>(Memory));
public:
CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
-
CallEventRef<>
getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
-
CallEventRef<>
getSimpleCall(const CallExpr *E, ProgramStateRef State,
const LocationContext *LCtx);
}
};
-
template <typename T>
CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
assert(isa<T>(*this) && "Cloning to unrelated type");
this->~CallEvent();
}
-} // end namespace ento
-} // end namespace clang
+} // namespace ento
+
+} // namespace clang
namespace llvm {
- // Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
- template<class T> struct simplify_type< clang::ento::CallEventRef<T> > {
- typedef const T *SimpleType;
- static SimpleType
- getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
- return Val.get();
- }
- };
-}
+// Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
+template<class T> struct simplify_type< clang::ento::CallEventRef<T>> {
+ using SimpleType = const T *;
+
+ static SimpleType
+ getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
+ return Val.get();
+ }
+};
+
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
-//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
+//===- ConstraintManager.h - Constraints on symbolic values. ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/SaveAndRestore.h"
+#include <memory>
+#include <utility>
namespace llvm {
+
class APSInt;
-}
+
+} // namespace llvm
namespace clang {
namespace ento {
+class ProgramStateManager;
class SubEngine;
+class SymbolReaper;
class ConditionTruthVal {
Optional<bool> Val;
+
public:
/// Construct a ConditionTruthVal indicating the constraint is constrained
/// to either true or false, depending on the boolean value provided.
ConditionTruthVal(bool constraint) : Val(constraint) {}
/// Construct a ConstraintVal indicating the constraint is underconstrained.
- ConditionTruthVal() {}
+ ConditionTruthVal() = default;
/// \return Stored value, assuming that the value is known.
/// Crashes otherwise.
class ConstraintManager {
public:
- ConstraintManager() : NotifyAssumeClients(true) {}
-
+ ConstraintManager() = default;
virtual ~ConstraintManager();
+
virtual ProgramStateRef assume(ProgramStateRef state,
DefinedSVal Cond,
bool Assumption) = 0;
- typedef std::pair<ProgramStateRef, ProgramStateRef> ProgramStatePair;
+ using ProgramStatePair = std::pair<ProgramStateRef, ProgramStateRef>;
/// Returns a pair of states (StTrue, StFalse) where the given condition is
/// assumed to be true or false, respectively.
///
/// Note that this flag allows the ConstraintManager to be re-entrant,
/// but not thread-safe.
- bool NotifyAssumeClients;
+ bool NotifyAssumeClients = true;
/// canReasonAbout - Not all ConstraintManagers can accurately reason about
/// all SVal values. This method returns true if the ConstraintManager can
std::unique_ptr<ConstraintManager>
CreateZ3ConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine);
-} // end GR namespace
-
-} // end clang namespace
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
-//== DynamicTypeMap.h - Dynamic type map ----------------------- -*- C++ -*--=//
+//===- DynamicTypeMap.h - Dynamic type map ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "llvm/ADT/ImmutableMap.h"
+#include "clang/AST/Type.h"
namespace clang {
namespace ento {
+class MemRegion;
+
/// The GDM component containing the dynamic type info. This is a map from a
/// symbol to its most likely type.
struct DynamicTypeMap {};
-typedef llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>
- DynamicTypeMapImpl;
+
+using DynamicTypeMapImpl =
+ llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>;
+
template <>
struct ProgramStateTrait<DynamicTypeMap>
: public ProgramStatePartialTrait<DynamicTypeMapImpl> {
void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
const char *NL, const char *Sep);
-} // ento
-} // clang
+} // namespace ento
+} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H
-//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==//
+//===- Environment.h - Map from Stmt* to Locations/Values -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/ImmutableMap.h"
+#include <utility>
namespace clang {
-class LiveVariables;
+class Stmt;
namespace ento {
-class EnvironmentManager;
class SValBuilder;
class SymbolReaper;
/// This allows the environment to manage context-sensitive bindings,
/// which is essentially for modeling recursive function analysis, among
/// other things.
-class EnvironmentEntry : public std::pair<const Stmt*,
+class EnvironmentEntry : public std::pair<const Stmt *,
const StackFrameContext *> {
public:
EnvironmentEntry(const Stmt *s, const LocationContext *L);
private:
friend class EnvironmentManager;
- // Type definitions.
- typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy;
+ using BindingsTy = llvm::ImmutableMap<EnvironmentEntry, SVal>;
- // Data.
BindingsTy ExprBindings;
- Environment(BindingsTy eb)
- : ExprBindings(eb) {}
+ Environment(BindingsTy eb) : ExprBindings(eb) {}
SVal lookupExpr(const EnvironmentEntry &E) const;
public:
- typedef BindingsTy::iterator iterator;
+ using iterator = BindingsTy::iterator;
+
iterator begin() const { return ExprBindings.begin(); }
iterator end() const { return ExprBindings.end(); }
class EnvironmentManager {
private:
- typedef Environment::BindingsTy::Factory FactoryTy;
+ using FactoryTy = Environment::BindingsTy::Factory;
+
FactoryTy F;
public:
- EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
+ EnvironmentManager(llvm::BumpPtrAllocator &Allocator) : F(Allocator) {}
Environment getInitialEnvironment() {
return Environment(F.getEmptyMap());
ProgramStateRef state);
};
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
-//== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
+//===- FunctionSummary.h - Stores summaries of functions. -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
+#include <cassert>
#include <deque>
+#include <utility>
namespace clang {
-
namespace ento {
-typedef std::deque<Decl*> SetOfDecls;
-typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
+
+using SetOfDecls = std::deque<Decl *>;
+using SetOfConstDecls = llvm::DenseSet<const Decl *>;
class FunctionSummariesTy {
class FunctionSummary {
/// The number of times the function has been inlined.
unsigned TimesInlined : 32;
- FunctionSummary() :
- TotalBasicBlocks(0),
- InlineChecked(0),
- MayInline(0),
- TimesInlined(0) {}
+ FunctionSummary()
+ : TotalBasicBlocks(0), InlineChecked(0), MayInline(0),
+ TimesInlined(0) {}
};
- typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
+ using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>;
MapTy Map;
public:
if (I != Map.end())
return I;
- typedef std::pair<const Decl *, FunctionSummary> KVPair;
+ using KVPair = std::pair<const Decl *, FunctionSummary>;
+
I = Map.insert(KVPair(D, FunctionSummary())).first;
assert(I != Map.end());
return I;
unsigned getTotalNumBasicBlocks();
unsigned getTotalNumVisitedBasicBlocks();
-
};
-}} // end clang ento namespaces
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
-//===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
+//===- CallEvent.cpp - Wrapper for all function and method calls ----------===//
//
// The LLVM Compiler Infrastructure
//
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.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/AST/Stmt.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/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <utility>
#define DEBUG_TYPE "static-analyzer-call-event"
}
static bool isVoidPointerToNonConst(QualType T) {
- if (const PointerType *PT = T->getAs<PointerType>()) {
+ if (const auto *PT = T->getAs<PointerType>()) {
QualType PointeeTy = PT->getPointeeType();
if (PointeeTy.isConstQualified())
return false;
}
bool CallEvent::isGlobalCFunction(StringRef FunctionName) const {
- const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
if (!FD)
return false;
SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
const Expr *ArgE = getArgExpr(Index);
if (!ArgE)
- return SourceRange();
+ return {};
return ArgE->getSourceRange();
}
Out << "Unknown call (type " << getKind() << ")";
}
-
bool CallEvent::isCallStmt(const Stmt *S) {
return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)
|| isa<CXXConstructExpr>(S)
QualType CallEvent::getDeclaredResultType(const Decl *D) {
assert(D);
- if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
return FD->getReturnType();
- if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D))
+ if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
return MD->getReturnType();
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
+ if (const auto *BD = dyn_cast<BlockDecl>(D)) {
// Blocks are difficult because the return type may not be stored in the
// BlockDecl itself. The AST should probably be enhanced, but for now we
// just do what we can.
return Ty;
}
- return QualType();
+ return {};
}
llvm_unreachable("unknown callable kind");
bool CallEvent::isVariadic(const Decl *D) {
assert(D);
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
return FD->isVariadic();
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
return MD->isVariadic();
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
+ if (const auto *BD = dyn_cast<BlockDecl>(D))
return BD->isVariadic();
llvm_unreachable("unknown callable kind");
}
}
- return RuntimeDefinition();
+ return {};
}
void AnyFunctionCall::getInitialStackFrameContents(
const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const {
- const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl());
+ const auto *D = cast<FunctionDecl>(CalleeCtx->getDecl());
SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
D->parameters());
return false;
}
-
const FunctionDecl *SimpleFunctionCall::getDecl() const {
const FunctionDecl *D = getOriginExpr()->getDirectCallee();
if (D)
return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
}
-
const FunctionDecl *CXXInstanceCall::getDecl() const {
- const CallExpr *CE = cast_or_null<CallExpr>(getOriginExpr());
+ const auto *CE = cast_or_null<CallExpr>(getOriginExpr());
if (!CE)
return AnyFunctionCall::getDecl();
Values.push_back(ThisVal);
// Don't invalidate if the method is const and there are no mutable fields.
- if (const CXXMethodDecl *D = cast_or_null<CXXMethodDecl>(getDecl())) {
+ if (const auto *D = cast_or_null<CXXMethodDecl>(getDecl())) {
if (!D->isConst())
return;
// Get the record decl for the class of 'This'. D->getParent() may return a
return ThisVal;
}
-
RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
// Do we have a decl at all?
const Decl *D = getDecl();
if (!D)
- return RuntimeDefinition();
+ return {};
// If the method is non-virtual, we know we can inline it.
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
+ const auto *MD = cast<CXXMethodDecl>(D);
if (!MD->isVirtual())
return AnyFunctionCall::getRuntimeDefinition();
// Do we know the implicit 'this' object being called?
const MemRegion *R = getCXXThisVal().getAsRegion();
if (!R)
- return RuntimeDefinition();
+ return {};
// Do we know anything about the type of 'this'?
DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
if (!DynType.isValid())
- return RuntimeDefinition();
+ return {};
// Is the type a C++ class? (This is mostly a defensive check.)
QualType RegionType = DynType.getType()->getPointeeType();
const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
if (!RD || !RD->hasDefinition())
- return RuntimeDefinition();
+ return {};
// Find the decl for this method in that class.
const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
// this is fixed. <rdar://problem/12287087>
//assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
- return RuntimeDefinition();
+ return {};
}
// Does the decl that we found have an implementation?
const FunctionDecl *Definition;
if (!Result->hasBody(Definition))
- return RuntimeDefinition();
+ return {};
// We found a definition. If we're not sure that this devirtualization is
// actually what will happen at runtime, make sure to provide the region so
ProgramStateManager &StateMgr = getState()->getStateManager();
SValBuilder &SVB = StateMgr.getSValBuilder();
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+ const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
// If we devirtualized to a different member function, we need to make sure
}
}
-
-
const Expr *CXXMemberCall::getCXXThisExpr() const {
return getOriginExpr()->getImplicitObjectArgument();
}
// id-expression in the class member access expression is a qualified-id,
// that function is called. Otherwise, its final overrider in the dynamic type
// of the object expression is called.
- if (const MemberExpr *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
+ if (const auto *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
if (ME->hasQualifier())
return AnyFunctionCall::getRuntimeDefinition();
return CXXInstanceCall::getRuntimeDefinition();
}
-
const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
return getOriginExpr()->getArg(0);
}
-
const BlockDataRegion *BlockCall::getBlockRegion() const {
const Expr *Callee = getOriginExpr()->getCallee();
const MemRegion *DataReg = getSVal(Callee).getAsRegion();
Params);
}
-
SVal CXXConstructorCall::getCXXThisVal() const {
if (Data)
return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
SVal ThisVal = getCXXThisVal();
if (!ThisVal.isUnknown()) {
SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+ const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
}
llvm_unreachable("unknown message kind");
}
-typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
+using ObjCMessageDataTy = llvm::PointerIntPair<const PseudoObjectExpr *, 2>;
const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
assert(Data && "Lazy lookup not yet performed.");
// This handles the funny case of assigning to the result of a getter.
// This can happen if the getter returns a non-const reference.
- if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
+ if (const auto *BO = dyn_cast<BinaryOperator>(Syntactic))
Syntactic = BO->getLHS();
return Syntactic;
ObjCMessageKind ObjCMethodCall::getMessageKind() const {
if (!Data) {
-
// Find the parent, ignoring implicit casts.
ParentMap &PM = getLocationContext()->getParentMap();
const Stmt *S = PM.getParentIgnoreParenCasts(getOriginExpr());
// Check if parent is a PseudoObjectExpr.
- if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
+ if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
ObjCMessageKind K;
Selector Sel = E->getSelector();
if (E->isInstanceMessage()) {
-
// Find the receiver type.
const ObjCObjectPointerType *ReceiverT = nullptr;
bool CanBeSubClassed = false;
} else {
Receiver = getReceiverSVal().getAsRegion();
if (!Receiver)
- return RuntimeDefinition();
+ return {};
DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
if (!DTI.isValid()) {
assert(isa<AllocaRegion>(Receiver) &&
"Unhandled untyped region class!");
- return RuntimeDefinition();
+ return {};
}
QualType DynType = DTI.getType();
// need to revisit this someday. In terms of memory, this table
// stays around until clang quits, which also may be bad if we
// need to release memory.
- typedef std::pair<const ObjCInterfaceDecl*, Selector>
- PrivateMethodKey;
- typedef llvm::DenseMap<PrivateMethodKey,
- Optional<const ObjCMethodDecl *> >
- PrivateMethodCache;
+ using PrivateMethodKey = std::pair<const ObjCInterfaceDecl *, Selector>;
+ using PrivateMethodCache =
+ llvm::DenseMap<PrivateMethodKey, Optional<const ObjCMethodDecl *>>;
static PrivateMethodCache PMC;
Optional<const ObjCMethodDecl *> &Val = PMC[std::make_pair(IDecl, Sel)];
else
return RuntimeDefinition(MD, nullptr);
}
-
} else {
// This is a class method.
// If we have type info for the receiver class, we are calling via
}
}
- return RuntimeDefinition();
+ return {};
}
bool ObjCMethodCall::argumentsMayEscape() const {
void ObjCMethodCall::getInitialStackFrameContents(
const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const {
- const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
+ const auto *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
D->parameters());
CallEventRef<>
CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
const LocationContext *LCtx) {
- if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE))
+ if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(CE))
return create<CXXMemberCall>(MCE, State, LCtx);
- if (const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
+ if (const auto *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
if (MD->isInstance())
return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
return create<SimpleFunctionCall>(CE, State, LCtx);
}
-
CallEventRef<>
CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
ProgramStateRef State) {
case Stmt::CXXConstructExprClass:
case Stmt::CXXTemporaryObjectExprClass: {
SValBuilder &SVB = State->getStateManager().getSValBuilder();
- const CXXMethodDecl *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+ const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
SVal ThisVal = State->getSVal(ThisPtr);
"All other CFG elements should have exprs");
SValBuilder &SVB = State->getStateManager().getSValBuilder();
- const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
+ const auto *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
SVal ThisVal = State->getSVal(ThisPtr);
-//== ConstraintManager.cpp - Constraints on symbolic values -----*- C++ -*--==//
+//===- ConstraintManager.cpp - Constraints on symbolic values. ------------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
+#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
using namespace clang;
using namespace ento;
-ConstraintManager::~ConstraintManager() {}
+ConstraintManager::~ConstraintManager() = default;
static DefinedSVal getLocFromSymbol(const ProgramStateRef &State,
SymbolRef Sym) {
return ConditionTruthVal(false);
if (!P.first && P.second)
return ConditionTruthVal(true);
- return ConditionTruthVal();
+ return {};
}
-//==- DynamicTypeMap.cpp - Dynamic Type Info related APIs ----------*- C++ -*-//
+//===- DynamicTypeMap.cpp - Dynamic Type Info related APIs ----------------===//
//
// The LLVM Compiler Infrastructure
//
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
namespace clang {
namespace ento {
return *GDMType;
// Otherwise, fall back to what we know about the region.
- if (const TypedRegion *TR = dyn_cast<TypedRegion>(Reg))
+ if (const auto *TR = dyn_cast<TypedRegion>(Reg))
return DynamicTypeInfo(TR->getLocationType(), /*CanBeSubclass=*/false);
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
+ if (const auto *SR = dyn_cast<SymbolicRegion>(Reg)) {
SymbolRef Sym = SR->getSymbol();
return DynamicTypeInfo(Sym->getType());
}
- return DynamicTypeInfo();
+ return {};
}
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg,
-//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
+//===- Environment.cpp - Map from Stmt* to Locations/Values ---------------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
+#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Stmt.h"
#include "clang/Analysis/AnalysisDeclContext.h"
-#include "clang/Analysis/CFG.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
using namespace clang;
using namespace ento;
}
static const Stmt *ignoreTransparentExprs(const Stmt *S) {
- if (const Expr *E = dyn_cast<Expr>(S))
+ if (const auto *E = dyn_cast<Expr>(S))
return ignoreTransparentExprs(E);
return S;
}
EnvironmentEntry::EnvironmentEntry(const Stmt *S, const LocationContext *L)
- : std::pair<const Stmt *,
- const StackFrameContext *>(ignoreTransparentExprs(S),
- L ? L->getCurrentStackFrame()
- : nullptr) {}
+ : std::pair<const Stmt *,
+ const StackFrameContext *>(ignoreTransparentExprs(S),
+ L ? L->getCurrentStackFrame()
+ : nullptr) {}
SVal Environment::lookupExpr(const EnvironmentEntry &E) const {
const SVal* X = ExprBindings.lookup(E);
return svalBuilder.getConstantVal(cast<Expr>(S)).getValue();
case Stmt::ReturnStmtClass: {
- const ReturnStmt *RS = cast<ReturnStmt>(S);
+ const auto *RS = cast<ReturnStmt>(S);
if (const Expr *RE = RS->getRetValue())
return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder);
return UndefinedVal();
}
namespace {
+
class MarkLiveCallback final : public SymbolVisitor {
SymbolReaper &SymReaper;
+
public:
MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
+
bool VisitSymbol(SymbolRef sym) override {
SymReaper.markLive(sym);
return true;
}
+
bool VisitMemRegion(const MemRegion *R) override {
SymReaper.markLive(R);
return true;
}
};
-} // end anonymous namespace
+
+} // namespace
// removeDeadBindings:
// - Remove subexpression bindings.
EnvironmentManager::removeDeadBindings(Environment Env,
SymbolReaper &SymReaper,
ProgramStateRef ST) {
-
// We construct a new Environment object entirely, as this is cheaper than
// individually removing all the subexpression bindings (which will greatly
// outnumber block-level expression bindings).
MarkLiveCallback CB(SymReaper);
ScanReachableSymbols RSScaner(ST, CB);
- llvm::ImmutableMapRef<EnvironmentEntry,SVal>
+ llvm::ImmutableMapRef<EnvironmentEntry, SVal>
EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(),
F.getTreeFactory());
// Iterate over the block-expr bindings.
for (Environment::iterator I = Env.begin(), E = Env.end();
I != E; ++I) {
-
const EnvironmentEntry &BlkExpr = I.getKey();
const SVal &X = I.getData();
-//== FunctionSummary.cpp - Stores summaries of functions. ----------*- C++ -*-//
+//===- FunctionSummary.cpp - Stores summaries of functions. ---------------===//
//
// The LLVM Compiler Infrastructure
//
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
+
using namespace clang;
using namespace ento;
unsigned FunctionSummariesTy::getTotalNumBasicBlocks() {
unsigned Total = 0;
- for (MapTy::iterator I = Map.begin(), E = Map.end(); I != E; ++I) {
- Total += I->second.TotalBasicBlocks;
- }
+ for (const auto &I : Map)
+ Total += I.second.TotalBasicBlocks;
return Total;
}
unsigned FunctionSummariesTy::getTotalNumVisitedBasicBlocks() {
unsigned Total = 0;
- for (MapTy::iterator I = Map.begin(), E = Map.end(); I != E; ++I) {
- Total += I->second.VisitedBasicBlocks.count();
- }
+ for (const auto &I : Map)
+ Total += I.second.VisitedBasicBlocks.count();
return Total;
}