aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h64
1 files changed, 51 insertions, 13 deletions
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 415fa05586ed..116a5970c341 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -617,6 +617,11 @@ public:
return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
}
+ /// Retreives which element is being constructed in a non POD type array.
+ static Optional<unsigned>
+ getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
/// By looking at a certain item that may be potentially part of an object's
/// ConstructionContext, retrieve such object's location. A particular
/// statement can be transparently passed as \p Item in most cases.
@@ -708,10 +713,19 @@ public:
/// fully implemented it sometimes indicates that it failed via its
/// out-parameter CallOpts; in such cases a fake temporary region is
/// returned, which is better than nothing but does not represent
- /// the actual behavior of the program.
- SVal computeObjectUnderConstruction(
- const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
- const ConstructionContext *CC, EvalCallOptions &CallOpts);
+ /// the actual behavior of the program. The Idx parameter is used if we
+ /// construct an array of objects. In that case it points to the index
+ /// of the continous memory region.
+ /// E.g.:
+ /// For `int arr[4]` this index can be 0,1,2,3.
+ /// For `int arr2[3][3]` this index can be 0,1,...,7,8.
+ /// A multi-dimensional array is also a continous memory location in a
+ /// row major order, so for arr[0][0] Idx is 0 and for arr[2][2] Idx is 8.
+ SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State,
+ const LocationContext *LCtx,
+ const ConstructionContext *CC,
+ EvalCallOptions &CallOpts,
+ unsigned Idx = 0);
/// Update the program state with all the path-sensitive information
/// that's necessary to perform construction of an object with a given
@@ -724,12 +738,16 @@ public:
/// A convenient wrapper around computeObjectUnderConstruction
/// and updateObjectsUnderConstruction.
- std::pair<ProgramStateRef, SVal> handleConstructionContext(
- const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
- const ConstructionContext *CC, EvalCallOptions &CallOpts) {
- SVal V = computeObjectUnderConstruction(E, State, LCtx, CC, CallOpts);
- return std::make_pair(
- updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts), V);
+ std::pair<ProgramStateRef, SVal>
+ handleConstructionContext(const Expr *E, ProgramStateRef State,
+ const LocationContext *LCtx,
+ const ConstructionContext *CC,
+ EvalCallOptions &CallOpts, unsigned Idx = 0) {
+
+ SVal V = computeObjectUnderConstruction(E, State, LCtx, CC, CallOpts, Idx);
+ State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
+
+ return std::make_pair(State, V);
}
private:
@@ -796,6 +814,15 @@ private:
const ExplodedNode *Pred,
const EvalCallOptions &CallOpts = {});
+ /// Checks whether our policies allow us to inline a non-POD type array
+ /// construction.
+ bool shouldInlineArrayConstruction(const ArrayType *Type);
+
+ /// Checks whether we construct an array of non-POD type, and decides if the
+ /// constructor should be inkoved once again.
+ bool shouldRepeatCtorCall(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
void inlineCall(WorkList *WList, const CallEvent &Call, const Decl *D,
NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State);
@@ -838,7 +865,7 @@ private:
const Expr *InitWithAdjustments, const Expr *Result = nullptr,
const SubRegion **OutRegionWithAdjustments = nullptr);
- /// Returns a region representing the first element of a (possibly
+ /// Returns a region representing the `Idx`th element of a (possibly
/// multi-dimensional) array, for the purposes of element construction or
/// destruction.
///
@@ -846,8 +873,8 @@ private:
///
/// If the type is not an array type at all, the original value is returned.
/// Otherwise the "IsArray" flag is set.
- static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
- QualType &Ty, bool &IsArray);
+ static SVal makeElementRegion(ProgramStateRef State, SVal LValue,
+ QualType &Ty, bool &IsArray, unsigned Idx = 0);
/// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG
/// block to find the constructor expression that directly constructed into
@@ -878,6 +905,17 @@ public:
const ObjCForCollectionStmt *O,
const LocationContext *LC);
private:
+ /// Assuming we construct an array of non-POD types, this method allows us
+ /// to store which element is to be constructed next.
+ static ProgramStateRef
+ setIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx, unsigned Idx);
+
+ static ProgramStateRef
+ removeIndexOfElementToConstruct(ProgramStateRef State,
+ const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
/// Store the location of a C++ object corresponding to a statement
/// until the statement is actually encountered. For example, if a DeclStmt
/// has CXXConstructExpr as its initializer, the object would be considered