[clang-tools-extra] b777bb7 - [clang-tidy] Add AllowStringArrays option to modernize-avoid-c-arrays (#71701)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 31 21:47:56 PST 2024


Author: Piotr Zegar
Date: 2024-02-01T06:47:53+01:00
New Revision: b777bb78b302055eba876a0258ea4b2625ffe71a

URL: https://github.com/llvm/llvm-project/commit/b777bb78b302055eba876a0258ea4b2625ffe71a
DIFF: https://github.com/llvm/llvm-project/commit/b777bb78b302055eba876a0258ea4b2625ffe71a.diff

LOG: [clang-tidy] Add AllowStringArrays option to modernize-avoid-c-arrays (#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

Added: 
    clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp

Modified: 
    clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
    clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst
    clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
index d1b15479ffe7a..89790ea70cf22 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,32 @@ 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()),
+                                         unless(parmVarDecl())))));
+
   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 7099f99c86949..719e88e4b3166 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 ad99fe9d08f9c..2a7749d71405c 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -106,6 +106,11 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+- 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
+  length initialized from string literals.
+
 Removed checks
 ^^^^^^^^^^^^^^
 

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 bc61033ff1fa1..8f13ca4466a31 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,14 @@ 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`), variables of character array type
+  with deduced length, initialized directly from string literals, will be ignored.
+  This option doesn't affect cases where length can't be deduced, resembling
+  pointers, as seen in class members and parameters. 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 0000000000000..f6d64848f9e3a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp
@@ -0,0 +1,9 @@
+// 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]
+
+void takeCharArray(const char name[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:26: 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 dd3078010eb38..ce99f0821b223 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,9 @@ 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]
+
+void takeCharArray(const char name[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays]


        


More information about the cfe-commits mailing list