1//===- unittests/StaticAnalyzer/SymbolReaperTest.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//===----------------------------------------------------------------------===//
8
9#include "Reusables.h"
10
11#include "clang/Tooling/Tooling.h"
12#include "gtest/gtest.h"
13
14namespace clang {
15namespace ento {
16namespace {
17
18class SuperRegionLivenessConsumer : public ExprEngineConsumer {
19 void performTest(const Decl *D) {
20 const auto *FD = findDeclByName<FieldDecl>(Where: D, Name: "x");
21 const auto *VD = findDeclByName<VarDecl>(Where: D, Name: "s");
22 assert(FD && VD);
23
24 // The variable must belong to a stack frame,
25 // otherwise SymbolReaper would think it's a global.
26 const StackFrameContext *SFC =
27 Eng.getAnalysisDeclContextManager().getStackFrame(D);
28
29 // Create regions for 's' and 's.x'.
30 const VarRegion *VR = Eng.getRegionManager().getVarRegion(VD, SFC);
31 const FieldRegion *FR = Eng.getRegionManager().getFieldRegion(FD, VR);
32
33 // Pass a null location context to the SymbolReaper so that
34 // it was thinking that the variable is dead.
35 SymbolReaper SymReaper((StackFrameContext *)nullptr, (Stmt *)nullptr,
36 Eng.getSymbolManager(), Eng.getStoreManager());
37
38 SymReaper.markLive(region: FR);
39 EXPECT_TRUE(SymReaper.isLiveRegion(VR));
40 }
41
42public:
43 SuperRegionLivenessConsumer(CompilerInstance &C) : ExprEngineConsumer(C) {}
44 ~SuperRegionLivenessConsumer() override {}
45
46 bool HandleTopLevelDecl(DeclGroupRef DG) override {
47 for (const auto *D : DG)
48 performTest(D);
49 return true;
50 }
51};
52
53class SuperRegionLivenessAction : public ASTFrontendAction {
54public:
55 SuperRegionLivenessAction() {}
56 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
57 StringRef File) override {
58 return std::make_unique<SuperRegionLivenessConsumer>(args&: Compiler);
59 }
60};
61
62// Test that marking s.x as live would also make s live.
63TEST(SymbolReaper, SuperRegionLiveness) {
64 EXPECT_TRUE(
65 tooling::runToolOnCode(std::make_unique<SuperRegionLivenessAction>(),
66 "void foo() { struct S { int x; } s; }"));
67}
68
69} // namespace
70} // namespace ento
71} // namespace clang
72

source code of clang/unittests/StaticAnalyzer/SymbolReaperTest.cpp