[clang-tools-extra] [clang-tidy] Add AllowStringArrays option to modernize-avoid-c-arrays (PR #71701)
Piotr Zegar via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 8 08:58:56 PST 2023
https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/71701
Add AllowStringArrays option, enabling the exclusion of array types with deduced sizes constructed from string literals. This includes only var declarations of array of characters constructed directly from c-strings.
Closes #59475
>From 8301beef04a70e54232cafdb24949e8f961b2aa7 Mon Sep 17 00:00:00 2001
From: Piotr Zegar <me at piotrzegar.pl>
Date: Wed, 8 Nov 2023 16:52:06 +0000
Subject: [PATCH] [clang-tidy] Add AllowStringArrays option to
modernize-avoid-c-arrays
Add AllowStringArrays option, enabling the exclusion of array types with deduced
sizes constructed from string literals. This includes only var declarations
of array of characters constructed directly from c-strings.
---
.../modernize/AvoidCArraysCheck.cpp | 21 +++++++++++++++++--
.../clang-tidy/modernize/AvoidCArraysCheck.h | 14 +++++++++----
clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++
.../checks/modernize/avoid-c-arrays.rst | 9 ++++++++
.../avoid-c-arrays-ignores-strings.cpp | 6 ++++++
.../checkers/modernize/avoid-c-arrays.cpp | 3 +++
6 files changed, 52 insertions(+), 6 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
index d1b15479ffe7a93..ab1cdd62aa2cc01 100644
--- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
@@ -12,6 +12,8 @@
using namespace clang::ast_matchers;
+namespace clang::tidy::modernize {
+
namespace {
AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) {
@@ -38,16 +40,31 @@ AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) {
} // namespace
-namespace clang::tidy::modernize {
+AvoidCArraysCheck::AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ AllowStringArrays(Options.get("AllowStringArrays", false)) {}
+
+void AvoidCArraysCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "AllowStringArrays", AllowStringArrays);
+}
void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) {
+ ast_matchers::internal::Matcher<TypeLoc> IgnoreStringArrayIfNeededMatcher =
+ anything();
+ if (AllowStringArrays)
+ IgnoreStringArrayIfNeededMatcher =
+ unless(typeLoc(loc(hasCanonicalType(incompleteArrayType(
+ hasElementType(isAnyCharacter())))),
+ hasParent(varDecl(hasInitializer(stringLiteral())))));
+
Finder->addMatcher(
typeLoc(hasValidBeginLoc(), hasType(arrayType()),
unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())),
hasParent(varDecl(isExternC())),
hasParent(fieldDecl(
hasParent(recordDecl(isExternCContext())))),
- hasAncestor(functionDecl(isExternC())))))
+ hasAncestor(functionDecl(isExternC())))),
+ std::move(IgnoreStringArrayIfNeededMatcher))
.bind("typeloc"),
this);
}
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h
index 7099f99c869498f..719e88e4b31662f 100644
--- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h
@@ -19,13 +19,19 @@ namespace clang::tidy::modernize {
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/avoid-c-arrays.html
class AvoidCArraysCheck : public ClangTidyCheck {
public:
- AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context);
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus11;
}
- void registerMatchers(ast_matchers::MatchFinder *Finder) override;
- void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
+
+private:
+ const bool AllowStringArrays;
};
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index fe8c7175d554c7b..97e532abbf8c715 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -330,6 +330,11 @@ Changes in existing checks
<clang-tidy/checks/modernize/avoid-bind>` check to
not emit a ``return`` for fixes when the function returns ``void``.
+- Improved :doc:`modernize-avoid-c-arrays
+ <clang-tidy/checks/modernize/avoid-c-arrays>` check by introducing the new
+ `AllowStringArrays` option, enabling the exclusion of array types with deduced
+ sizes constructed from string literals.
+
- Improved :doc:`modernize-loop-convert
<clang-tidy/checks/modernize/loop-convert>` to support for-loops with
iterators initialized by free functions like ``begin``, ``end``, or ``size``
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst
index bc61033ff1fa1fa..acc628d58f80ee0 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst
@@ -58,3 +58,12 @@ such headers between C code, and C++ code.
Similarly, the ``main()`` function is ignored. Its second and third parameters
can be either ``char* argv[]`` or ``char** argv``, but cannot be
``std::array<>``.
+
+.. option:: AllowStringArrays
+
+ When set to `true` (default is `false`), incomplete array types constructed
+ from string literals will be ignored. Example:
+
+ .. code:: c++
+
+ const char name[] = "Some name";
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp
new file mode 100644
index 000000000000000..545429b2be807e9
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp
@@ -0,0 +1,6 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t -- \
+// RUN: -config='{CheckOptions: { modernize-avoid-c-arrays.AllowStringArrays: true }}'
+
+const char name[] = "name";
+const char array[] = {'n', 'a', 'm', 'e', '\0'};
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays]
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp
index dd3078010eb3805..4233f69337898ee 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp
@@ -86,3 +86,6 @@ struct Bar {
int j[1];
};
}
+
+const char name[] = "Some string";
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays]
More information about the cfe-commits
mailing list