diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 8690616411db9..9c027ef4552ee 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -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 #include @@ -178,12 +179,16 @@ class Environment { /// 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 @@ class Environment { template std::enable_if_t::value, T &> create(Args &&...args) { - return arena().create(std::forward(args)...); + return DACtx->arena().create(std::forward(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(); + return DACtx->arena().create(); } /// Returns a unique instance of boolean Top. BoolValue &makeTopBoolValue() const { - return arena().create(); + return DACtx->arena().create(); } /// Returns a boolean value that represents the conjunction of `LHS` and @@ -355,7 +360,7 @@ class Environment { /// 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 @@ class Environment { /// 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 @@ class Environment { /// 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 @@ class Environment { /// 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 @@ class Environment { /// 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; diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 35988af6d5bc6..91969cd3386b2 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -381,7 +381,7 @@ void Environment::pushCallInternal(const FunctionDecl *FuncDecl, QualType ParamType = Param->getType(); if (ParamType->isReferenceType()) { - auto &Val = arena().create(*ArgLoc); + auto &Val = DACtx->arena().create(*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(); + return &DACtx->arena().create(); } if (Type->isReferenceType() || Type->isPointerType()) { @@ -725,9 +725,9 @@ Value *Environment::createValueUnlessSelfReferential( } if (Type->isReferenceType()) - return &arena().create(PointeeLoc); + return &DACtx->arena().create(PointeeLoc); else - return &arena().create(PointeeLoc); + return &DACtx->arena().create(PointeeLoc); } if (Type->isRecordType()) { @@ -747,7 +747,7 @@ Value *Environment::createValueUnlessSelfReferential( Visited.erase(FieldType.getCanonicalType()); } - return &arena().create(std::move(FieldValues)); + return &DACtx->arena().create(std::move(FieldValues)); } return nullptr; diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 0814257d5cd37..a11ff8668236e 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -496,7 +496,7 @@ class TransferVisitor : public ConstStmtVisitor { } void VisitReturnStmt(const ReturnStmt *S) { - if (!Env.getAnalysisOptions().ContextSensitiveOpts) + if (!Env.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts) return; auto *Ret = S->getRetValue(); @@ -863,12 +863,13 @@ class TransferVisitor : public ConstStmtVisitor { // `F` of `S`. The type `E` must be either `CallExpr` or `CXXConstructExpr`. template 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; diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index ad250c432e2c5..99319620f43f9 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -168,7 +168,8 @@ struct AnalysisContext { llvm::ArrayRef> 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(); } diff --git a/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp b/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp index 7ba19b86dd102..7201771e0b118 100644 --- a/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp @@ -37,14 +37,16 @@ class TestAnalysis : public DataflowAnalysis { 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) { - OS << "transferBranch(" << Branch << ")"; - }); + E.getDataflowAnalysisContext().getOptions().Log->log( + [&](llvm::raw_ostream &OS) { + OS << "transferBranch(" << Branch << ")"; + }); ++L.Branches; } }; diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 1589067a81c7b..750d095af451a 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -53,9 +53,10 @@ void runDataflow(llvm::StringRef Code, Matcher Match, [UseBuiltinModel = Options.BuiltinOpts.has_value()](ASTContext &C, Environment &Env) { return NoopAnalysis( - C, DataflowAnalysisOptions{UseBuiltinModel - ? Env.getAnalysisOptions() - : std::optional()}); + C, + DataflowAnalysisOptions{ + UseBuiltinModel ? Env.getDataflowAnalysisContext().getOptions() + : std::optional()}); }); AI.ASTBuildArgs = ASTBuildArgs; if (Options.BuiltinOpts)