aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
diff options
context:
space:
mode:
authorCongcong Cai <congcongcai0907@163.com>2024-09-18 08:03:06 +0800
committerGitHub <noreply@github.com>2024-09-18 08:03:06 +0800
commit785624b28237bb75d4fa3b8e4219a5448b90eaac (patch)
tree5b408561e50492ab4aaf0e519feed86958f1b58c /clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
parentca0613e0fcef2a9972f2802318201f8272e74693 (diff)
downloadllvm-785624b28237bb75d4fa3b8e4219a5448b90eaac.zip
llvm-785624b28237bb75d4fa3b8e4219a5448b90eaac.tar.gz
llvm-785624b28237bb75d4fa3b8e4219a5448b90eaac.tar.bz2
[clang-tidy]suggest use `std::span` as replacement of c array in C++20 for modernize-avoid-c-arrays (#108555)
The incompleted C-Array in parameter does not own memory. Instead, It is equivalent to pointer. So we should not use `std::array` as recommended modern C++ replacement, but use `std::vector` and `std::span` in C++20
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
index 89790ea..9877819 100644
--- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
@@ -9,6 +9,7 @@
#include "AvoidCArraysCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
using namespace clang::ast_matchers;
@@ -60,6 +61,7 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
typeLoc(hasValidBeginLoc(), hasType(arrayType()),
+ optionally(hasParent(parmVarDecl().bind("param_decl"))),
unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())),
hasParent(varDecl(isExternC())),
hasParent(fieldDecl(
@@ -72,11 +74,28 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) {
void AvoidCArraysCheck::check(const MatchFinder::MatchResult &Result) {
const auto *ArrayType = Result.Nodes.getNodeAs<TypeLoc>("typeloc");
-
+ const bool IsInParam =
+ Result.Nodes.getNodeAs<ParmVarDecl>("param_decl") != nullptr;
+ const bool IsVLA = ArrayType->getTypePtr()->isVariableArrayType();
+ enum class RecommendType { Array, Vector, Span };
+ llvm::SmallVector<const char *> RecommendTypes{};
+ if (IsVLA) {
+ RecommendTypes.push_back("std::vector<>");
+ } else if (ArrayType->getTypePtr()->isIncompleteArrayType() && IsInParam) {
+ // in function parameter, we also don't know the size of
+ // IncompleteArrayType.
+ if (Result.Context->getLangOpts().CPlusPlus20)
+ RecommendTypes.push_back("std::span<>");
+ else {
+ RecommendTypes.push_back("std::array<>");
+ RecommendTypes.push_back("std::vector<>");
+ }
+ } else {
+ RecommendTypes.push_back("std::array<>");
+ }
diag(ArrayType->getBeginLoc(),
- "do not declare %select{C-style|C VLA}0 arrays, use "
- "%select{std::array<>|std::vector<>}0 instead")
- << ArrayType->getTypePtr()->isVariableArrayType();
+ "do not declare %select{C-style|C VLA}0 arrays, use %1 instead")
+ << IsVLA << llvm::join(RecommendTypes, " or ");
}
} // namespace clang::tidy::modernize