https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/71701
>From 050d53bdbc01be93a15f6851faddc24e520f0472 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <m...@piotrzegar.pl> Date: Wed, 8 Nov 2023 16:52:06 +0000 Subject: [PATCH 1/4] [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 d1b15479ffe7a..ab1cdd62aa2cc 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 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 fd2cba4e4f463..94b51f919f80a 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 + sizes constructed 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..acc628d58f80e 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 0000000000000..545429b2be807 --- /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 dd3078010eb38..4233f69337898 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] >From b4c4573d505fe0df63ed4252fb49e46e5c1a7afb Mon Sep 17 00:00:00 2001 From: Piotr Zegar <m...@piotrzegar.pl> Date: Mon, 29 Jan 2024 22:44:31 +0000 Subject: [PATCH 2/4] Explicitly exclude function arguments --- clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp | 5 ++--- .../checkers/modernize/avoid-c-arrays-ignores-strings.cpp | 3 +++ .../test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp index ab1cdd62aa2cc..8118d8335853a 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -53,9 +53,8 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { anything(); if (AllowStringArrays) IgnoreStringArrayIfNeededMatcher = - unless(typeLoc(loc(hasCanonicalType(incompleteArrayType( - hasElementType(isAnyCharacter())))), - hasParent(varDecl(hasInitializer(stringLiteral()))))); + unless(typeLoc(loc(hasCanonicalType(incompleteArrayType(hasElementType(isAnyCharacter())))), + hasParent(varDecl(hasInitializer(stringLiteral()), unless(parmVarDecl()))))); Finder->addMatcher( typeLoc(hasValidBeginLoc(), hasType(arrayType()), 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 index 545429b2be807..f6d64848f9e3a 100644 --- 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 @@ -4,3 +4,6 @@ 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 4233f69337898..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 @@ -89,3 +89,6 @@ struct Bar { 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] >From 3d108c3e30aa7b63dbfbaff76f7309e5b9e0d4f3 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <m...@piotrzegar.pl> Date: Wed, 31 Jan 2024 17:57:55 +0000 Subject: [PATCH 3/4] Formating --- .../clang-tidy/modernize/AvoidCArraysCheck.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp index 8118d8335853a..89790ea70cf22 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -53,8 +53,10 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { anything(); if (AllowStringArrays) IgnoreStringArrayIfNeededMatcher = - unless(typeLoc(loc(hasCanonicalType(incompleteArrayType(hasElementType(isAnyCharacter())))), - hasParent(varDecl(hasInitializer(stringLiteral()), unless(parmVarDecl()))))); + unless(typeLoc(loc(hasCanonicalType(incompleteArrayType( + hasElementType(isAnyCharacter())))), + hasParent(varDecl(hasInitializer(stringLiteral()), + unless(parmVarDecl()))))); Finder->addMatcher( typeLoc(hasValidBeginLoc(), hasType(arrayType()), >From cebb72648c62650d607bfcc11a349860f4898e1d Mon Sep 17 00:00:00 2001 From: Piotr Zegar <m...@piotrzegar.pl> Date: Wed, 31 Jan 2024 19:26:25 +0000 Subject: [PATCH 4/4] Update documentation --- clang-tools-extra/docs/ReleaseNotes.rst | 2 +- .../docs/clang-tidy/checks/modernize/avoid-c-arrays.rst | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 94b51f919f80a..9f183f615da49 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -109,7 +109,7 @@ 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 - sizes constructed from string literals. + 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 acc628d58f80e..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 @@ -61,8 +61,10 @@ can be either ``char* argv[]`` or ``char** argv``, but cannot be .. option:: AllowStringArrays - When set to `true` (default is `false`), incomplete array types constructed - from string literals will be ignored. Example: + 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++ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits