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 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 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 + ` 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]