summaryrefslogtreecommitdiffstats
path: root/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h')
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h50
1 files changed, 32 insertions, 18 deletions
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674..9a65f76cdf56 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -43,6 +43,15 @@ enum class ComparisonResult {
Unknown,
};
+/// The result of a `widen` operation.
+struct WidenResult {
+ /// Non-null pointer to a potentially widened version of the input value.
+ Value *V;
+ /// Whether `V` represents a "change" (that is, a different value) with
+ /// respect to the previous value in the sequence.
+ LatticeEffect Effect;
+};
+
/// Holds the state of the program (store and heap) at a given program point.
///
/// WARNING: Symbolic values that are created by the environment for static
@@ -104,14 +113,17 @@ public:
/// serve as a comparison operation, by indicating whether the widened value
/// is equivalent to the previous value.
///
- /// Returns either:
- ///
- /// `nullptr`, if this value is not of interest to the model, or
- ///
- /// `&Prev`, if the widened value is equivalent to `Prev`, or
- ///
- /// A non-null value that approximates `Current`. `Prev` is available to
- /// inform the chosen approximation.
+ /// Returns one of the folowing:
+ /// * `std::nullopt`, if this value is not of interest to the
+ /// model.
+ /// * A `WidenResult` with:
+ /// * A non-null `Value *` that points either to `Current` or a widened
+ /// version of `Current`. This value must be consistent with
+ /// the flow condition of `CurrentEnv`. We particularly caution
+ /// against using `Prev`, which is rarely consistent.
+ /// * A `LatticeEffect` indicating whether the value should be
+ /// considered a new value (`Changed`) or one *equivalent* (if not
+ /// necessarily equal) to `Prev` (`Unchanged`).
///
/// `PrevEnv` and `CurrentEnv` can be used to query child values and path
/// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +134,19 @@ public:
///
/// `Prev` and `Current` must be assigned to the same storage location in
/// `PrevEnv` and `CurrentEnv`, respectively.
- virtual Value *widen(QualType Type, Value &Prev, const Environment &PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+ virtual std::optional<WidenResult> widen(QualType Type, Value &Prev,
+ const Environment &PrevEnv,
+ Value &Current,
+ Environment &CurrentEnv) {
// The default implementation reduces to just comparison, since comparison
// is required by the API, even if no widening is performed.
switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
- case ComparisonResult::Same:
- return &Prev;
- case ComparisonResult::Different:
- return &Current;
- case ComparisonResult::Unknown:
- return nullptr;
+ case ComparisonResult::Unknown:
+ return std::nullopt;
+ case ComparisonResult::Same:
+ return WidenResult{&Current, LatticeEffect::Unchanged};
+ case ComparisonResult::Different:
+ return WidenResult{&Current, LatticeEffect::Changed};
}
llvm_unreachable("all cases in switch covered");
}
@@ -236,8 +250,8 @@ public:
///
/// `PrevEnv` must be the immediate previous version of the environment.
/// `PrevEnv` and `this` must use the same `DataflowAnalysisContext`.
- LatticeJoinEffect widen(const Environment &PrevEnv,
- Environment::ValueModel &Model);
+ LatticeEffect widen(const Environment &PrevEnv,
+ Environment::ValueModel &Model);
// FIXME: Rename `createOrGetStorageLocation` to `getOrCreateStorageLocation`,
// `getStableStorageLocation`, or something more appropriate.