brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · cb37976 Raw
97 lines · cpp
1//===----------------------------------------------------------------------===//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 "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 15using namespace clang::ast_matchers;16 17namespace clang::tidy::bugprone {18 19SuspiciousStringviewDataUsageCheck::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 27void 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 35bool SuspiciousStringviewDataUsageCheck::isLanguageVersionSupported(36    const LangOptions &LangOpts) const {37  return LangOpts.CPlusPlus;38}39 40std::optional<TraversalKind>41SuspiciousStringviewDataUsageCheck::getCheckTraversalKind() const {42  return TK_AsIs;43}44 45void SuspiciousStringviewDataUsageCheck::registerMatchers(MatchFinder *Finder) {46  auto AncestorCall = anyOf(47      cxxConstructExpr(), callExpr(unless(cxxOperatorCallExpr())), lambdaExpr(),48      initListExpr(49          hasType(qualType(hasCanonicalType(hasDeclaration(recordDecl()))))));50 51  auto DataMethod =52      cxxMethodDecl(hasName("data"),53                    ofClass(matchers::matchesAnyListedName(StringViewTypes)));54 55  auto SizeCall = cxxMemberCallExpr(56      callee(cxxMethodDecl(hasAnyName("size", "length"))),57      on(ignoringParenImpCasts(58          matchers::isStatementIdenticalToBoundNode("self"))));59 60  auto DescendantSizeCall = expr(hasDescendant(61      expr(SizeCall, hasAncestor(expr(AncestorCall).bind("ancestor-size")),62           hasAncestor(expr(equalsBoundNode("parent"),63                            equalsBoundNode("ancestor-size"))))));64 65  Finder->addMatcher(66      cxxMemberCallExpr(67          on(ignoringParenImpCasts(expr().bind("self"))), callee(DataMethod),68          expr().bind("data-call"),69          hasParent(expr(anyOf(70              invocation(71                  expr().bind("parent"), unless(cxxOperatorCallExpr()),72                  hasAnyArgument(73                      ignoringParenImpCasts(equalsBoundNode("data-call"))),74                  unless(hasAnyArgument(ignoringParenImpCasts(SizeCall))),75                  unless(hasAnyArgument(DescendantSizeCall)),76                  hasDeclaration(namedDecl(77                      unless(matchers::matchesAnyListedName(AllowedCallees))))),78              initListExpr(expr().bind("parent"),79                           hasType(qualType(hasCanonicalType(hasDeclaration(80                               recordDecl(unless(matchers::matchesAnyListedName(81                                   AllowedCallees))))))),82                           unless(DescendantSizeCall)))))),83      this);84}85 86void SuspiciousStringviewDataUsageCheck::check(87    const MatchFinder::MatchResult &Result) {88  const auto *DataCallExpr =89      Result.Nodes.getNodeAs<CXXMemberCallExpr>("data-call");90  diag(DataCallExpr->getExprLoc(),91       "result of a `data()` call may not be null terminated, provide size "92       "information to the callee to prevent potential issues")93      << DataCallExpr->getCallee()->getSourceRange();94}95 96} // namespace clang::tidy::bugprone97