llvm-project

Форк
0
/
SuspiciousStringviewDataUsageCheck.cpp 
97 строк · 3.9 Кб
1
//===--- SuspiciousStringviewDataUsageCheck.cpp - clang-tidy --------------===//
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 "SuspiciousStringviewDataUsageCheck.h"
10
#include "../utils/Matchers.h"
11
#include "../utils/OptionsUtils.h"
12
#include "clang/AST/ASTContext.h"
13
#include "clang/ASTMatchers/ASTMatchFinder.h"
14

15
using namespace clang::ast_matchers;
16

17
namespace clang::tidy::bugprone {
18

19
SuspiciousStringviewDataUsageCheck::SuspiciousStringviewDataUsageCheck(
20
    StringRef Name, ClangTidyContext *Context)
21
    : ClangTidyCheck(Name, Context),
22
      StringViewTypes(utils::options::parseStringList(Options.get(
23
          "StringViewTypes", "::std::basic_string_view;::llvm::StringRef"))),
24
      AllowedCallees(
25
          utils::options::parseStringList(Options.get("AllowedCallees", ""))) {}
26

27
void SuspiciousStringviewDataUsageCheck::storeOptions(
28
    ClangTidyOptions::OptionMap &Opts) {
29
  Options.store(Opts, "StringViewTypes",
30
                utils::options::serializeStringList(StringViewTypes));
31
  Options.store(Opts, "AllowedCallees",
32
                utils::options::serializeStringList(AllowedCallees));
33
}
34

35
bool SuspiciousStringviewDataUsageCheck::isLanguageVersionSupported(
36
    const LangOptions &LangOpts) const {
37
  return LangOpts.CPlusPlus;
38
}
39

40
std::optional<TraversalKind>
41
SuspiciousStringviewDataUsageCheck::getCheckTraversalKind() const {
42
  return TK_AsIs;
43
}
44

45
void SuspiciousStringviewDataUsageCheck::registerMatchers(MatchFinder *Finder) {
46

47
  auto AncestorCall = anyOf(
48
      cxxConstructExpr(), callExpr(unless(cxxOperatorCallExpr())), lambdaExpr(),
49
      initListExpr(
50
          hasType(qualType(hasCanonicalType(hasDeclaration(recordDecl()))))));
51

52
  auto DataMethod =
53
      cxxMethodDecl(hasName("data"),
54
                    ofClass(matchers::matchesAnyListedName(StringViewTypes)));
55

56
  auto SizeCall = cxxMemberCallExpr(
57
      callee(cxxMethodDecl(hasAnyName("size", "length"))),
58
      on(ignoringParenImpCasts(
59
          matchers::isStatementIdenticalToBoundNode("self"))));
60

61
  auto DescendantSizeCall = expr(hasDescendant(
62
      expr(SizeCall, hasAncestor(expr(AncestorCall).bind("ancestor-size")),
63
           hasAncestor(expr(equalsBoundNode("parent"),
64
                            equalsBoundNode("ancestor-size"))))));
65

66
  Finder->addMatcher(
67
      cxxMemberCallExpr(
68
          on(ignoringParenImpCasts(expr().bind("self"))), callee(DataMethod),
69
          expr().bind("data-call"),
70
          hasParent(expr(anyOf(
71
              invocation(
72
                  expr().bind("parent"), unless(cxxOperatorCallExpr()),
73
                  hasAnyArgument(
74
                      ignoringParenImpCasts(equalsBoundNode("data-call"))),
75
                  unless(hasAnyArgument(ignoringParenImpCasts(SizeCall))),
76
                  unless(hasAnyArgument(DescendantSizeCall)),
77
                  hasDeclaration(namedDecl(
78
                      unless(matchers::matchesAnyListedName(AllowedCallees))))),
79
              initListExpr(expr().bind("parent"),
80
                           hasType(qualType(hasCanonicalType(hasDeclaration(
81
                               recordDecl(unless(matchers::matchesAnyListedName(
82
                                   AllowedCallees))))))),
83
                           unless(DescendantSizeCall)))))),
84
      this);
85
}
86

87
void SuspiciousStringviewDataUsageCheck::check(
88
    const MatchFinder::MatchResult &Result) {
89
  const auto *DataCallExpr =
90
      Result.Nodes.getNodeAs<CXXMemberCallExpr>("data-call");
91
  diag(DataCallExpr->getExprLoc(),
92
       "result of a `data()` call may not be null terminated, provide size "
93
       "information to the callee to prevent potential issues")
94
      << DataCallExpr->getCallee()->getSourceRange();
95
}
96

97
} // namespace clang::tidy::bugprone
98

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.