diff options
Diffstat (limited to 'clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h')
-rw-r--r-- | clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h | 50 |
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. |