wyt updated this revision to Diff 456317.
wyt marked 2 inline comments as done.
wyt added a comment.

Address comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D132756/new/

https://reviews.llvm.org/D132756

Files:
  clang/unittests/Analysis/FlowSensitive/TestingSupport.h
  clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -24,8 +24,10 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Testing/ADT/StringMapEntry.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -42,12 +44,10 @@
 using namespace dataflow;
 using namespace test;
 using namespace ast_matchers;
-using ::testing::_;
-using ::testing::ElementsAre;
+using llvm::IsStringMapEntry;
+using ::testing::DescribeMatcher;
 using ::testing::IsEmpty;
-using ::testing::IsNull;
 using ::testing::NotNull;
-using ::testing::Pair;
 using ::testing::Test;
 using ::testing::UnorderedElementsAre;
 
@@ -130,7 +130,8 @@
 }
 
 struct FunctionCallLattice {
-  llvm::SmallSet<std::string, 8> CalledFunctions;
+  using FunctionSet = llvm::SmallSet<std::string, 8>;
+  FunctionSet CalledFunctions;
 
   bool operator==(const FunctionCallLattice &Other) const {
     return CalledFunctions == Other.CalledFunctions;
@@ -197,16 +198,24 @@
 
     ASSERT_THAT_ERROR(
         test::checkDataflow<FunctionCallAnalysis>(
-            Code, "target",
-            [](ASTContext &C, Environment &) {
-              return FunctionCallAnalysis(C);
+            /*AI:AnalysisInputs=*/
+            {
+                .Code = Code,
+                .TargetFuncMatcher = ast_matchers::hasName("target"),
+                .MakeAnalysis =
+                    [](ASTContext &C, Environment &) {
+                      return FunctionCallAnalysis(C);
+                    },
+                .ASTBuildArgs = {"-fsyntax-only", "-std=c++17"},
+                .ASTBuildVirtualMappedFiles = FilesContents,
             },
+            /*VerifyResults=*/
             [&Expectations](
-                llvm::ArrayRef<std::pair<
-                    std::string, DataflowAnalysisState<FunctionCallLattice>>>
-                    Results,
-                ASTContext &) { EXPECT_THAT(Results, Expectations); },
-            {"-fsyntax-only", "-std=c++17"}, FilesContents),
+                const llvm::StringMap<
+                    DataflowAnalysisState<FunctionCallLattice>> &Results,
+                const AnalysisOutputs &) {
+              EXPECT_THAT(Results, Expectations);
+            }),
         llvm::Succeeded());
   }
 };
@@ -214,12 +223,16 @@
 MATCHER_P(HoldsFunctionCallLattice, m,
           ((negation ? "doesn't hold" : "holds") +
            llvm::StringRef(" a lattice element that ") +
-           ::testing::DescribeMatcher<FunctionCallLattice>(m, negation))
+           DescribeMatcher<FunctionCallLattice>(m))
               .str()) {
   return ExplainMatchResult(m, arg.Lattice, result_listener);
 }
 
-MATCHER_P(HasCalledFunctions, m, "") {
+MATCHER_P(HasCalledFunctions, m,
+          ((negation ? "doesn't hold" : "holds") +
+           llvm::StringRef(" a set of called functions that ") +
+           DescribeMatcher<FunctionCallLattice::FunctionSet>(m))
+              .str()) {
   return ExplainMatchResult(m, arg.CalledFunctions, result_listener);
 }
 
@@ -233,9 +246,9 @@
       // [[p]]
     }
   )";
-  runDataflow(Code, UnorderedElementsAre(
-                        Pair("p", HoldsFunctionCallLattice(HasCalledFunctions(
-                                      UnorderedElementsAre("foo", "bar"))))));
+  runDataflow(Code, UnorderedElementsAre(IsStringMapEntry(
+                        "p", HoldsFunctionCallLattice(HasCalledFunctions(
+                                 UnorderedElementsAre("foo", "bar"))))));
 }
 
 TEST_F(NoreturnDestructorTest, ConditionalOperatorLeftBranchReturns) {
@@ -248,9 +261,9 @@
       // [[p]]
     }
   )";
-  runDataflow(Code, UnorderedElementsAre(
-                        Pair("p", HoldsFunctionCallLattice(HasCalledFunctions(
-                                      UnorderedElementsAre("foo"))))));
+  runDataflow(Code, UnorderedElementsAre(IsStringMapEntry(
+                        "p", HoldsFunctionCallLattice(HasCalledFunctions(
+                                 UnorderedElementsAre("foo"))))));
 }
 
 TEST_F(NoreturnDestructorTest, ConditionalOperatorRightBranchReturns) {
@@ -263,9 +276,9 @@
       // [[p]]
     }
   )";
-  runDataflow(Code, UnorderedElementsAre(
-                        Pair("p", HoldsFunctionCallLattice(HasCalledFunctions(
-                                      UnorderedElementsAre("foo"))))));
+  runDataflow(Code, UnorderedElementsAre(IsStringMapEntry(
+                        "p", HoldsFunctionCallLattice(HasCalledFunctions(
+                                 UnorderedElementsAre("foo"))))));
 }
 
 TEST_F(NoreturnDestructorTest, ConditionalOperatorNestedBranchesDoNotReturn) {
@@ -292,9 +305,9 @@
       // [[p]]
     }
   )";
-  runDataflow(Code, UnorderedElementsAre(
-                        Pair("p", HoldsFunctionCallLattice(HasCalledFunctions(
-                                      UnorderedElementsAre("baz", "foo"))))));
+  runDataflow(Code, UnorderedElementsAre(IsStringMapEntry(
+                        "p", HoldsFunctionCallLattice(HasCalledFunctions(
+                                 UnorderedElementsAre("baz", "foo"))))));
   // FIXME: Called functions at point `p` should contain only "foo".
 }
 
@@ -388,16 +401,21 @@
   void runDataflow(llvm::StringRef Code, Matcher Match) {
     ASSERT_THAT_ERROR(
         test::checkDataflow<SpecialBoolAnalysis>(
-            Code, "target",
-            [](ASTContext &Context, Environment &Env) {
-              return SpecialBoolAnalysis(Context);
+            /*AI:AnalysisInputs=*/
+            {
+                .Code = Code,
+                .TargetFuncMatcher = ast_matchers::hasName("target"),
+                .MakeAnalysis =
+                    [](ASTContext &Context, Environment &Env) {
+                      return SpecialBoolAnalysis(Context);
+                    },
+                .ASTBuildArgs = {"-fsyntax-only", "-std=c++17"},
             },
-            [&Match](
-                llvm::ArrayRef<
-                    std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                    Results,
-                ASTContext &ASTCtx) { Match(Results, ASTCtx); },
-            {"-fsyntax-only", "-std=c++17"}),
+            /*VerifyResults=*/[&Match](const llvm::StringMap<
+                                           DataflowAnalysisState<NoopLattice>>
+                                           &Results,
+                                       const AnalysisOutputs
+                                           &AO) { Match(Results, AO.ASTCtx); }),
         llvm::Succeeded());
   }
 };
@@ -424,16 +442,15 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
-        ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _),
-                                         Pair("p3", _), Pair("p4", _)));
-        const Environment &Env1 = Results[0].second.Env;
-        const Environment &Env2 = Results[1].second.Env;
-        const Environment &Env3 = Results[2].second.Env;
-        const Environment &Env4 = Results[3].second.Env;
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(),
+                    UnorderedElementsAre("p1", "p2", "p3", "p4"));
+        const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+        const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+        const Environment &Env3 = getEnvironmentAtAnnotation(Results, "p3");
+        const Environment &Env4 = getEnvironmentAtAnnotation(Results, "p4");
 
         const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
         ASSERT_THAT(FooDecl, NotNull());
@@ -539,20 +556,26 @@
       };
     )"));
     ASSERT_THAT_ERROR(
-        test::checkDataflow<OptionalIntAnalysis>(
-            Code, "target",
-            [this](ASTContext &Context, Environment &Env) {
-              assert(HasValueTop == nullptr);
-              HasValueTop =
-                  &Env.takeOwnership(std::make_unique<AtomicBoolValue>());
-              return OptionalIntAnalysis(Context, *HasValueTop);
+        checkDataflow<OptionalIntAnalysis>(
+            /*AI:AnalysisInputs=*/
+            {
+                .Code = Code,
+                .TargetFuncMatcher = ast_matchers::hasName("target"),
+                .MakeAnalysis =
+                    [this](ASTContext &Context, Environment &Env) {
+                      assert(HasValueTop == nullptr);
+                      HasValueTop = &Env.takeOwnership(
+                          std::make_unique<AtomicBoolValue>());
+                      return OptionalIntAnalysis(Context, *HasValueTop);
+                    },
+                .ASTBuildArgs = {"-fsyntax-only", "-std=c++17"},
+                .ASTBuildVirtualMappedFiles = FilesContents,
             },
-            [&Match](
-                llvm::ArrayRef<
-                    std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                    Results,
-                ASTContext &ASTCtx) { Match(Results, ASTCtx); },
-            {"-fsyntax-only", "-std=c++17"}, FilesContents),
+            /*VerifyResults=*/[&Match](const llvm::StringMap<
+                                           DataflowAnalysisState<NoopLattice>>
+                                           &Results,
+                                       const AnalysisOutputs
+                                           &AO) { Match(Results, AO.ASTCtx); }),
         llvm::Succeeded());
   }
 
@@ -576,15 +599,12 @@
   )";
   runDataflow(
       Code,
-      [this](llvm::ArrayRef<
-                 std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                 Results,
+      [this](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
              ASTContext &ASTCtx) {
-        ASSERT_THAT(Results,
-                    ElementsAre(Pair("p1", _), Pair("p2", _), Pair("p3", _)));
-        const Environment &Env1 = Results[0].second.Env;
-        const Environment &Env2 = Results[1].second.Env;
-        const Environment &Env3 = Results[2].second.Env;
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2", "p3"));
+        const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+        const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+        const Environment &Env3 = getEnvironmentAtAnnotation(Results, "p3");
 
         const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
         ASSERT_THAT(FooDecl, NotNull());
@@ -619,34 +639,33 @@
       /*[[p4]]*/
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _),
-                                                 Pair("p3", _), Pair("p4", _)));
-                const Environment &Env1 = Results[0].second.Env;
-                const Environment &Env2 = Results[1].second.Env;
-                const Environment &Env3 = Results[2].second.Env;
-                const Environment &Env4 = Results[3].second.Env;
-
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                auto GetFooValue = [FooDecl](const Environment &Env) {
-                  return Env.getValue(*FooDecl, SkipPast::None);
-                };
-
-                EXPECT_EQ(GetFooValue(Env1)->getProperty("has_value"),
-                          &Env1.getBoolLiteralValue(false));
-                EXPECT_EQ(GetFooValue(Env2)->getProperty("has_value"),
-                          &Env2.getBoolLiteralValue(true));
-                EXPECT_EQ(GetFooValue(Env3)->getProperty("has_value"),
-                          &Env3.getBoolLiteralValue(true));
-                EXPECT_EQ(GetFooValue(Env4)->getProperty("has_value"),
-                          &Env4.getBoolLiteralValue(true));
-              });
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(),
+                    UnorderedElementsAre("p1", "p2", "p3", "p4"));
+        const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+        const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+        const Environment &Env3 = getEnvironmentAtAnnotation(Results, "p3");
+        const Environment &Env4 = getEnvironmentAtAnnotation(Results, "p4");
+
+        const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+        ASSERT_THAT(FooDecl, NotNull());
+
+        auto GetFooValue = [FooDecl](const Environment &Env) {
+          return Env.getValue(*FooDecl, SkipPast::None);
+        };
+
+        EXPECT_EQ(GetFooValue(Env1)->getProperty("has_value"),
+                  &Env1.getBoolLiteralValue(false));
+        EXPECT_EQ(GetFooValue(Env2)->getProperty("has_value"),
+                  &Env2.getBoolLiteralValue(true));
+        EXPECT_EQ(GetFooValue(Env3)->getProperty("has_value"),
+                  &Env3.getBoolLiteralValue(true));
+        EXPECT_EQ(GetFooValue(Env4)->getProperty("has_value"),
+                  &Env4.getBoolLiteralValue(true));
+      });
 }
 
 TEST_F(WideningTest, DistinctPointersToTheSameLocationAreEquivalent) {
@@ -660,26 +679,25 @@
       // [[p]]
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
-                const Environment &Env = Results[0].second.Env;
-
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
-                ASSERT_THAT(BarDecl, NotNull());
-
-                const auto *FooLoc = cast<ScalarStorageLocation>(
-                    Env.getStorageLocation(*FooDecl, SkipPast::None));
-                const auto *BarVal =
-                    cast<PointerValue>(Env.getValue(*BarDecl, SkipPast::None));
-                EXPECT_EQ(&BarVal->getPointeeLoc(), FooLoc);
-              });
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+        const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+        ASSERT_THAT(FooDecl, NotNull());
+
+        const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+        ASSERT_THAT(BarDecl, NotNull());
+
+        const auto *FooLoc = cast<ScalarStorageLocation>(
+            Env.getStorageLocation(*FooDecl, SkipPast::None));
+        const auto *BarVal =
+            cast<PointerValue>(Env.getValue(*BarDecl, SkipPast::None));
+        EXPECT_EQ(&BarVal->getPointeeLoc(), FooLoc);
+      });
 }
 
 TEST_F(WideningTest, DistinctValuesWithSamePropertiesAreEquivalent) {
@@ -696,21 +714,20 @@
       /*[[p]]*/
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
-                const Environment &Env = Results[0].second.Env;
-
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                const auto *FooVal = Env.getValue(*FooDecl, SkipPast::None);
-                EXPECT_EQ(FooVal->getProperty("has_value"),
-                          &Env.getBoolLiteralValue(true));
-              });
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+        const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+        ASSERT_THAT(FooDecl, NotNull());
+
+        const auto *FooVal = Env.getValue(*FooDecl, SkipPast::None);
+        EXPECT_EQ(FooVal->getProperty("has_value"),
+                  &Env.getBoolLiteralValue(true));
+      });
 }
 
 class FlowConditionTest : public Test {
@@ -718,17 +735,22 @@
   template <typename Matcher>
   void runDataflow(llvm::StringRef Code, Matcher Match) {
     ASSERT_THAT_ERROR(
-        test::checkDataflow<NoopAnalysis>(
-            Code, "target",
-            [](ASTContext &Context, Environment &Env) {
-              return NoopAnalysis(Context, true);
+        checkDataflow<NoopAnalysis>(
+            /*AI:AnalysisInputs=*/
+            {
+                .Code = Code,
+                .TargetFuncMatcher = ast_matchers::hasName("target"),
+                .MakeAnalysis =
+                    [](ASTContext &Context, Environment &Env) {
+                      return NoopAnalysis(Context, true);
+                    },
+                .ASTBuildArgs = {"-fsyntax-only", "-std=c++17"},
             },
-            [&Match](
-                llvm::ArrayRef<
-                    std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                    Results,
-                ASTContext &ASTCtx) { Match(Results, ASTCtx); },
-            {"-fsyntax-only", "-std=c++17"}),
+            /*VerifyResults=*/[&Match](const llvm::StringMap<
+                                           DataflowAnalysisState<NoopLattice>>
+                                           &Results,
+                                       const AnalysisOutputs
+                                           &AO) { Match(Results, AO.ASTCtx); }),
         llvm::Succeeded());
   }
 };
@@ -745,26 +767,25 @@
       }
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
-
-                const Environment &Env1 = Results[0].second.Env;
-                auto *FooVal1 =
-                    cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
-                EXPECT_TRUE(Env1.flowConditionImplies(*FooVal1));
-
-                const Environment &Env2 = Results[1].second.Env;
-                auto *FooVal2 =
-                    cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
-                EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
-              });
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+        ASSERT_THAT(FooDecl, NotNull());
+
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
+        const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+        auto *FooVal1 =
+            cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
+        EXPECT_TRUE(Env1.flowConditionImplies(*FooVal1));
+
+        const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+        auto *FooVal2 =
+            cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
+        EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
+      });
 }
 
 TEST_F(FlowConditionTest, IfStmtSingleNegatedVar) {
@@ -779,26 +800,25 @@
       }
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
-
-                const Environment &Env1 = Results[0].second.Env;
-                auto *FooVal1 =
-                    cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
-                EXPECT_FALSE(Env1.flowConditionImplies(*FooVal1));
-
-                const Environment &Env2 = Results[1].second.Env;
-                auto *FooVal2 =
-                    cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
-                EXPECT_TRUE(Env2.flowConditionImplies(*FooVal2));
-              });
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+        ASSERT_THAT(FooDecl, NotNull());
+
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
+        const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+        auto *FooVal1 =
+            cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
+        EXPECT_FALSE(Env1.flowConditionImplies(*FooVal1));
+
+        const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+        auto *FooVal2 =
+            cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
+        EXPECT_TRUE(Env2.flowConditionImplies(*FooVal2));
+      });
 }
 
 TEST_F(FlowConditionTest, WhileStmt) {
@@ -811,15 +831,14 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
         const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
         ASSERT_THAT(FooDecl, NotNull());
 
-        ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
-        const Environment &Env = Results[0].second.Env;
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
 
         auto *FooVal = cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
         EXPECT_TRUE(Env.flowConditionImplies(*FooVal));
@@ -838,35 +857,29 @@
       }
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
-                ASSERT_THAT(BarDecl, NotNull());
-
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
-
-                const Environment &Env1 = Results[0].second.Env;
-                auto *FooVal1 =
-                    cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal1 =
-                    cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
-                EXPECT_TRUE(Env1.flowConditionImplies(*FooVal1));
-                EXPECT_TRUE(Env1.flowConditionImplies(*BarVal1));
-
-                const Environment &Env2 = Results[1].second.Env;
-                auto *FooVal2 =
-                    cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal2 =
-                    cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
-                EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
-                EXPECT_FALSE(Env2.flowConditionImplies(*BarVal2));
-              });
+  runDataflow(Code, [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>>
+                           &Results,
+                       ASTContext &ASTCtx) {
+    const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+    ASSERT_THAT(FooDecl, NotNull());
+
+    const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+    ASSERT_THAT(BarDecl, NotNull());
+
+    ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
+    const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+    auto *FooVal1 = cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal1 = cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
+    EXPECT_TRUE(Env1.flowConditionImplies(*FooVal1));
+    EXPECT_TRUE(Env1.flowConditionImplies(*BarVal1));
+
+    const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+    auto *FooVal2 = cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal2 = cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
+    EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
+    EXPECT_FALSE(Env2.flowConditionImplies(*BarVal2));
+  });
 }
 
 TEST_F(FlowConditionTest, Disjunction) {
@@ -881,35 +894,29 @@
       }
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
-                ASSERT_THAT(BarDecl, NotNull());
-
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
-
-                const Environment &Env1 = Results[0].second.Env;
-                auto *FooVal1 =
-                    cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal1 =
-                    cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
-                EXPECT_FALSE(Env1.flowConditionImplies(*FooVal1));
-                EXPECT_FALSE(Env1.flowConditionImplies(*BarVal1));
-
-                const Environment &Env2 = Results[1].second.Env;
-                auto *FooVal2 =
-                    cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal2 =
-                    cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
-                EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
-                EXPECT_FALSE(Env2.flowConditionImplies(*BarVal2));
-              });
+  runDataflow(Code, [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>>
+                           &Results,
+                       ASTContext &ASTCtx) {
+    const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+    ASSERT_THAT(FooDecl, NotNull());
+
+    const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+    ASSERT_THAT(BarDecl, NotNull());
+
+    ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
+    const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+    auto *FooVal1 = cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal1 = cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
+    EXPECT_FALSE(Env1.flowConditionImplies(*FooVal1));
+    EXPECT_FALSE(Env1.flowConditionImplies(*BarVal1));
+
+    const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+    auto *FooVal2 = cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal2 = cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
+    EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
+    EXPECT_FALSE(Env2.flowConditionImplies(*BarVal2));
+  });
 }
 
 TEST_F(FlowConditionTest, NegatedConjunction) {
@@ -924,35 +931,29 @@
       }
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
-                ASSERT_THAT(BarDecl, NotNull());
-
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
-
-                const Environment &Env1 = Results[0].second.Env;
-                auto *FooVal1 =
-                    cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal1 =
-                    cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
-                EXPECT_FALSE(Env1.flowConditionImplies(*FooVal1));
-                EXPECT_FALSE(Env1.flowConditionImplies(*BarVal1));
-
-                const Environment &Env2 = Results[1].second.Env;
-                auto *FooVal2 =
-                    cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal2 =
-                    cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
-                EXPECT_TRUE(Env2.flowConditionImplies(*FooVal2));
-                EXPECT_TRUE(Env2.flowConditionImplies(*BarVal2));
-              });
+  runDataflow(Code, [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>>
+                           &Results,
+                       ASTContext &ASTCtx) {
+    const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+    ASSERT_THAT(FooDecl, NotNull());
+
+    const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+    ASSERT_THAT(BarDecl, NotNull());
+
+    ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
+    const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+    auto *FooVal1 = cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal1 = cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
+    EXPECT_FALSE(Env1.flowConditionImplies(*FooVal1));
+    EXPECT_FALSE(Env1.flowConditionImplies(*BarVal1));
+
+    const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+    auto *FooVal2 = cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal2 = cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
+    EXPECT_TRUE(Env2.flowConditionImplies(*FooVal2));
+    EXPECT_TRUE(Env2.flowConditionImplies(*BarVal2));
+  });
 }
 
 TEST_F(FlowConditionTest, DeMorgan) {
@@ -967,35 +968,29 @@
       }
     }
   )";
-  runDataflow(Code,
-              [](llvm::ArrayRef<
-                     std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                     Results,
-                 ASTContext &ASTCtx) {
-                const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
-                ASSERT_THAT(FooDecl, NotNull());
-
-                const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
-                ASSERT_THAT(BarDecl, NotNull());
-
-                ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
-
-                const Environment &Env1 = Results[0].second.Env;
-                auto *FooVal1 =
-                    cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal1 =
-                    cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
-                EXPECT_TRUE(Env1.flowConditionImplies(*FooVal1));
-                EXPECT_TRUE(Env1.flowConditionImplies(*BarVal1));
-
-                const Environment &Env2 = Results[1].second.Env;
-                auto *FooVal2 =
-                    cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
-                auto *BarVal2 =
-                    cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
-                EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
-                EXPECT_FALSE(Env2.flowConditionImplies(*BarVal2));
-              });
+  runDataflow(Code, [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>>
+                           &Results,
+                       ASTContext &ASTCtx) {
+    const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+    ASSERT_THAT(FooDecl, NotNull());
+
+    const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+    ASSERT_THAT(BarDecl, NotNull());
+
+    ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
+    const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
+    auto *FooVal1 = cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal1 = cast<BoolValue>(Env1.getValue(*BarDecl, SkipPast::None));
+    EXPECT_TRUE(Env1.flowConditionImplies(*FooVal1));
+    EXPECT_TRUE(Env1.flowConditionImplies(*BarVal1));
+
+    const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
+    auto *FooVal2 = cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::None));
+    auto *BarVal2 = cast<BoolValue>(Env2.getValue(*BarDecl, SkipPast::None));
+    EXPECT_FALSE(Env2.flowConditionImplies(*FooVal2));
+    EXPECT_FALSE(Env2.flowConditionImplies(*BarVal2));
+  });
 }
 
 TEST_F(FlowConditionTest, Join) {
@@ -1013,16 +1008,15 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
-        ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
 
         const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
         ASSERT_THAT(FooDecl, NotNull());
 
-        const Environment &Env = Results[0].second.Env;
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
         auto *FooVal = cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
         EXPECT_TRUE(Env.flowConditionImplies(*FooVal));
       });
@@ -1047,12 +1041,11 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
-        ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
-        const Environment &Env = Results[0].second.Env;
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
 
         const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
         ASSERT_THAT(BarDecl, NotNull());
@@ -1090,12 +1083,11 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
-        ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
-        const Environment &Env = Results[0].second.Env;
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
 
         const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
         ASSERT_THAT(BarDecl, NotNull());
@@ -1126,12 +1118,11 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
-        ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
-        const Environment &Env = Results[0].second.Env;
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
 
         const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
         ASSERT_THAT(BarDecl, NotNull());
@@ -1157,20 +1148,20 @@
     }
   )";
   runDataflow(
-      Code, [](llvm::ArrayRef<
-                   std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
-                   Results,
-               ASTContext &ASTCtx) {
-        ASSERT_THAT(Results, ElementsAre(Pair("p1", _), Pair("p2", _)));
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2"));
+
         const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
         ASSERT_THAT(FooDecl, NotNull());
 
-        const Environment &Env1 = Results[0].second.Env;
+        const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
         auto &FooVal1 =
             *cast<BoolValue>(Env1.getValue(*FooDecl, SkipPast::Reference));
         EXPECT_TRUE(Env1.flowConditionImplies(FooVal1));
 
-        const Environment &Env2 = Results[1].second.Env;
+        const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
         auto &FooVal2 =
             *cast<BoolValue>(Env2.getValue(*FooDecl, SkipPast::Reference));
         EXPECT_FALSE(Env2.flowConditionImplies(FooVal2));
Index: clang/unittests/Analysis/FlowSensitive/TestingSupport.h
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TestingSupport.h
+++ clang/unittests/Analysis/FlowSensitive/TestingSupport.h
@@ -57,6 +57,21 @@
 
 namespace test {
 
+/// Returns the environment at the program point marked with `Annotation` from
+/// the mapping of annotated program points to analysis state.
+///
+/// Requirements:
+///
+///   `Annotation` must be present as a key in `AnnotationStates`.
+template <typename LatticeT>
+const Environment &getEnvironmentAtAnnotation(
+    const llvm::StringMap<DataflowAnalysisState<LatticeT>> &AnnotationStates,
+    llvm::StringRef Annotation) {
+  auto It = AnnotationStates.find(Annotation);
+  assert(It != AnnotationStates.end());
+  return It->getValue().Env;
+}
+
 /// Contains data structures required and produced by a dataflow analysis run.
 struct AnalysisOutputs {
   /// Input code that is analyzed. Points within the code may be marked with
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to