#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <memory>
#include <utility>
#define DEBUG_TYPE …
namespace clang {
namespace dataflow {
static constexpr int MaxCompositeValueDepth = …;
static constexpr int MaxCompositeValueSize = …;
static llvm::DenseMap<const ValueDecl *, StorageLocation *> intersectDeclToLoc(
const llvm::DenseMap<const ValueDecl *, StorageLocation *> &DeclToLoc1,
const llvm::DenseMap<const ValueDecl *, StorageLocation *> &DeclToLoc2) { … }
template <typename MapT> MapT joinExprMaps(const MapT &Map1, const MapT &Map2) { … }
static bool equateUnknownValues(Value::Kind K) { … }
static bool compareDistinctValues(QualType Type, Value &Val1,
const Environment &Env1, Value &Val2,
const Environment &Env2,
Environment::ValueModel &Model) { … }
static Value *joinDistinctValues(QualType Type, Value &Val1,
const Environment &Env1, Value &Val2,
const Environment &Env2,
Environment &JoinedEnv,
Environment::ValueModel &Model) { … }
static WidenResult widenDistinctValues(QualType Type, Value &Prev,
const Environment &PrevEnv,
Value &Current, Environment &CurrentEnv,
Environment::ValueModel &Model) { … }
template <typename Key>
bool compareKeyToValueMaps(const llvm::MapVector<Key, Value *> &Map1,
const llvm::MapVector<Key, Value *> &Map2,
const Environment &Env1, const Environment &Env2,
Environment::ValueModel &Model) { … }
static llvm::MapVector<const StorageLocation *, Value *>
joinLocToVal(const llvm::MapVector<const StorageLocation *, Value *> &LocToVal,
const llvm::MapVector<const StorageLocation *, Value *> &LocToVal2,
const Environment &Env1, const Environment &Env2,
Environment &JoinedEnv, Environment::ValueModel &Model) { … }
template <typename Key>
llvm::MapVector<Key, Value *>
widenKeyToValueMap(const llvm::MapVector<Key, Value *> &CurMap,
const llvm::MapVector<Key, Value *> &PrevMap,
Environment &CurEnv, const Environment &PrevEnv,
Environment::ValueModel &Model, LatticeEffect &Effect) { … }
namespace {
class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> { … };
}
void Environment::initialize() { … }
void Environment::initFieldsGlobalsAndFuncs(const ReferencedDecls &Referenced) { … }
Environment Environment::fork() const { … }
bool Environment::canDescend(unsigned MaxDepth,
const FunctionDecl *Callee) const { … }
Environment Environment::pushCall(const CallExpr *Call) const { … }
Environment Environment::pushCall(const CXXConstructExpr *Call) const { … }
void Environment::pushCallInternal(const FunctionDecl *FuncDecl,
ArrayRef<const Expr *> Args) { … }
void Environment::popCall(const CallExpr *Call, const Environment &CalleeEnv) { … }
void Environment::popCall(const CXXConstructExpr *Call,
const Environment &CalleeEnv) { … }
bool Environment::equivalentTo(const Environment &Other,
Environment::ValueModel &Model) const { … }
LatticeEffect Environment::widen(const Environment &PrevEnv,
Environment::ValueModel &Model) { … }
Environment Environment::join(const Environment &EnvA, const Environment &EnvB,
Environment::ValueModel &Model,
ExprJoinBehavior ExprBehavior) { … }
Value *Environment::joinValues(QualType Ty, Value *Val1,
const Environment &Env1, Value *Val2,
const Environment &Env2, Environment &JoinedEnv,
Environment::ValueModel &Model) { … }
StorageLocation &Environment::createStorageLocation(QualType Type) { … }
StorageLocation &Environment::createStorageLocation(const ValueDecl &D) { … }
StorageLocation &Environment::createStorageLocation(const Expr &E) { … }
void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) { … }
StorageLocation *Environment::getStorageLocation(const ValueDecl &D) const { … }
void Environment::removeDecl(const ValueDecl &D) { … }
void Environment::setStorageLocation(const Expr &E, StorageLocation &Loc) { … }
StorageLocation *Environment::getStorageLocation(const Expr &E) const { … }
RecordStorageLocation &
Environment::getResultObjectLocation(const Expr &RecordPRValue) const { … }
PointerValue &Environment::getOrCreateNullPointerValue(QualType PointeeType) { … }
void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc,
QualType Type) { … }
void Environment::setValue(const StorageLocation &Loc, Value &Val) { … }
void Environment::setValue(const Expr &E, Value &Val) { … }
Value *Environment::getValue(const StorageLocation &Loc) const { … }
Value *Environment::getValue(const ValueDecl &D) const { … }
Value *Environment::getValue(const Expr &E) const { … }
Value *Environment::createValue(QualType Type) { … }
Value *Environment::createValueUnlessSelfReferential(
QualType Type, llvm::DenseSet<QualType> &Visited, int Depth,
int &CreatedValuesCount) { … }
StorageLocation &
Environment::createLocAndMaybeValue(QualType Ty,
llvm::DenseSet<QualType> &Visited,
int Depth, int &CreatedValuesCount) { … }
void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc,
QualType Type,
llvm::DenseSet<QualType> &Visited,
int Depth,
int &CreatedValuesCount) { … }
StorageLocation &Environment::createObjectInternal(const ValueDecl *D,
QualType Ty,
const Expr *InitExpr) { … }
void Environment::assume(const Formula &F) { … }
bool Environment::proves(const Formula &F) const { … }
bool Environment::allows(const Formula &F) const { … }
void Environment::dump(raw_ostream &OS) const { … }
void Environment::dump() const { … }
Environment::PrValueToResultObject Environment::buildResultObjectMap(
DataflowAnalysisContext *DACtx, const FunctionDecl *FuncDecl,
RecordStorageLocation *ThisPointeeLoc,
RecordStorageLocation *LocForRecordReturnVal) { … }
Environment::PrValueToResultObject Environment::buildResultObjectMap(
DataflowAnalysisContext *DACtx, Stmt *S,
RecordStorageLocation *ThisPointeeLoc,
RecordStorageLocation *LocForRecordReturnVal) { … }
RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
const Environment &Env) { … }
RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
const Environment &Env) { … }
}
}