Commit 2cdb6b84 authored by Samira Bazuzi's avatar Samira Bazuzi Committed by Yitzhak Mandelbaum
Browse files

[clang][dataflow] Expose DataflowAnalysisContext from DataflowEnvironment.

This will eliminate the need for more pass-through APIs. Also replace pass-through usages with this exposure.

Reviewed By: ymandel, gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D149464
parent 084ca632
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <memory>
#include <type_traits>
@@ -178,12 +179,16 @@ public:
  /// with a symbolic representation of the `this` pointee.
  Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx);

  LLVM_DEPRECATED("Use getDataflowAnalysisContext().getOptions() instead.", "")
  const DataflowAnalysisContext::Options &getAnalysisOptions() const {
    return DACtx->getOptions();
  }

  LLVM_DEPRECATED("Use getDataflowAnalysisContext().arena() instead.", "")
  Arena &arena() const { return DACtx->arena(); }

  LLVM_DEPRECATED("Use getDataflowAnalysisContext().getOptions().Log instead.",
                  "")
  Logger &logger() const { return *DACtx->getOptions().Log; }

  /// Creates and returns an environment to use for an inline analysis  of the
@@ -331,23 +336,23 @@ public:
  template <typename T, typename... Args>
  std::enable_if_t<std::is_base_of<Value, T>::value, T &>
  create(Args &&...args) {
    return arena().create<T>(std::forward<Args>(args)...);
    return DACtx->arena().create<T>(std::forward<Args>(args)...);
  }

  /// Returns a symbolic boolean value that models a boolean literal equal to
  /// `Value`
  AtomicBoolValue &getBoolLiteralValue(bool Value) const {
    return arena().makeLiteral(Value);
    return DACtx->arena().makeLiteral(Value);
  }

  /// Returns an atomic boolean value.
  BoolValue &makeAtomicBoolValue() const {
    return arena().create<AtomicBoolValue>();
    return DACtx->arena().create<AtomicBoolValue>();
  }

  /// Returns a unique instance of boolean Top.
  BoolValue &makeTopBoolValue() const {
    return arena().create<TopBoolValue>();
    return DACtx->arena().create<TopBoolValue>();
  }

  /// Returns a boolean value that represents the conjunction of `LHS` and
@@ -355,7 +360,7 @@ public:
  /// order, will return the same result. If the given boolean values represent
  /// the same value, the result will be the value itself.
  BoolValue &makeAnd(BoolValue &LHS, BoolValue &RHS) const {
    return arena().makeAnd(LHS, RHS);
    return DACtx->arena().makeAnd(LHS, RHS);
  }

  /// Returns a boolean value that represents the disjunction of `LHS` and
@@ -363,13 +368,13 @@ public:
  /// order, will return the same result. If the given boolean values represent
  /// the same value, the result will be the value itself.
  BoolValue &makeOr(BoolValue &LHS, BoolValue &RHS) const {
    return arena().makeOr(LHS, RHS);
    return DACtx->arena().makeOr(LHS, RHS);
  }

  /// Returns a boolean value that represents the negation of `Val`. Subsequent
  /// calls with the same argument will return the same result.
  BoolValue &makeNot(BoolValue &Val) const {
    return arena().makeNot(Val);
    return DACtx->arena().makeNot(Val);
  }

  /// Returns a boolean value represents `LHS` => `RHS`. Subsequent calls with
@@ -377,7 +382,7 @@ public:
  /// values represent the same value, the result will be a value that
  /// represents the true boolean literal.
  BoolValue &makeImplication(BoolValue &LHS, BoolValue &RHS) const {
    return arena().makeImplies(LHS, RHS);
    return DACtx->arena().makeImplies(LHS, RHS);
  }

  /// Returns a boolean value represents `LHS` <=> `RHS`. Subsequent calls with
@@ -385,7 +390,7 @@ public:
  /// result. If the given boolean values represent the same value, the result
  /// will be a value that represents the true boolean literal.
  BoolValue &makeIff(BoolValue &LHS, BoolValue &RHS) const {
    return arena().makeEquals(LHS, RHS);
    return DACtx->arena().makeEquals(LHS, RHS);
  }

  /// Returns the token that identifies the flow condition of the environment.
@@ -409,10 +414,15 @@ public:

  /// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise,
  /// returns null.
  LLVM_DEPRECATED(
      "Use getDataflowAnalysisContext().getControlFlowContext(F) instead.", "")
  const ControlFlowContext *getControlFlowContext(const FunctionDecl *F) {
    return DACtx->getControlFlowContext(F);
  }

  /// Returns the `DataflowAnalysisContext` used by the environment.
  DataflowAnalysisContext &getDataflowAnalysisContext() const { return *DACtx; }

  LLVM_DUMP_METHOD void dump() const;
  LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;

+5 −5
Original line number Diff line number Diff line
@@ -381,7 +381,7 @@ void Environment::pushCallInternal(const FunctionDecl *FuncDecl,

    QualType ParamType = Param->getType();
    if (ParamType->isReferenceType()) {
      auto &Val = arena().create<ReferenceValue>(*ArgLoc);
      auto &Val = DACtx->arena().create<ReferenceValue>(*ArgLoc);
      setValue(Loc, Val);
    } else if (auto *ArgVal = getValue(*ArgLoc)) {
      setValue(Loc, *ArgVal);
@@ -707,7 +707,7 @@ Value *Environment::createValueUnlessSelfReferential(
    // with integers, and so distinguishing them serves no purpose, but could
    // prevent convergence.
    CreatedValuesCount++;
    return &arena().create<IntegerValue>();
    return &DACtx->arena().create<IntegerValue>();
  }

  if (Type->isReferenceType() || Type->isPointerType()) {
@@ -725,9 +725,9 @@ Value *Environment::createValueUnlessSelfReferential(
    }

    if (Type->isReferenceType())
      return &arena().create<ReferenceValue>(PointeeLoc);
      return &DACtx->arena().create<ReferenceValue>(PointeeLoc);
    else
      return &arena().create<PointerValue>(PointeeLoc);
      return &DACtx->arena().create<PointerValue>(PointeeLoc);
  }

  if (Type->isRecordType()) {
@@ -747,7 +747,7 @@ Value *Environment::createValueUnlessSelfReferential(
      Visited.erase(FieldType.getCanonicalType());
    }

    return &arena().create<StructValue>(std::move(FieldValues));
    return &DACtx->arena().create<StructValue>(std::move(FieldValues));
  }

  return nullptr;
+4 −3
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ public:
  }

  void VisitReturnStmt(const ReturnStmt *S) {
    if (!Env.getAnalysisOptions().ContextSensitiveOpts)
    if (!Env.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts)
      return;

    auto *Ret = S->getRetValue();
@@ -863,12 +863,13 @@ private:
  // `F` of `S`. The type `E` must be either `CallExpr` or `CXXConstructExpr`.
  template <typename E>
  void transferInlineCall(const E *S, const FunctionDecl *F) {
    const auto &Options = Env.getAnalysisOptions();
    const auto &Options = Env.getDataflowAnalysisContext().getOptions();
    if (!(Options.ContextSensitiveOpts &&
          Env.canDescend(Options.ContextSensitiveOpts->Depth, F)))
      return;

    const ControlFlowContext *CFCtx = Env.getControlFlowContext(F);
    const ControlFlowContext *CFCtx =
        Env.getDataflowAnalysisContext().getControlFlowContext(F);
    if (!CFCtx)
      return;

+2 −1
Original line number Diff line number Diff line
@@ -168,7 +168,8 @@ struct AnalysisContext {
                  llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
                      BlockStates)
      : CFCtx(CFCtx), Analysis(Analysis), InitEnv(InitEnv),
        Log(InitEnv.logger()), BlockStates(BlockStates) {
        Log(*InitEnv.getDataflowAnalysisContext().getOptions().Log),
        BlockStates(BlockStates) {
    Log.beginAnalysis(CFCtx, Analysis);
  }
  ~AnalysisContext() { Log.endAnalysis(); }
+6 −4
Original line number Diff line number Diff line
@@ -37,12 +37,14 @@ public:

  static TestLattice initialElement() { return TestLattice{}; }
  void transfer(const CFGElement &, TestLattice &L, Environment &E) {
    E.logger().log([](llvm::raw_ostream &OS) { OS << "transfer()"; });
    E.getDataflowAnalysisContext().getOptions().Log->log(
        [](llvm::raw_ostream &OS) { OS << "transfer()"; });
    ++L.Elements;
  }
  void transferBranch(bool Branch, const Stmt *S, TestLattice &L,
                      Environment &E) {
    E.logger().log([&](llvm::raw_ostream &OS) {
    E.getDataflowAnalysisContext().getOptions().Log->log(
        [&](llvm::raw_ostream &OS) {
          OS << "transferBranch(" << Branch << ")";
        });
    ++L.Branches;
Loading