1 //===- ArenaTest.cpp ------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/Analysis/FlowSensitive/Arena.h"
10 #include "llvm/Support/ScopedPrinter.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
14 namespace clang::dataflow
{
17 class ArenaTest
: public ::testing::Test
{
22 TEST_F(ArenaTest
, CreateAtomicBoolValueReturnsDistinctValues
) {
23 auto &X
= A
.makeAtomValue();
24 auto &Y
= A
.makeAtomValue();
28 TEST_F(ArenaTest
, CreateTopBoolValueReturnsDistinctValues
) {
29 auto &X
= A
.makeTopValue();
30 auto &Y
= A
.makeTopValue();
34 TEST_F(ArenaTest
, GetOrCreateConjunctionReturnsSameExprGivenSameArgs
) {
35 auto &X
= A
.makeAtomRef(A
.makeAtom());
36 auto &XAndX
= A
.makeAnd(X
, X
);
37 EXPECT_EQ(&XAndX
, &X
);
40 TEST_F(ArenaTest
, GetOrCreateConjunctionReturnsSameExprOnSubsequentCalls
) {
41 auto &X
= A
.makeAtomRef(A
.makeAtom());
42 auto &Y
= A
.makeAtomRef(A
.makeAtom());
43 auto &XAndY1
= A
.makeAnd(X
, Y
);
44 auto &XAndY2
= A
.makeAnd(X
, Y
);
45 EXPECT_EQ(&XAndY1
, &XAndY2
);
47 auto &YAndX
= A
.makeAnd(Y
, X
);
48 EXPECT_EQ(&XAndY1
, &YAndX
);
50 auto &Z
= A
.makeAtomRef(A
.makeAtom());
51 auto &XAndZ
= A
.makeAnd(X
, Z
);
52 EXPECT_NE(&XAndY1
, &XAndZ
);
55 TEST_F(ArenaTest
, GetOrCreateDisjunctionReturnsSameExprGivenSameArgs
) {
56 auto &X
= A
.makeAtomRef(A
.makeAtom());
57 auto &XOrX
= A
.makeOr(X
, X
);
61 TEST_F(ArenaTest
, GetOrCreateDisjunctionReturnsSameExprOnSubsequentCalls
) {
62 auto &X
= A
.makeAtomRef(A
.makeAtom());
63 auto &Y
= A
.makeAtomRef(A
.makeAtom());
64 auto &XOrY1
= A
.makeOr(X
, Y
);
65 auto &XOrY2
= A
.makeOr(X
, Y
);
66 EXPECT_EQ(&XOrY1
, &XOrY2
);
68 auto &YOrX
= A
.makeOr(Y
, X
);
69 EXPECT_EQ(&XOrY1
, &YOrX
);
71 auto &Z
= A
.makeAtomRef(A
.makeAtom());
72 auto &XOrZ
= A
.makeOr(X
, Z
);
73 EXPECT_NE(&XOrY1
, &XOrZ
);
76 TEST_F(ArenaTest
, GetOrCreateNegationReturnsSameExprOnSubsequentCalls
) {
77 auto &X
= A
.makeAtomRef(A
.makeAtom());
78 auto &NotX1
= A
.makeNot(X
);
79 auto &NotX2
= A
.makeNot(X
);
80 EXPECT_EQ(&NotX1
, &NotX2
);
81 auto &Y
= A
.makeAtomRef(A
.makeAtom());
82 auto &NotY
= A
.makeNot(Y
);
83 EXPECT_NE(&NotX1
, &NotY
);
86 TEST_F(ArenaTest
, GetOrCreateImplicationReturnsTrueGivenSameArgs
) {
87 auto &X
= A
.makeAtomRef(A
.makeAtom());
88 auto &XImpliesX
= A
.makeImplies(X
, X
);
89 EXPECT_EQ(&XImpliesX
, &A
.makeLiteral(true));
92 TEST_F(ArenaTest
, GetOrCreateImplicationReturnsSameExprOnSubsequentCalls
) {
93 auto &X
= A
.makeAtomRef(A
.makeAtom());
94 auto &Y
= A
.makeAtomRef(A
.makeAtom());
95 auto &XImpliesY1
= A
.makeImplies(X
, Y
);
96 auto &XImpliesY2
= A
.makeImplies(X
, Y
);
97 EXPECT_EQ(&XImpliesY1
, &XImpliesY2
);
99 auto &YImpliesX
= A
.makeImplies(Y
, X
);
100 EXPECT_NE(&XImpliesY1
, &YImpliesX
);
102 auto &Z
= A
.makeAtomRef(A
.makeAtom());
103 auto &XImpliesZ
= A
.makeImplies(X
, Z
);
104 EXPECT_NE(&XImpliesY1
, &XImpliesZ
);
107 TEST_F(ArenaTest
, GetOrCreateIffReturnsTrueGivenSameArgs
) {
108 auto &X
= A
.makeAtomRef(A
.makeAtom());
109 auto &XIffX
= A
.makeEquals(X
, X
);
110 EXPECT_EQ(&XIffX
, &A
.makeLiteral(true));
113 TEST_F(ArenaTest
, GetOrCreateIffReturnsSameExprOnSubsequentCalls
) {
114 auto &X
= A
.makeAtomRef(A
.makeAtom());
115 auto &Y
= A
.makeAtomRef(A
.makeAtom());
116 auto &XIffY1
= A
.makeEquals(X
, Y
);
117 auto &XIffY2
= A
.makeEquals(X
, Y
);
118 EXPECT_EQ(&XIffY1
, &XIffY2
);
120 auto &YIffX
= A
.makeEquals(Y
, X
);
121 EXPECT_EQ(&XIffY1
, &YIffX
);
123 auto &Z
= A
.makeAtomRef(A
.makeAtom());
124 auto &XIffZ
= A
.makeEquals(X
, Z
);
125 EXPECT_NE(&XIffY1
, &XIffZ
);
128 TEST_F(ArenaTest
, Interning
) {
129 Atom X
= A
.makeAtom();
130 Atom Y
= A
.makeAtom();
131 const Formula
&F1
= A
.makeAnd(A
.makeAtomRef(X
), A
.makeAtomRef(Y
));
132 const Formula
&F2
= A
.makeAnd(A
.makeAtomRef(Y
), A
.makeAtomRef(X
));
134 BoolValue
&B1
= A
.makeBoolValue(F1
);
135 BoolValue
&B2
= A
.makeBoolValue(F2
);
137 EXPECT_EQ(&B1
.formula(), &F1
);
141 } // namespace clang::dataflow