SymbolReaperTest.cpp 2.3 KB

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