Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / StaticAnalyzer / ParamRegionTest.cpp
blob3dbbc7ba1578df7a3671cd1b292203ec8d675774
1 //===- unittests/StaticAnalyzer/ParamRegionTest.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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "Reusables.h"
11 #include "clang/Tooling/Tooling.h"
12 #include "gtest/gtest.h"
14 namespace clang {
15 namespace ento {
16 namespace {
18 class ParamRegionTestConsumer : public ExprEngineConsumer {
19 void checkForSameParamRegions(MemRegionManager &MRMgr,
20 const StackFrameContext *SFC,
21 const ParmVarDecl *PVD) {
22 ASSERT_TRUE(llvm::all_of(PVD->redecls(), [&](const clang::VarDecl *D2) {
23 return MRMgr.getVarRegion(PVD, SFC) ==
24 MRMgr.getVarRegion(cast<ParmVarDecl>(D2), SFC);
25 }));
28 void performTest(const Decl *D) {
29 StoreManager &StMgr = Eng.getStoreManager();
30 MemRegionManager &MRMgr = StMgr.getRegionManager();
31 const StackFrameContext *SFC =
32 Eng.getAnalysisDeclContextManager().getStackFrame(D);
34 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
35 for (const auto *P : FD->parameters()) {
36 if (SFC->inTopFrame())
37 assert(isa<NonParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
38 else
39 assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
40 checkForSameParamRegions(MRMgr, SFC, P);
42 } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
43 for (const auto *P : CD->parameters()) {
44 if (SFC->inTopFrame())
45 assert(isa<NonParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
46 else
47 assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
48 checkForSameParamRegions(MRMgr, SFC, P);
50 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
51 for (const auto *P : MD->parameters()) {
52 if (SFC->inTopFrame())
53 assert(isa<NonParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
54 else
55 assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
56 checkForSameParamRegions(MRMgr, SFC, P);
61 public:
62 ParamRegionTestConsumer(CompilerInstance &C) : ExprEngineConsumer(C) {}
64 bool HandleTopLevelDecl(DeclGroupRef DG) override {
65 for (const auto *D : DG) {
66 performTest(D);
68 return true;
72 class ParamRegionTestAction : public ASTFrontendAction {
73 public:
74 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
75 StringRef File) override {
76 return std::make_unique<ParamRegionTestConsumer>(Compiler);
80 TEST(ParamRegion, ParamRegionTest) {
81 EXPECT_TRUE(
82 tooling::runToolOnCode(std::make_unique<ParamRegionTestAction>(),
83 R"(void foo(int n);
84 void baz(int p);
86 void foo(int n) {
87 auto lambda = [n](int m) {
88 return n + m;
91 int k = lambda(2);
94 void bar(int l) {
95 foo(l);
98 struct S {
99 int n;
100 S(int nn): n(nn) {}
103 void baz(int p) {
104 S s(p);
107 void bar(int l);
108 void baz(int p);)"));
109 EXPECT_TRUE(
110 tooling::runToolOnCode(std::make_unique<ParamRegionTestAction>(),
111 R"(@interface O
112 + alloc;
113 - initWithInt:(int)q;
114 @end
116 void qix(int r) {
117 O *o = [[O alloc] initWithInt:r];
118 })",
119 "input.m"));
122 } // namespace
123 } // namespace ento
124 } // namespace clang