Skip to content

Commit 8301bee

Browse files
committed
[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.
1 parent 2626916 commit 8301bee

File tree

6 files changed

+52
-6
lines changed

6 files changed

+52
-6
lines changed

clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
using namespace clang::ast_matchers;
1414

15+
namespace clang::tidy::modernize {
16+
1517
namespace {
1618

1719
AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) {
@@ -38,16 +40,31 @@ AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) {
3840

3941
} // namespace
4042

41-
namespace clang::tidy::modernize {
43+
AvoidCArraysCheck::AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context)
44+
: ClangTidyCheck(Name, Context),
45+
AllowStringArrays(Options.get("AllowStringArrays", false)) {}
46+
47+
void AvoidCArraysCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
48+
Options.store(Opts, "AllowStringArrays", AllowStringArrays);
49+
}
4250

4351
void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) {
52+
ast_matchers::internal::Matcher<TypeLoc> IgnoreStringArrayIfNeededMatcher =
53+
anything();
54+
if (AllowStringArrays)
55+
IgnoreStringArrayIfNeededMatcher =
56+
unless(typeLoc(loc(hasCanonicalType(incompleteArrayType(
57+
hasElementType(isAnyCharacter())))),
58+
hasParent(varDecl(hasInitializer(stringLiteral())))));
59+
4460
Finder->addMatcher(
4561
typeLoc(hasValidBeginLoc(), hasType(arrayType()),
4662
unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())),
4763
hasParent(varDecl(isExternC())),
4864
hasParent(fieldDecl(
4965
hasParent(recordDecl(isExternCContext())))),
50-
hasAncestor(functionDecl(isExternC())))))
66+
hasAncestor(functionDecl(isExternC())))),
67+
std::move(IgnoreStringArrayIfNeededMatcher))
5168
.bind("typeloc"),
5269
this);
5370
}

clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,19 @@ namespace clang::tidy::modernize {
1919
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/avoid-c-arrays.html
2020
class AvoidCArraysCheck : public ClangTidyCheck {
2121
public:
22-
AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context)
23-
: ClangTidyCheck(Name, Context) {}
22+
AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context);
23+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
24+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
25+
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
2426
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
2527
return LangOpts.CPlusPlus11;
2628
}
27-
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
28-
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
29+
std::optional<TraversalKind> getCheckTraversalKind() const override {
30+
return TK_IgnoreUnlessSpelledInSource;
31+
}
32+
33+
private:
34+
const bool AllowStringArrays;
2935
};
3036

3137
} // namespace clang::tidy::modernize

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,11 @@ Changes in existing checks
330330
<clang-tidy/checks/modernize/avoid-bind>` check to
331331
not emit a ``return`` for fixes when the function returns ``void``.
332332

333+
- Improved :doc:`modernize-avoid-c-arrays
334+
<clang-tidy/checks/modernize/avoid-c-arrays>` check by introducing the new
335+
`AllowStringArrays` option, enabling the exclusion of array types with deduced
336+
sizes constructed from string literals.
337+
333338
- Improved :doc:`modernize-loop-convert
334339
<clang-tidy/checks/modernize/loop-convert>` to support for-loops with
335340
iterators initialized by free functions like ``begin``, ``end``, or ``size``

clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-c-arrays.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,12 @@ such headers between C code, and C++ code.
5858
Similarly, the ``main()`` function is ignored. Its second and third parameters
5959
can be either ``char* argv[]`` or ``char** argv``, but cannot be
6060
``std::array<>``.
61+
62+
.. option:: AllowStringArrays
63+
64+
When set to `true` (default is `false`), incomplete array types constructed
65+
from string literals will be ignored. Example:
66+
67+
.. code:: c++
68+
69+
const char name[] = "Some name";
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t -- \
2+
// RUN: -config='{CheckOptions: { modernize-avoid-c-arrays.AllowStringArrays: true }}'
3+
4+
const char name[] = "name";
5+
const char array[] = {'n', 'a', 'm', 'e', '\0'};
6+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays]

clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-arrays.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ struct Bar {
8686
int j[1];
8787
};
8888
}
89+
90+
const char name[] = "Some string";
91+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays]

0 commit comments

Comments
 (0)