brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · ef78131 Raw
115 lines · cpp
1//===- unittests/Analysis/FlowSensitive/SignAnalysisTest.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//  This file defines a test for the transferBranch function of the10//  TypeErasedDataflowAnalysis.11//12//===----------------------------------------------------------------------===//13 14#include "TestingSupport.h"15#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"16#include "clang/Tooling/Tooling.h"17#include "llvm/Support/Error.h"18#include "llvm/Testing/Annotations/Annotations.h"19#include "llvm/Testing/Support/Error.h"20#include "gtest/gtest.h"21#include <optional>22 23namespace clang::dataflow::test {24namespace {25 26using namespace ast_matchers;27 28struct TestLattice {29  std::optional<bool> Branch;30  static TestLattice bottom() { return {}; }31 32  // Does not matter for this test, but we must provide some definition of join.33  LatticeJoinEffect join(const TestLattice &Other) {34    return LatticeJoinEffect::Unchanged;35  }36  friend bool operator==(const TestLattice &Lhs, const TestLattice &Rhs) {37    return Lhs.Branch == Rhs.Branch;38  }39};40 41class TestPropagationAnalysis42    : public DataflowAnalysis<TestPropagationAnalysis, TestLattice> {43public:44  explicit TestPropagationAnalysis(ASTContext &Context)45      : DataflowAnalysis<TestPropagationAnalysis, TestLattice>(Context) {}46  static TestLattice initialElement() { return TestLattice::bottom(); }47  void transfer(const CFGElement &, TestLattice &, Environment &) {}48  void transferBranch(bool Branch, const Stmt *S, TestLattice &L,49                      Environment &Env) {50    L.Branch = Branch;51  }52};53 54using ::testing::UnorderedElementsAre;55 56template <typename Matcher>57void runDataflow(llvm::StringRef Code, Matcher VerifyResults,58                 LangStandard::Kind Std = LangStandard::lang_cxx17,59                 llvm::StringRef TargetFun = "fun") {60  using ast_matchers::hasName;61  ASSERT_THAT_ERROR(62      checkDataflow<TestPropagationAnalysis>(63          AnalysisInputs<TestPropagationAnalysis>(64              Code, hasName(TargetFun),65              [](ASTContext &C, Environment &) {66                return TestPropagationAnalysis(C);67              })68              .withASTBuildArgs(69                  {"-fsyntax-only", "-fno-delayed-template-parsing",70                   "-std=" +71                       std::string(LangStandard::getLangStandardForKind(Std)72                                       .getName())}),73          VerifyResults),74      llvm::Succeeded());75}76 77template <typename LatticeT>78const LatticeT &getLatticeAtAnnotation(79    const llvm::StringMap<DataflowAnalysisState<LatticeT>> &AnnotationStates,80    llvm::StringRef Annotation) {81  auto It = AnnotationStates.find(Annotation);82  assert(It != AnnotationStates.end());83  return It->getValue().Lattice;84}85 86TEST(TransferBranchTest, IfElse) {87  std::string Code = R"(88    void fun(int a) {89      if (a > 0) {90        (void)1;91        // [[p]]92      } else {93        (void)0;94        // [[q]]95      }96    }97  )";98  runDataflow(99      Code,100      [](const llvm::StringMap<DataflowAnalysisState<TestLattice>> &Results,101         const AnalysisOutputs &) {102        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p", "q"));103 104        const TestLattice &LP = getLatticeAtAnnotation(Results, "p");105        EXPECT_THAT(LP.Branch, std::make_optional(true));106 107        const TestLattice &LQ = getLatticeAtAnnotation(Results, "q");108        EXPECT_THAT(LQ.Branch, std::make_optional(false));109      },110      LangStandard::lang_cxx17);111}112 113} // namespace114} // namespace clang::dataflow::test115