Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / Analysis / FlowSensitive / MapLatticeTest.cpp
blobf6fe81e0dfc5f6a1a1f6d93d6abbf6315bc65722
1 #include "clang/Analysis/FlowSensitive/MapLattice.h"
2 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
3 #include "llvm/Support/Error.h"
4 #include "gmock/gmock.h"
5 #include "gtest/gtest.h"
6 #include <ostream>
8 using namespace clang;
9 using namespace dataflow;
11 namespace {
12 // A simple lattice for basic tests.
13 class BooleanLattice {
14 public:
15 BooleanLattice() : Value(false) {}
16 explicit BooleanLattice(bool B) : Value(B) {}
18 static BooleanLattice bottom() { return BooleanLattice(false); }
20 static BooleanLattice top() { return BooleanLattice(true); }
22 LatticeJoinEffect join(BooleanLattice Other) {
23 auto Prev = Value;
24 Value = Value || Other.Value;
25 return Prev == Value ? LatticeJoinEffect::Unchanged
26 : LatticeJoinEffect::Changed;
29 friend bool operator==(BooleanLattice LHS, BooleanLattice RHS) {
30 return LHS.Value == RHS.Value;
33 friend bool operator!=(BooleanLattice LHS, BooleanLattice RHS) {
34 return LHS.Value != RHS.Value;
37 friend std::ostream &operator<<(std::ostream &Os, const BooleanLattice &B) {
38 Os << B.Value;
39 return Os;
42 bool value() const { return Value; }
44 private:
45 bool Value;
47 } // namespace
49 static constexpr int Key1 = 0;
50 static constexpr int Key2 = 1;
52 namespace {
53 using ::testing::_;
54 using ::testing::Pair;
55 using ::testing::UnorderedElementsAre;
57 TEST(MapLatticeTest, InsertWorks) {
58 MapLattice<int, BooleanLattice> Lattice;
59 EXPECT_THAT(Lattice.insert({Key1, BooleanLattice(false)}), Pair(_, true));
60 EXPECT_THAT(Lattice.insert({Key2, BooleanLattice(false)}), Pair(_, true));
62 // Insertion fails on collision.
63 EXPECT_THAT(Lattice.insert({Key1, BooleanLattice(false)}), Pair(_, false));
64 EXPECT_THAT(Lattice.insert({Key2, BooleanLattice(false)}), Pair(_, false));
66 EXPECT_THAT(Lattice, UnorderedElementsAre(Pair(Key1, BooleanLattice(false)),
67 Pair(Key2, BooleanLattice(false))));
70 TEST(MapLatticeTest, ComparisonWorks) {
71 MapLattice<int, BooleanLattice> Lattice1;
72 Lattice1.insert({Key1, BooleanLattice(true)});
73 Lattice1.insert({Key2, BooleanLattice(false)});
74 MapLattice<int, BooleanLattice> Lattice2 = Lattice1;
75 EXPECT_EQ(Lattice1, Lattice2);
77 Lattice2.find(Key2)->second = BooleanLattice(true);
78 EXPECT_NE(Lattice1, Lattice2);
81 TEST(MapLatticeTest, JoinChange) {
82 MapLattice<int, BooleanLattice> Lattice1;
83 Lattice1.insert({Key1, BooleanLattice(false)});
84 Lattice1.insert({Key2, BooleanLattice(false)});
86 MapLattice<int, BooleanLattice> Lattice2;
87 Lattice2.insert({Key1, BooleanLattice(true)});
88 Lattice2.insert({Key2, BooleanLattice(true)});
90 ASSERT_THAT(Lattice1,
91 UnorderedElementsAre(Pair(Key1, BooleanLattice(false)),
92 Pair(Key2, BooleanLattice(false))));
94 ASSERT_EQ(Lattice1.join(Lattice2), LatticeJoinEffect::Changed);
95 EXPECT_THAT(Lattice1, UnorderedElementsAre(Pair(Key1, BooleanLattice(true)),
96 Pair(Key2, BooleanLattice(true))));
99 TEST(MapLatticeTest, JoinEqNoChange) {
100 MapLattice<int, BooleanLattice> Lattice;
101 Lattice.insert({Key1, BooleanLattice(false)});
102 Lattice.insert({Key2, BooleanLattice(false)});
104 ASSERT_EQ(Lattice.join(Lattice), LatticeJoinEffect::Unchanged);
105 EXPECT_THAT(Lattice, UnorderedElementsAre(Pair(Key1, BooleanLattice(false)),
106 Pair(Key2, BooleanLattice(false))));
109 TEST(MapLatticeTest, JoinLtNoChange) {
110 MapLattice<int, BooleanLattice> Lattice1;
111 Lattice1.insert({Key1, BooleanLattice(false)});
112 Lattice1.insert({Key2, BooleanLattice(false)});
114 MapLattice<int, BooleanLattice> Lattice2;
115 Lattice2.insert({Key1, BooleanLattice(true)});
116 Lattice2.insert({Key2, BooleanLattice(true)});
118 ASSERT_THAT(Lattice1,
119 UnorderedElementsAre(Pair(Key1, BooleanLattice(false)),
120 Pair(Key2, BooleanLattice(false))));
122 ASSERT_THAT(Lattice2, UnorderedElementsAre(Pair(Key1, BooleanLattice(true)),
123 Pair(Key2, BooleanLattice(true))));
125 ASSERT_EQ(Lattice2.join(Lattice1), LatticeJoinEffect::Unchanged);
126 EXPECT_THAT(Lattice2, UnorderedElementsAre(Pair(Key1, BooleanLattice(true)),
127 Pair(Key2, BooleanLattice(true))));
130 TEST(MapLatticeTest, JoinDifferentDomainsProducesUnion) {
131 MapLattice<int, BooleanLattice> Lattice1;
132 Lattice1.insert({Key1, BooleanLattice(true)});
133 MapLattice<int, BooleanLattice> Lattice2;
134 Lattice2.insert({Key2, BooleanLattice(true)});
136 ASSERT_EQ(Lattice1.join(Lattice2), LatticeJoinEffect::Changed);
137 EXPECT_THAT(Lattice1, UnorderedElementsAre(Pair(Key1, BooleanLattice(true)),
138 Pair(Key2, BooleanLattice(true))));
141 TEST(MapLatticeTest, FindWorks) {
142 MapLattice<int, BooleanLattice> Lattice;
143 Lattice.insert({Key1, BooleanLattice(true)});
144 Lattice.insert({Key2, BooleanLattice(false)});
146 auto It = Lattice.find(Key1);
147 ASSERT_NE(It, Lattice.end());
148 EXPECT_EQ(It->second, BooleanLattice(true));
150 It = Lattice.find(Key2);
151 ASSERT_NE(It, Lattice.end());
152 EXPECT_EQ(It->second, BooleanLattice(false));
155 TEST(MapLatticeTest, ContainsWorks) {
156 MapLattice<int, BooleanLattice> Lattice;
157 Lattice.insert({Key1, BooleanLattice(true)});
158 EXPECT_TRUE(Lattice.contains(Key1));
159 EXPECT_FALSE(Lattice.contains(Key2));
161 } // namespace