summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Zegar <me@piotrzegar.pl>2024-02-01 06:47:53 +0100
committerGitHub <noreply@github.com>2024-02-01 06:47:53 +0100
commitb777bb78b302055eba876a0258ea4b2625ffe71a (patch)
tree342ebf36d49d387bb52de423882a5a8d915d3780
parent8eea582dcb900afb45866a09296624b6fef9dd20 (diff)
[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
-rw-r--r--clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp22
-rw-r--r--clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h14
-rw-r--r--clang-tools-extra/docs/ReleaseNotes.rst5
-rw-r--r--clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst11
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays-ignores-strings.cpp9
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp6
6 files changed, 61 insertions, 6 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
index d1b15479ffe7..89790ea70cf2 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 7099f99c8694..719e88e4b316 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 ad99fe9d08f9..2a7749d71405 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 bc61033ff1fa..8f13ca4466a3 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 000000000000..f6d64848f9e3
--- /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 dd3078010eb3..ce99f0821b22 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]