1 //===- unittests/Analysis/FlowSensitive/SimplifyConstraintsTest.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/SimplifyConstraints.h"
10 #include "TestingSupport.h"
11 #include "clang/Analysis/FlowSensitive/Arena.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
17 using namespace clang
;
18 using namespace dataflow
;
20 using ::testing::ElementsAre
;
21 using ::testing::IsEmpty
;
23 class SimplifyConstraintsTest
: public ::testing::Test
{
25 llvm::SetVector
<const Formula
*> parse(StringRef Lines
) {
26 std::vector
<const Formula
*> formulas
= test::parseFormulas(A
, Lines
);
27 llvm::SetVector
<const Formula
*> Constraints(formulas
.begin(),
32 llvm::SetVector
<const Formula
*> simplify(StringRef Lines
,
33 SimplifyConstraintsInfo
&Info
) {
34 llvm::SetVector
<const Formula
*> Constraints
= parse(Lines
);
35 simplifyConstraints(Constraints
, A
, &Info
);
42 void printConstraints(const llvm::SetVector
<const Formula
*> &Constraints
,
44 if (Constraints
.empty()) {
48 for (const auto *Constraint
: Constraints
) {
49 Constraint
->print(OS
);
55 constraintsToString(const llvm::SetVector
<const Formula
*> &Constraints
) {
57 llvm::raw_string_ostream
OS(Str
);
58 printConstraints(Constraints
, OS
);
62 MATCHER_P(EqualsConstraints
, Constraints
,
63 "constraints are: " + constraintsToString(Constraints
)) {
64 if (arg
== Constraints
)
67 if (result_listener
->stream()) {
68 llvm::raw_os_ostream
OS(*result_listener
->stream());
69 OS
<< "constraints are: ";
70 printConstraints(arg
, OS
);
75 TEST_F(SimplifyConstraintsTest
, TriviallySatisfiable
) {
76 SimplifyConstraintsInfo Info
;
77 EXPECT_THAT(simplify(R
"(
81 EqualsConstraints(parse("")));
82 EXPECT_THAT(Info
.EquivalentAtoms
, IsEmpty());
83 EXPECT_THAT(Info
.TrueAtoms
, ElementsAre(Atom(0)));
84 EXPECT_THAT(Info
.FalseAtoms
, IsEmpty());
87 TEST_F(SimplifyConstraintsTest
, SimpleContradiction
) {
88 SimplifyConstraintsInfo Info
;
89 EXPECT_THAT(simplify(R
"(
94 EqualsConstraints(parse("false")));
95 EXPECT_THAT(Info
.EquivalentAtoms
, IsEmpty());
96 EXPECT_THAT(Info
.TrueAtoms
, IsEmpty());
97 EXPECT_THAT(Info
.FalseAtoms
, IsEmpty());
100 TEST_F(SimplifyConstraintsTest
, ContradictionThroughEquivalence
) {
101 SimplifyConstraintsInfo Info
;
102 EXPECT_THAT(simplify(R
"(
108 EqualsConstraints(parse("false")));
109 EXPECT_THAT(Info
.EquivalentAtoms
, IsEmpty());
110 EXPECT_THAT(Info
.TrueAtoms
, IsEmpty());
111 EXPECT_THAT(Info
.FalseAtoms
, IsEmpty());
114 TEST_F(SimplifyConstraintsTest
, EquivalenceChain
) {
115 SimplifyConstraintsInfo Info
;
116 EXPECT_THAT(simplify(R
"(
122 EqualsConstraints(parse("(V0 | V1)")));
123 EXPECT_THAT(Info
.EquivalentAtoms
,
124 ElementsAre(ElementsAre(Atom(1), Atom(2), Atom(3))));
125 EXPECT_THAT(Info
.TrueAtoms
, IsEmpty());
126 EXPECT_THAT(Info
.FalseAtoms
, IsEmpty());
129 TEST_F(SimplifyConstraintsTest
, TrueAndFalseAtomsSimplifyOtherExpressions
) {
130 SimplifyConstraintsInfo Info
;
131 EXPECT_THAT(simplify(R
"(
138 EqualsConstraints(parse(R
"(
142 EXPECT_THAT(Info
.EquivalentAtoms
, IsEmpty());
143 EXPECT_THAT(Info
.TrueAtoms
, ElementsAre(Atom(0)));
144 EXPECT_THAT(Info
.FalseAtoms
, ElementsAre(Atom(1)));
147 TEST_F(SimplifyConstraintsTest
, TrueAtomUnlocksEquivalenceChain
) {
148 SimplifyConstraintsInfo Info
;
149 EXPECT_THAT(simplify(R
"(
155 EqualsConstraints(parse("")));
156 EXPECT_THAT(Info
.EquivalentAtoms
,
157 ElementsAre(ElementsAre(Atom(1), Atom(2), Atom(3))));
158 EXPECT_THAT(Info
.TrueAtoms
, ElementsAre(Atom(0)));
159 EXPECT_THAT(Info
.FalseAtoms
, IsEmpty());
162 TEST_F(SimplifyConstraintsTest
, TopLevelAndSplitIntoMultipleConstraints
) {
163 SimplifyConstraintsInfo Info
;
164 EXPECT_THAT(simplify(R
"(
165 ((V0 => V1) & (V2 => V3))
168 EqualsConstraints(parse(R
"(
172 EXPECT_THAT(Info
.EquivalentAtoms
, IsEmpty());
173 EXPECT_THAT(Info
.TrueAtoms
, IsEmpty());
174 EXPECT_THAT(Info
.FalseAtoms
, IsEmpty());