1 //===- unittests/Analysis/FlowSensitive/SignAnalysisTest.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 // This file defines a test for the transferBranch function of the
10 // TypeErasedDataflowAnalysis.
12 //===----------------------------------------------------------------------===//
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"
23 namespace clang::dataflow::test
{
26 using namespace ast_matchers
;
29 std::optional
<bool> Branch
;
30 static TestLattice
bottom() { return {}; }
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
;
36 friend bool operator==(const TestLattice
&Lhs
, const TestLattice
&Rhs
) {
37 return Lhs
.Branch
== Rhs
.Branch
;
41 class TestPropagationAnalysis
42 : public DataflowAnalysis
<TestPropagationAnalysis
, TestLattice
> {
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
,
54 using ::testing::UnorderedElementsAre
;
56 template <typename Matcher
>
57 void runDataflow(llvm::StringRef Code
, Matcher VerifyResults
,
58 LangStandard::Kind Std
= LangStandard::lang_cxx17
,
59 llvm::StringRef TargetFun
= "fun") {
60 using ast_matchers::hasName
;
62 checkDataflow
<TestPropagationAnalysis
>(
63 AnalysisInputs
<TestPropagationAnalysis
>(
64 Code
, hasName(TargetFun
),
65 [](ASTContext
&C
, Environment
&) {
66 return TestPropagationAnalysis(C
);
69 {"-fsyntax-only", "-fno-delayed-template-parsing",
71 std::string(LangStandard::getLangStandardForKind(Std
)
77 template <typename LatticeT
>
78 const 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
;
86 TEST(TransferBranchTest
, IfElse
) {
87 std::string Code
= R
"(
100 [](const llvm::StringMap
<DataflowAnalysisState
<TestLattice
>> &Results
,
101 const AnalysisOutputs
&) {
102 ASSERT_THAT(Results
.keys(), UnorderedElementsAre("p", "q"));
104 const TestLattice
&LP
= getLatticeAtAnnotation(Results
, "p");
105 EXPECT_THAT(LP
.Branch
, std::make_optional(true));
107 const TestLattice
&LQ
= getLatticeAtAnnotation(Results
, "q");
108 EXPECT_THAT(LQ
.Branch
, std::make_optional(false));
110 LangStandard::lang_cxx17
);
114 } // namespace clang::dataflow::test