15#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
16#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/DenseSet.h"
32#include "llvm/ADT/MapVector.h"
33#include "llvm/Support/Compiler.h"
34#include "llvm/Support/ErrorHandling.h"
149 switch (
compare(
Type, Prev, PrevEnv, Current, CurrentEnv)) {
157 llvm_unreachable(
"all cases in switch covered");
171 virtual std::unique_ptr<BoolModel>
clone()
const = 0;
219 virtual void dump(raw_ostream &OS)
const = 0;
241 InitialTargetStmt = &S;
254 InitialTargetFunc = &FD;
350 return BoolState->joinBoolValues(Val1, *Env1.BoolState, Val2,
351 *Env2.BoolState, *
this);
421 template <
typename T>
422 std::enable_if_t<std::is_base_of_v<StorageLocation, T>,
T *>
426 template <
typename T>
427 std::enable_if_t<std::is_base_of_v<StorageLocation, T>,
T *>
438 return ThisPointeeLoc;
457 auto It = ThisExprOverrides->find(&ThisExpr);
458 if (It == ThisExprOverrides->end())
459 return ThisPointeeLoc;
466 ThisPointeeLoc = &Loc;
562 return createObjectInternal(
nullptr, Ty, InitExpr);
580 return createObjectInternal(&D, D.
getType(), InitExpr);
638 template <
typename T>
639 std::enable_if_t<std::is_base_of_v<Value, T>,
T *>
641 return cast_or_null<T>(
getValue(Loc));
643 template <
typename T>
644 std::enable_if_t<std::is_base_of_v<Value, T>,
T *>
646 return cast_or_null<T>(
getValue(D));
648 template <
typename T>
649 std::enable_if_t<std::is_base_of_v<Value, T>,
T *>
get(
const Expr &E)
const {
650 return cast_or_null<T>(
getValue(E));
660 template <
typename T,
typename... Args>
661 std::enable_if_t<std::is_base_of<Value, T>::value,
T &>
745 return BoolState->getFlowConditionToken();
770 return CallStack.empty() ? InitialTargetFunc : CallStack.back();
788 LLVM_DUMP_METHOD
void dump()
const;
789 LLVM_DUMP_METHOD
void dump(raw_ostream &OS)
const;
792 using PrValueToResultObject =
793 llvm::DenseMap<const Expr *, RecordStorageLocation *>;
794 using ThisExprOverridesMap =
795 llvm::DenseMap<const CXXThisExpr *, RecordStorageLocation *>;
812 llvm::DenseSet<QualType> &Visited,
813 int Depth,
int &CreatedValuesCount);
820 llvm::DenseSet<QualType> &Visited,
821 int Depth,
int &CreatedValuesCount);
830 llvm::DenseSet<QualType> &Visited,
int Depth,
831 int &CreatedValuesCount);
836 const Expr *InitExpr);
848 static PrValueToResultObject
854 static PrValueToResultObject
859 static ThisExprOverridesMap
862 const PrValueToResultObject &ResultObjectMap);
864 static ThisExprOverridesMap
866 const PrValueToResultObject &ResultObjectMap);
877 std::vector<const FunctionDecl *> CallStack;
886 Stmt *InitialTargetStmt =
nullptr;
895 std::shared_ptr<PrValueToResultObject> ResultObjectMap;
901 Value *ReturnVal =
nullptr;
917 std::shared_ptr<ThisExprOverridesMap> ThisExprOverrides;
923 llvm::DenseMap<const ValueDecl *, StorageLocation *> DeclToLoc;
924 llvm::DenseMap<const Expr *, StorageLocation *> ExprToLoc;
929 llvm::MapVector<const Expr *, Value *> ExprToVal;
930 llvm::MapVector<const StorageLocation *, Value *> LocToVal;
933 std::unique_ptr<BoolModel> BoolState;
941 const Environment &Env);
947 const Environment &Env);
Defines the clang::Expr interface and subclasses for C++ expressions.
C Language Family Type Representation.
Represents a call to a C++ constructor.
Represents a call to a member function that may be written either with member call syntax (e....
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
This represents one expression.
Represents a function declaration or definition.
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A (possibly-)qualified type.
Stmt - This represents one statement.
The base class of the type hierarchy.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const Expr * getInit() const
The Arena owns the objects that model data within an analysis.
IntegerValue & makeIntLiteral(llvm::APInt Value)
Returns a symbolic integer value that models an integer literal equal to Value.
TopBoolValue & makeTopValue()
Creates a fresh Top boolean value.
BoolValue & makeBoolValue(const Formula &)
Creates a BoolValue wrapping a particular formula.
AtomicBoolValue & makeAtomValue()
Creates a fresh atom and wraps in in an AtomicBoolValue.
std::enable_if_t< std::is_base_of< StorageLocation, T >::value, T & > create(Args &&...args)
Creates a T (some subclass of StorageLocation), forwarding args to the constructor,...
const Formula & formula() const
Owns objects that encompass the state of a program and stores context that is used during dataflow an...
virtual void dump(raw_ostream &OS) const =0
virtual void join(const BoolModel &ModelA, const BoolModel &ModelB)=0
Populates this with the join of ModelA and ModelB.
BoolModelKind getKind() const
virtual bool proves(const Formula &F) const =0
Returns true if F is always true when this point is reached.
virtual ~BoolModel()=default
virtual Atom getFlowConditionToken() const =0
Returns the flow condition token (only meaningful for SAT-based models).
virtual void onFork()=0
If this model state was cloned, updates this model state to be a fork so that mutations to either mod...
virtual bool isEquivalentTo(const BoolModel &Other) const =0
Returns whether this boolean model state is equivalent to Other for convergence purposes.
virtual std::unique_ptr< BoolModel > clone() const =0
Returns an exact copy of this model state.
BoolModel(BoolModelKind K)
virtual LatticeEffect widen(const BoolModel &PrevModel)=0
Widens this with respect to PrevModel and returns whether the state changed relative to PrevModel.
virtual void assume(const Formula &F)=0
Records a fact that must be true if this point in the program is reached.
virtual bool allows(const Formula &F) const =0
Returns true if F may be true when this point is reached.
virtual BoolValue & joinBoolValues(BoolValue &Val1, const BoolModel &Model1, BoolValue &Val2, const BoolModel &Model2, Environment &JoinedEnv)=0
Joins two distinct boolean values Val1 (from Model1) and Val2 (from Model2) into JoinedEnv.
Supplements Environment with non-standard comparison and join operations.
virtual std::optional< WidenResult > widen(QualType Type, Value &Prev, const Environment &PrevEnv, Value &Current, Environment &CurrentEnv)
This function may widen the current value – replace it with an approximation that can reach a fixed p...
virtual ~ValueModel()=default
virtual void join(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2, Value &JoinedVal, Environment &JoinedEnv)
Modifies JoinedVal to approximate both Val1 and Val2.
virtual ComparisonResult compare(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2)
Returns: Same: Val1 is equivalent to Val2, according to the model.
Holds the state of the program (store and heap) at a given program point.
bool allows(const Formula &) const
Returns true if the formula may be true when this point is reached.
void initializeFieldsWithValues(RecordStorageLocation &Loc)
LatticeEffect widen(const Environment &PrevEnv, Environment::ValueModel &Model)
Widens the environment point-wise, using PrevEnv as needed to inform the approximation.
PointerValue & getOrCreateNullPointerValue(QualType PointeeType)
Returns a pointer value that represents a null pointer.
BoolValue & makeAnd(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value that represents the conjunction of LHS and RHS.
std::enable_if_t< std::is_base_of_v< Value, T >, T * > get(const StorageLocation &Loc) const
Returns the result of casting getValue(...) to a subclass of Value (using cast_or_null<T>).
RecordStorageLocation * getThisPointeeStorageLocation() const
Returns the storage location assigned to the this pointee in the environment or null if the this poin...
BoolValue & makeIff(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value represents LHS <=> RHS.
Environment pushCall(const CallExpr *Call) const
Creates and returns an environment to use for an inline analysis of the callee.
void clearValue(const StorageLocation &Loc)
Clears any association between Loc and a value in the environment.
StorageLocation * getStorageLocation(const ValueDecl &D) const
Returns the storage location assigned to D in the environment, or null if D isn't assigned a storage ...
LLVM_DUMP_METHOD void dump() const
Environment(DataflowAnalysisContext &DACtx, Stmt &S)
Creates an environment that uses DACtx to store objects that encompass the state of a program,...
void setReturnValue(Value *Val)
Sets the return value of the function currently being analyzed.
Environment(Environment &&Other)=default
BoolValue & makeTopBoolValue() const
Returns a unique instance of boolean Top.
StorageLocation & createObject(const VarDecl &D)
Creates an object for the variable declaration D.
void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type)
Initializes the fields (including synthetic fields) of Loc with values, unless values of the field ty...
StorageLocation & createStorageLocation(QualType Type)
Creates a storage location appropriate for Type.
Value * getReturnValue() const
Returns the return value of the function currently being analyzed.
Environment fork() const
Returns a new environment that is a copy of this one.
void popCall(const CallExpr *Call, const Environment &CalleeEnv)
Moves gathered information back into this from a CalleeEnv created via pushCall.
bool equivalentTo(const Environment &Other, Environment::ValueModel &Model) const
Returns true if and only if the environment is equivalent to Other, i.e the two environments:
BoolValue & makeAtomicBoolValue() const
Returns an atomic boolean value.
std::enable_if_t< std::is_base_of_v< Value, T >, T * > get(const ValueDecl &D) const
bool proves(const Formula &) const
Returns true if the formula is always true when this point is reached.
Value * getValue(const StorageLocation &Loc) const
Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...
Environment & operator=(const Environment &Other)=delete
const FunctionDecl * getCurrentFunc() const
Returns the function currently being analyzed, or null if the code being analyzed isn't part of a fun...
BoolValue & getBoolLiteralValue(bool Value) const
Returns a symbolic boolean value that models a boolean literal equal to Value
StorageLocation & createObject(QualType Ty, const Expr *InitExpr=nullptr)
Creates an object (i.e.
void assume(const Formula &)
Record a fact that must be true if this point in the program is reached.
DataflowAnalysisContext & getDataflowAnalysisContext() const
Returns the DataflowAnalysisContext used by the environment.
BoolValue & joinBoolValues(BoolValue &Val1, const Environment &Env1, BoolValue &Val2, const Environment &Env2)
Joins two distinct boolean values Val1 (from Env1) and Val2 (from Env2) into this environment.
Environment(DataflowAnalysisContext &DACtx, Atom FlowConditionToken)
Creates an environment that uses DACtx to store objects that encompass the state of a program.
static Value * joinValues(QualType Ty, Value *Val1, const Environment &Env1, Value *Val2, const Environment &Env2, Environment &JoinedEnv, Environment::ValueModel &Model)
Returns a value that approximates both Val1 and Val2, or null if no such value can be produced.
void setStorageLocation(const ValueDecl &D, StorageLocation &Loc)
Assigns Loc as the storage location of D in the environment.
void removeDecl(const ValueDecl &D)
Removes the location assigned to D in the environment (if any).
RecordStorageLocation & getResultObjectLocation(const Expr &RecordPRValue) const
Returns the location of the result object for a record-type prvalue.
std::enable_if_t< std::is_base_of_v< StorageLocation, T >, T * > get(const Expr &E) const
ExprJoinBehavior
How to treat expression state (ExprToLoc and ExprToVal) in a join.
static Environment join(const Environment &EnvA, const Environment &EnvB, Environment::ValueModel &Model, ExprJoinBehavior ExprBehavior)
Joins two environments by taking the intersection of storage locations and values that are stored in ...
Value * createValue(QualType Type)
Creates a value appropriate for Type, if Type is supported, otherwise returns null.
void setValue(const StorageLocation &Loc, Value &Val)
Assigns Val as the value of Loc in the environment.
IntegerValue & getIntLiteralValue(llvm::APInt Value) const
Returns a symbolic integer value that models an integer literal equal to Value
Environment & operator=(Environment &&Other)=default
void setThisPointeeStorageLocation(RecordStorageLocation &Loc)
Sets the storage location assigned to the this pointee in the environment.
Atom getFlowConditionToken() const
Returns a boolean variable that identifies the flow condition (FC).
Environment(DataflowAnalysisContext &DACtx, const FunctionDecl &FD)
Creates an environment that uses DACtx to store objects that encompass the state of a program,...
RecordStorageLocation * getThisPointeeStorageLocation(const CXXThisExpr &ThisExpr) const
Returns the storage location assigned to the this pointee in the environment given a specific CXXThis...
StorageLocation & createObject(const ValueDecl &D, const Expr *InitExpr)
Creates an object for the variable declaration D.
BoolValue & makeNot(BoolValue &Val) const
Returns a boolean value that represents the negation of Val.
size_t callStackSize() const
Returns the size of the call stack, not counting the initial analysis target.
bool canDescend(unsigned MaxDepth, const FunctionDecl *Callee) const
Returns whether this Environment can be extended to analyze the given Callee (i.e.
std::enable_if_t< std::is_base_of_v< StorageLocation, T >, T * > get(const ValueDecl &D) const
Returns the result of casting getStorageLocation(...) to a subclass of StorageLocation (using cast_or...
void initialize()
Assigns storage locations and values to all parameters, captures, global variables,...
BoolValue & makeOr(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value that represents the disjunction of LHS and RHS.
std::enable_if_t< std::is_base_of< Value, T >::value, T & > create(Args &&...args)
Creates a T (some subclass of Value), forwarding args to the constructor, and returns a reference to ...
void setReturnStorageLocation(StorageLocation *Loc)
Sets the storage location for the reference returned by the function currently being analyzed.
StorageLocation * getReturnStorageLocation() const
Returns the storage location for the reference returned by the function currently being analyzed.
std::enable_if_t< std::is_base_of_v< Value, T >, T * > get(const Expr &E) const
BoolValue & makeImplication(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value represents LHS => RHS.
Models a symbolic pointer. Specifically, any value of type T*.
A storage location for a record (struct, class, or union).
Base class for elements of the local variable store and of the heap.
Base class for all values computed by abstract interpretation.
BoolModelKind
Selects the boolean model used to represent and reason about path conditions and boolean values in En...
Atom
Identifies an atomic boolean variable such as "V1".
ComparisonResult
Indicates the result of a tentative comparison.
RecordStorageLocation * getImplicitObjectLocation(const CXXMemberCallExpr &MCE, const Environment &Env)
Returns the storage location for the implicit object of a CXXMemberCallExpr, or null if none is defin...
RecordStorageLocation * getBaseObjectLocation(const MemberExpr &ME, const Environment &Env)
Returns the storage location for the base object of a MemberExpr, or null if none is defined in the e...
LatticeEffect
Effect indicating whether a lattice operation resulted in a new value.
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T
A collection of several types of declarations, all referenced from the same function.
The result of a widen operation.
LatticeEffect Effect
Whether V represents a "change" (that is, a different value) with respect to the previous value in th...
Value * V
Non-null pointer to a potentially widened version of the input value.