47 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 "BitwisePointerCastCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11 12using namespace clang::ast_matchers;13 14namespace clang::tidy::bugprone {15 16void BitwisePointerCastCheck::registerMatchers(MatchFinder *Finder) {17 if (getLangOpts().CPlusPlus20) {18 auto IsPointerType = refersToType(qualType(isAnyPointer()));19 Finder->addMatcher(callExpr(hasDeclaration(functionDecl(allOf(20 hasName("::std::bit_cast"),21 hasTemplateArgument(0, IsPointerType),22 hasTemplateArgument(1, IsPointerType)))))23 .bind("bit_cast"),24 this);25 }26 27 auto IsDoublePointerType =28 hasType(qualType(pointsTo(qualType(isAnyPointer()))));29 Finder->addMatcher(callExpr(hasArgument(0, IsDoublePointerType),30 hasArgument(1, IsDoublePointerType),31 hasDeclaration(functionDecl(hasName("::memcpy"))))32 .bind("memcpy"),33 this);34}35 36void BitwisePointerCastCheck::check(const MatchFinder::MatchResult &Result) {37 if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("bit_cast"))38 diag(Call->getBeginLoc(),39 "do not use 'std::bit_cast' to cast between pointers")40 << Call->getSourceRange();41 else if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("memcpy"))42 diag(Call->getBeginLoc(), "do not use 'memcpy' to cast between pointers")43 << Call->getSourceRange();44}45 46} // namespace clang::tidy::bugprone47