brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 7b837f3 Raw
174 lines · cpp
1//===- MemRegionDescriptiveNameTest.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 "CheckerRegistration.h"10#include "clang/StaticAnalyzer/Core/Checker.h"11#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"12#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"13#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"14#include "gtest/gtest.h"15 16using namespace clang;17using namespace ento;18 19namespace {20 21class DescriptiveNameChecker : public Checker<check::PreCall> {22public:23  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {24    if (!HandlerFn.matches(Call))25      return;26 27    const MemRegion *ArgReg = Call.getArgSVal(0).getAsRegion();28    assert(ArgReg && "expecting a location as the first argument");29 30    auto DescriptiveName = ArgReg->getDescriptiveName(/*UseQuotes=*/false);31    if (ExplodedNode *Node = C.generateNonFatalErrorNode(C.getState())) {32      auto Report =33          std::make_unique<PathSensitiveBugReport>(Bug, DescriptiveName, Node);34      C.emitReport(std::move(Report));35    }36  }37 38private:39  const BugType Bug{this, "DescriptiveNameBug"};40  const CallDescription HandlerFn = {41      CDM::SimpleFunc, {"reportDescriptiveName"}, 1};42};43 44void addDescriptiveNameChecker(AnalysisASTConsumer &AnalysisConsumer,45                               AnalyzerOptions &AnOpts) {46  AnOpts.CheckersAndPackages = {{"DescriptiveNameChecker", true}};47  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {48    Registry.addChecker<DescriptiveNameChecker>("DescriptiveNameChecker",49                                                "MockDescription");50  });51}52 53bool runChecker(StringRef Code, std::string &Output) {54  return runCheckerOnCode<addDescriptiveNameChecker>(Code.str(), Output,55                                                     /*OnlyEmitWarnings=*/true);56}57 58TEST(MemRegionDescriptiveNameTest, ConcreteIntElementRegionIndex) {59  StringRef Code = R"cpp(60void reportDescriptiveName(int *p);61const unsigned int index = 1;62extern int array[3];63void top() {64  reportDescriptiveName(&array[index]);65})cpp";66 67  std::string Output;68  ASSERT_TRUE(runChecker(Code, Output));69  EXPECT_EQ(Output, "DescriptiveNameChecker: array[1]\n");70}71 72TEST(MemRegionDescriptiveNameTest, SymbolicElementRegionIndex) {73  StringRef Code = R"cpp(74void reportDescriptiveName(int *p);75extern unsigned int index;76extern int array[3];77void top() {78  reportDescriptiveName(&array[index]);79})cpp";80 81  std::string Output;82  ASSERT_TRUE(runChecker(Code, Output));83  EXPECT_EQ(Output, "DescriptiveNameChecker: array[index]\n");84}85 86TEST(MemRegionDescriptiveNameTest, SymbolicElementRegionIndexSymbolValFails) {87  StringRef Code = R"cpp(88void reportDescriptiveName(int *p);89extern int* ptr;90extern int array[3];91void top() {92  reportDescriptiveName(&array[(long long)ptr]);93})cpp";94 95  std::string Output;96  ASSERT_TRUE(runChecker(Code, Output));97  EXPECT_EQ(Output, "DescriptiveNameChecker: \n");98}99 100TEST(MemRegionDescriptiveNameTest, SymbolicElementRegionIndexOrigRegionFails) {101  StringRef Code = R"cpp(102void reportDescriptiveName(int *p);103extern int getInt(void);104extern int array[3];105void top() {106  reportDescriptiveName(&array[getInt()]);107})cpp";108 109  std::string Output;110  ASSERT_TRUE(runChecker(Code, Output));111  EXPECT_EQ(Output, "DescriptiveNameChecker: \n");112}113 114TEST(MemRegionDescriptiveNameTest, SymbolicElementRegionIndexDescrNameFails) {115  StringRef Code = R"cpp(116void reportDescriptiveName(int *p);117extern int *ptr;118extern int array[3];119void top() {120  reportDescriptiveName(&array[*ptr]);121})cpp";122 123  std::string Output;124  ASSERT_TRUE(runChecker(Code, Output));125  EXPECT_EQ(Output, "DescriptiveNameChecker: \n");126}127 128TEST(MemRegionDescriptiveNameTest,129     SymbolicElementRegionIndexIncorrectSymbolName) {130  StringRef Code = R"cpp(131void reportDescriptiveName(int *p);132extern int x, y;133extern int array[3];134void top() {135  y = x;136  reportDescriptiveName(&array[y]);137})cpp";138 139  std::string Output;140  ASSERT_TRUE(runChecker(Code, Output));141  // FIXME: Should return array[y], but returns array[x] (OriginRegion).142  EXPECT_EQ(Output, "DescriptiveNameChecker: array[x]\n");143}144 145TEST(MemRegionDescriptiveNameTest, FieldRegWithSuperElementReg) {146  StringRef Code = R"cpp(147void reportDescriptiveName(int *p);148struct val_struct { int val; };149extern struct val_struct val_struct_array[3];150void top() {151  reportDescriptiveName(&val_struct_array[0].val);152})cpp";153 154  std::string Output;155  ASSERT_TRUE(runChecker(Code, Output));156  EXPECT_EQ(Output, "DescriptiveNameChecker: val_struct_array[0].val\n");157}158 159TEST(MemRegionDescriptiveNameTest, FieldRegWithSuperMultidimElementReg) {160  StringRef Code = R"cpp(161void reportDescriptiveName(int *p);162struct val_struct { int val; };163extern struct val_struct val_struct_array[3][4];164void top() {165  reportDescriptiveName(&val_struct_array[1][2].val);166})cpp";167 168  std::string Output;169  ASSERT_TRUE(runChecker(Code, Output));170  EXPECT_EQ(Output, "DescriptiveNameChecker: val_struct_array[1][2].val\n");171}172 173} // namespace174