117 lines · cpp
1//===- unittests/Analysis/FlowSensitive/DebugSupportTest.cpp --------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Analysis/FlowSensitive/DebugSupport.h"10#include "TestingSupport.h"11#include "clang/Analysis/FlowSensitive/Formula.h"12#include "llvm/Support/ScopedPrinter.h"13#include "llvm/Support/raw_ostream.h"14#include "gmock/gmock.h"15#include "gtest/gtest.h"16 17namespace {18 19using namespace clang;20using namespace dataflow;21 22using test::ConstraintContext;23using testing::StrEq;24 25TEST(BoolValueDebugStringTest, AtomicBoolean) {26 ConstraintContext Ctx;27 auto B = Ctx.atom();28 29 auto Expected = "V0";30 EXPECT_THAT(llvm::to_string(*B), StrEq(Expected));31}32 33TEST(BoolValueDebugStringTest, Literal) {34 ConstraintContext Ctx;35 EXPECT_EQ("true", llvm::to_string(*Ctx.literal(true)));36 EXPECT_EQ("false", llvm::to_string(*Ctx.literal(false)));37}38 39TEST(BoolValueDebugStringTest, Negation) {40 ConstraintContext Ctx;41 auto B = Ctx.neg(Ctx.atom());42 43 auto Expected = "!V0";44 EXPECT_THAT(llvm::to_string(*B), StrEq(Expected));45}46 47TEST(BoolValueDebugStringTest, Conjunction) {48 ConstraintContext Ctx;49 auto *V0 = Ctx.atom();50 auto *V1 = Ctx.atom();51 EXPECT_EQ("(V0 & V1)", llvm::to_string(*Ctx.conj(V0, V1)));52}53 54TEST(BoolValueDebugStringTest, Disjunction) {55 ConstraintContext Ctx;56 auto *V0 = Ctx.atom();57 auto *V1 = Ctx.atom();58 EXPECT_EQ("(V0 | V1)", llvm::to_string(*Ctx.disj(V0, V1)));59}60 61TEST(BoolValueDebugStringTest, Implication) {62 ConstraintContext Ctx;63 auto *V0 = Ctx.atom();64 auto *V1 = Ctx.atom();65 EXPECT_EQ("(V0 => V1)", llvm::to_string(*Ctx.impl(V0, V1)));66}67 68TEST(BoolValueDebugStringTest, Iff) {69 ConstraintContext Ctx;70 auto *V0 = Ctx.atom();71 auto *V1 = Ctx.atom();72 EXPECT_EQ("(V0 = V1)", llvm::to_string(*Ctx.iff(V0, V1)));73}74 75TEST(BoolValueDebugStringTest, Xor) {76 ConstraintContext Ctx;77 auto V0 = Ctx.atom();78 auto V1 = Ctx.atom();79 auto B = Ctx.disj(Ctx.conj(V0, Ctx.neg(V1)), Ctx.conj(Ctx.neg(V0), V1));80 81 auto Expected = "((V0 & !V1) | (!V0 & V1))";82 EXPECT_THAT(llvm::to_string(*B), StrEq(Expected));83}84 85TEST(BoolValueDebugStringTest, NestedBoolean) {86 ConstraintContext Ctx;87 auto V0 = Ctx.atom();88 auto V1 = Ctx.atom();89 auto V2 = Ctx.atom();90 auto V3 = Ctx.atom();91 auto V4 = Ctx.atom();92 auto B = Ctx.conj(V0, Ctx.disj(V1, Ctx.conj(V2, Ctx.disj(V3, V4))));93 94 auto Expected = "(V0 & (V1 | (V2 & (V3 | V4))))";95 EXPECT_THAT(llvm::to_string(*B), StrEq(Expected));96}97 98TEST(BoolValueDebugStringTest, ComplexBooleanWithSomeNames) {99 ConstraintContext Ctx;100 auto X = Ctx.atom();101 auto Y = Ctx.atom();102 Formula::AtomNames Names;103 Names[X->getAtom()] = "X";104 Names[Y->getAtom()] = "Y";105 auto V2 = Ctx.atom();106 auto V3 = Ctx.atom();107 auto B = Ctx.disj(Ctx.conj(Y, V2), Ctx.disj(X, V3));108 109 auto Expected = R"(((Y & V2) | (X | V3)))";110 std::string Actual;111 llvm::raw_string_ostream OS(Actual);112 B->print(OS, &Names);113 EXPECT_THAT(Actual, StrEq(Expected));114}115 116} // namespace117