brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 3dbbc7b Raw
125 lines · cpp
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-exception6//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 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    }));26  }27 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);33 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        else39          assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));40        checkForSameParamRegions(MRMgr, SFC, P);41      }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        else47          assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));48        checkForSameParamRegions(MRMgr, SFC, P);49      }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        else55          assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));56        checkForSameParamRegions(MRMgr, SFC, P);57      }58    }59  }60 61public:62  ParamRegionTestConsumer(CompilerInstance &C) : ExprEngineConsumer(C) {}63 64  bool HandleTopLevelDecl(DeclGroupRef DG) override {65    for (const auto *D : DG) {66      performTest(D);67    }68    return true;69  }70};71 72class ParamRegionTestAction : public ASTFrontendAction {73public:74  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,75                                                 StringRef File) override {76    return std::make_unique<ParamRegionTestConsumer>(Compiler);77  }78};79 80TEST(ParamRegion, ParamRegionTest) {81  EXPECT_TRUE(82      tooling::runToolOnCode(std::make_unique<ParamRegionTestAction>(),83                             R"(void foo(int n);84                                void baz(int p);85 86                                void foo(int n) {87                                  auto lambda = [n](int m) {88                                    return n + m;89                                  };90 91                                  int k = lambda(2);92                                }93 94                                void bar(int l) {95                                  foo(l);96                                }97 98                                struct S {99                                  int n;100                                  S(int nn): n(nn) {}101                                };102 103                                void baz(int p) {104                                  S s(p);105                                }106 107                                void bar(int l);108                                void baz(int p);)"));109  EXPECT_TRUE(110      tooling::runToolOnCode(std::make_unique<ParamRegionTestAction>(),111                             R"(@interface O112                                + alloc;113                                - initWithInt:(int)q;114                                @end115 116                                void qix(int r) {117                                  O *o = [[O alloc] initWithInt:r];118                                })",119                             "input.m"));120}121 122} // namespace123} // namespace ento124} // namespace clang125