diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -82,9 +82,11 @@ /// Deprecated. Use the `DataflowAnalysisOptions` constructor instead. explicit DataflowAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer) - : DataflowAnalysis(Context, {ApplyBuiltinTransfer - ? TransferOptions{} - : llvm::Optional()}) {} + : DataflowAnalysis( + Context, + {ApplyBuiltinTransfer + ? DataflowAnalysisContext::Options{} + : std::optional()}) {} explicit DataflowAnalysis(ASTContext &Context, DataflowAnalysisOptions Options) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -50,13 +50,22 @@ /// Returns the set of all fields in the type. llvm::DenseSet getObjectFields(QualType Type); +struct ContextSensitiveOptions { + /// The maximum depth to analyze. A value of zero is equivalent to disabling + /// context-sensitive analysis entirely. + unsigned Depth = 2; +}; + /// Owns objects that encompass the state of a program and stores context that /// is used during dataflow analysis. class DataflowAnalysisContext { public: - // FIXME: merge with TransferOptions from Transfer.h. struct Options { - bool EnableContextSensitiveAnalysis; + /// Options for analyzing function bodies when present in the translation + /// unit, or empty to disable context-sensitive analysis. Note that this is + /// fundamentally limited: some constructs, such as recursion, are + /// explicitly unsupported. + llvm::Optional ContextSensitiveOpts; }; /// Constructs a dataflow analysis context. @@ -65,10 +74,10 @@ /// /// `S` must not be null. DataflowAnalysisContext(std::unique_ptr S, - Options Opts = { - /*EnableContextSensitiveAnalysis=*/false}) + Options Opts = Options{ + /*ContextSensitiveOpts=*/std::nullopt}) : S(std::move(S)), TrueVal(createAtomicBoolValue()), - FalseVal(createAtomicBoolValue()), Options(Opts) { + FalseVal(createAtomicBoolValue()), Opts(Opts) { assert(this->S != nullptr); } @@ -262,6 +271,8 @@ void addFieldsReferencedInScope(llvm::DenseSet Fields); + const Options &getOptions() { return Opts; } + private: friend class Environment; @@ -345,7 +356,7 @@ AtomicBoolValue &TrueVal; AtomicBoolValue &FalseVal; - Options Options; + Options Opts; // Indices that are used to avoid recreating the same composite boolean // values. diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -177,6 +177,10 @@ /// with a symbolic representation of the `this` pointee. Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx); + const DataflowAnalysisContext::Options &getAnalysisOptions() { + return DACtx->getOptions(); + } + /// Creates and returns an environment to use for an inline analysis of the /// callee. Uses the storage location from each argument in the `Call` as the /// storage location for the corresponding parameter in the callee. diff --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h b/clang/include/clang/Analysis/FlowSensitive/Transfer.h --- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h +++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h @@ -15,26 +15,12 @@ #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H #include "clang/AST/Stmt.h" +#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" -#include "llvm/ADT/Optional.h" namespace clang { namespace dataflow { -struct ContextSensitiveOptions { - /// The maximum depth to analyze. A value of zero is equivalent to disabling - /// context-sensitive analysis entirely. - unsigned Depth = 2; -}; - -struct TransferOptions { - /// Options for analyzing function bodies when present in the translation - /// unit, or empty to disable context-sensitive analysis. Note that this is - /// fundamentally limited: some constructs, such as recursion, are explicitly - /// unsupported. - llvm::Optional ContextSensitiveOpts; -}; - /// Maps statements to the environments of basic blocks that contain them. class StmtToEnvMap { public: @@ -51,8 +37,7 @@ /// Requirements: /// /// `S` must not be `ParenExpr` or `ExprWithCleanups`. -void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, - TransferOptions Options); +void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env); } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h --- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h @@ -21,9 +21,9 @@ #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" -#include "clang/Analysis/FlowSensitive/Transfer.h" #include "llvm/ADT/Any.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Error.h" @@ -32,11 +32,12 @@ namespace dataflow { struct DataflowAnalysisOptions { - /// Options for the built-in transfer functions, or empty to not apply them. + /// Options for the built-in model, or empty to not apply them. // FIXME: Remove this option once the framework supports composing analyses // (at which point the built-in transfer functions can be simply a standalone // analysis). - llvm::Optional BuiltinTransferOpts = TransferOptions{}; + std::optional BuiltinOpts = + DataflowAnalysisContext::Options{}; }; /// Type-erased lattice element container. @@ -106,11 +107,11 @@ virtual void transferBranchTypeErased(bool Branch, const Stmt *, TypeErasedLattice &, Environment &) = 0; - /// If the built-in transfer functions (which model the heap and stack in the - /// `Environment`) are to be applied, returns the options to be passed to + /// If the built-in model is enabled, returns the options to be passed to /// them. Otherwise returns empty. - llvm::Optional builtinTransferOptions() const { - return Options.BuiltinTransferOpts; + const std::optional & + builtinOptions() const { + return Options.BuiltinOpts; } }; diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -48,9 +48,8 @@ // context-sensitive analysis. But, this only applies to storage locations, // since fields access it not allowed to fail. In contrast, field *values* // don't need this allowance, since the API allows for uninitialized fields. - auto Fields = Options.EnableContextSensitiveAnalysis - ? getObjectFields(Type) - : getReferencedFields(Type); + auto Fields = Opts.ContextSensitiveOpts ? getObjectFields(Type) + : getReferencedFields(Type); for (const FieldDecl *Field : Fields) FieldLocs.insert({Field, &createStorageLocation(Field->getType())}); return takeOwnership( diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -128,9 +128,8 @@ class TransferVisitor : public ConstStmtVisitor { public: - TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env, - TransferOptions Options) - : StmtToEnv(StmtToEnv), Env(Env), Options(Options) {} + TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env) + : StmtToEnv(StmtToEnv), Env(Env) {} void VisitBinaryOperator(const BinaryOperator *S) { const Expr *LHS = S->getLHS(); @@ -429,7 +428,7 @@ } void VisitReturnStmt(const ReturnStmt *S) { - if (!Options.ContextSensitiveOpts) + if (!Env.getAnalysisOptions().ContextSensitiveOpts) return; auto *Ret = S->getRetValue(); @@ -760,6 +759,7 @@ // `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(); if (!(Options.ContextSensitiveOpts && Env.canDescend(Options.ContextSensitiveOpts->Depth, F))) return; @@ -804,12 +804,10 @@ const StmtToEnvMap &StmtToEnv; Environment &Env; - TransferOptions Options; }; -void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, - TransferOptions Options) { - TransferVisitor(StmtToEnv, Env, Options).Visit(&S); +void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env) { + TransferVisitor(StmtToEnv, Env).Visit(&S); } } // namespace dataflow diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -95,9 +95,8 @@ : public ConstStmtVisitor { public: TerminatorVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env, - int BlockSuccIdx, TransferOptions TransferOpts) - : StmtToEnv(StmtToEnv), Env(Env), - BlockSuccIdx(BlockSuccIdx), TransferOpts(TransferOpts) {} + int BlockSuccIdx) + : StmtToEnv(StmtToEnv), Env(Env), BlockSuccIdx(BlockSuccIdx) {} TerminatorVisitorRetTy VisitIfStmt(const IfStmt *S) { auto *Cond = S->getCond(); @@ -142,7 +141,7 @@ TerminatorVisitorRetTy extendFlowCondition(const Expr &Cond) { // The terminator sub-expression might not be evaluated. if (Env.getStorageLocation(Cond, SkipPast::None) == nullptr) - transfer(StmtToEnv, Cond, Env, TransferOpts); + transfer(StmtToEnv, Cond, Env); // FIXME: The flow condition must be an r-value, so `SkipPast::None` should // suffice. @@ -178,7 +177,6 @@ const StmtToEnvMap &StmtToEnv; Environment &Env; int BlockSuccIdx; - TransferOptions TransferOpts; }; /// Holds data structures required for running dataflow analysis. @@ -248,8 +246,6 @@ llvm::Optional MaybeState; auto &Analysis = AC.Analysis; - auto BuiltinTransferOpts = Analysis.builtinTransferOptions(); - for (const CFGBlock *Pred : Preds) { // Skip if the `Block` is unreachable or control flow cannot get past it. if (!Pred || Pred->hasNoReturnElement()) @@ -263,13 +259,12 @@ continue; TypeErasedDataflowAnalysisState PredState = *MaybePredState; - if (BuiltinTransferOpts) { + if (Analysis.builtinOptions()) { if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) { const StmtToEnvMapImpl StmtToEnv(AC.CFCtx, AC.BlockStates); auto [Cond, CondValue] = TerminatorVisitor(StmtToEnv, PredState.Env, - blockIndexInPredecessor(*Pred, Block), - *BuiltinTransferOpts) + blockIndexInPredecessor(*Pred, Block)) .Visit(PredTerminatorStmt); if (Cond != nullptr) // FIXME: Call transferBranchTypeErased even if BuiltinTransferOpts @@ -301,8 +296,7 @@ AnalysisContext &AC) { const Stmt *S = Elt.getStmt(); assert(S != nullptr); - transfer(StmtToEnvMapImpl(AC.CFCtx, AC.BlockStates), *S, InputState.Env, - *AC.Analysis.builtinTransferOptions()); + transfer(StmtToEnvMapImpl(AC.CFCtx, AC.BlockStates), *S, InputState.Env); } /// Built-in transfer function for `CFGInitializer`. @@ -373,7 +367,7 @@ auto State = computeBlockInputState(Block, AC); for (const auto &Element : Block) { // Built-in analysis - if (AC.Analysis.builtinTransferOptions()) { + if (AC.Analysis.builtinOptions()) { builtinTransfer(Element, State, AC); } diff --git a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h --- a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h +++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h @@ -29,6 +29,7 @@ #include "clang/Analysis/CFG.h" #include "clang/Analysis/FlowSensitive/ControlFlowContext.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h" +#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/MatchSwitch.h" #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h" @@ -135,8 +136,8 @@ return std::move(*this); } AnalysisInputs && - withContextSensitivity() && { - EnableContextSensitivity = true; + withBuiltinOptions(DataflowAnalysisContext::Options Options) && { + BuiltinOptions = std::move(Options); return std::move(*this); } @@ -164,9 +165,8 @@ ArrayRef ASTBuildArgs = {}; /// Optional. Options for building the AST context. tooling::FileContentMappings ASTBuildVirtualMappedFiles = {}; - /// Enables context-sensitive analysis when constructing the - /// `DataflowAnalysisContext`. - bool EnableContextSensitivity = false; + /// Configuration options for the built-in model. + DataflowAnalysisContext::Options BuiltinOptions; }; /// Returns assertions based on annotations that are present after statements in @@ -230,9 +230,8 @@ auto &CFCtx = *MaybeCFCtx; // Initialize states for running dataflow analysis. - DataflowAnalysisContext DACtx( - std::make_unique(), - {/*EnableContextSensitiveAnalysis=*/AI.EnableContextSensitivity}); + DataflowAnalysisContext DACtx(std::make_unique(), + {/*Opts=*/AI.BuiltinOptions}); Environment InitEnv(DACtx, *Target); auto Analysis = AI.MakeAnalysis(Context, InitEnv); std::function void runDataflow(llvm::StringRef Code, Matcher Match, DataflowAnalysisOptions Options, @@ -44,15 +47,18 @@ "-fsyntax-only", "-fno-delayed-template-parsing", "-std=" + std::string(LangStandard::getLangStandardForKind(Std).getName())}; - auto AI = - AnalysisInputs(Code, hasName(TargetFun), - [&Options](ASTContext &C, Environment &) { - return NoopAnalysis(C, Options); - }) - .withASTBuildArgs(ASTBuildArgs); - if (Options.BuiltinTransferOpts && - Options.BuiltinTransferOpts->ContextSensitiveOpts) - (void)std::move(AI).withContextSensitivity(); + AnalysisInputs AI( + Code, hasName(TargetFun), + [UseBuiltinModel = Options.BuiltinOpts.has_value()](ASTContext &C, + Environment &Env) { + return NoopAnalysis( + C, DataflowAnalysisOptions{UseBuiltinModel + ? Env.getAnalysisOptions() + : llvm::Optional()}); + }); + AI.ASTBuildArgs = ASTBuildArgs; + if (Options.BuiltinOpts) + AI.BuiltinOptions = *Options.BuiltinOpts; ASSERT_THAT_ERROR( checkDataflow( std::move(AI), @@ -69,8 +75,8 @@ bool ApplyBuiltinTransfer = true, llvm::StringRef TargetFun = "target") { runDataflow(Code, std::move(Match), - {ApplyBuiltinTransfer ? TransferOptions{} - : llvm::Optional()}, + {ApplyBuiltinTransfer ? BuiltinOptions{} + : std::optional()}, Std, TargetFun); } @@ -4123,7 +4129,7 @@ EXPECT_FALSE(Env.flowConditionImplies(FooVal)); EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{/*.ContextSensitiveOpts=*/std::nullopt}}); + {BuiltinOptions{/*.ContextSensitiveOpts=*/std::nullopt}}); } // This test is a regression test, based on a real crash. @@ -4152,7 +4158,7 @@ EXPECT_THAT(Env.getValue(*Loc), IsNull()); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveDepthZero) { @@ -4180,7 +4186,7 @@ EXPECT_FALSE(Env.flowConditionImplies(FooVal)); EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{ContextSensitiveOptions{/*.Depth=*/0}}}); + {BuiltinOptions{ContextSensitiveOptions{/*.Depth=*/0}}}); } TEST(TransferTest, ContextSensitiveSetTrue) { @@ -4207,7 +4213,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveSetFalse) { @@ -4234,7 +4240,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveSetBothTrueAndFalse) { @@ -4271,7 +4277,7 @@ EXPECT_FALSE(Env.flowConditionImplies(BarVal)); EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(BarVal))); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveSetTwoLayersDepthOne) { @@ -4300,7 +4306,7 @@ EXPECT_FALSE(Env.flowConditionImplies(FooVal)); EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{ContextSensitiveOptions{/*.Depth=*/1}}}); + {BuiltinOptions{ContextSensitiveOptions{/*.Depth=*/1}}}); } TEST(TransferTest, ContextSensitiveSetTwoLayersDepthTwo) { @@ -4328,7 +4334,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{/*.Depth=*/2}}}); + {BuiltinOptions{ContextSensitiveOptions{/*.Depth=*/2}}}); } TEST(TransferTest, ContextSensitiveSetThreeLayersDepthTwo) { @@ -4358,7 +4364,7 @@ EXPECT_FALSE(Env.flowConditionImplies(FooVal)); EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{ContextSensitiveOptions{/*.Depth=*/2}}}); + {BuiltinOptions{ContextSensitiveOptions{/*.Depth=*/2}}}); } TEST(TransferTest, ContextSensitiveSetThreeLayersDepthThree) { @@ -4387,7 +4393,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{/*.Depth=*/3}}}); + {BuiltinOptions{ContextSensitiveOptions{/*.Depth=*/3}}}); } TEST(TransferTest, ContextSensitiveMutualRecursion) { @@ -4431,7 +4437,7 @@ EXPECT_FALSE(Env.flowConditionImplies(FooVal)); EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{ContextSensitiveOptions{/*.Depth=*/4}}}); + {BuiltinOptions{ContextSensitiveOptions{/*.Depth=*/4}}}); } TEST(TransferTest, ContextSensitiveSetMultipleLines) { @@ -4469,7 +4475,7 @@ EXPECT_FALSE(Env.flowConditionImplies(BarVal)); EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(BarVal))); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveSetMultipleBlocks) { @@ -4511,7 +4517,7 @@ EXPECT_TRUE(Env.flowConditionImplies(BazVal)); EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(BazVal))); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveReturnVoid) { @@ -4530,7 +4536,7 @@ ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); // This just tests that the analysis doesn't crash. }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveReturnTrue) { @@ -4555,7 +4561,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveReturnFalse) { @@ -4580,7 +4586,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(FooVal))); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveReturnArg) { @@ -4608,7 +4614,7 @@ auto &BazVal = *cast(Env.getValue(*BazDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(BazVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveReturnInt) { @@ -4627,7 +4633,7 @@ ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); // This just tests that the analysis doesn't crash. }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveMethodLiteral) { @@ -4656,7 +4662,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveMethodGetter) { @@ -4688,7 +4694,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveMethodSetter) { @@ -4720,7 +4726,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveMethodGetterAndSetter) { @@ -4754,7 +4760,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } @@ -4779,7 +4785,8 @@ Code, [](const llvm::StringMap> &Results, ASTContext &ASTCtx) { - ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));; + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + ; const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); @@ -4788,7 +4795,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveMethodTwoLayersReturn) { @@ -4812,7 +4819,8 @@ Code, [](const llvm::StringMap> &Results, ASTContext &ASTCtx) { - ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));; + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + ; const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); @@ -4821,7 +4829,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveConstructorBody) { @@ -4852,7 +4860,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveConstructorInitializer) { @@ -4883,7 +4891,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } TEST(TransferTest, ContextSensitiveConstructorDefault) { @@ -4914,7 +4922,7 @@ auto &FooVal = *cast(Env.getValue(*FooDecl, SkipPast::None)); EXPECT_TRUE(Env.flowConditionImplies(FooVal)); }, - {TransferOptions{ContextSensitiveOptions{}}}); + {BuiltinOptions{ContextSensitiveOptions{}}}); } } // namespace