Skip to content

Commit c14fce8

Browse files
committed
improved regex matching, updated docs
1 parent 43153e3 commit c14fce8

File tree

4 files changed

+29
-19
lines changed

4 files changed

+29
-19
lines changed

clang-tools-extra/clang-tidy/bugprone/CastToStructCheck.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ namespace clang::tidy::bugprone {
1818
CastToStructCheck::CastToStructCheck(StringRef Name, ClangTidyContext *Context)
1919
: ClangTidyCheck(Name, Context),
2020
IgnoredCasts(
21-
utils::options::parseStringList(Options.get("IgnoredCasts", ""))) {}
21+
utils::options::parseStringList(Options.get("IgnoredCasts", ""))) {
22+
IgnoredCastsRegex.reserve(IgnoredCasts.size());
23+
for (const auto &Str : IgnoredCasts)
24+
IgnoredCastsRegex.emplace_back(Str);
25+
}
2226

2327
void CastToStructCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
2428
Options.store(Opts, "IgnoredCasts",
@@ -60,14 +64,12 @@ void CastToStructCheck::check(const MatchFinder::MatchResult &Result) {
6064

6165
const std::string FromName = FromPointee->getAsString();
6266
const std::string ToName = ToPointee->getAsString();
63-
llvm::Regex FromR;
64-
llvm::Regex ToR;
65-
for (auto [Idx, Str] : llvm::enumerate(IgnoredCasts)) {
67+
bool FromMatch = false;
68+
for (auto [Idx, Regex] : llvm::enumerate(IgnoredCastsRegex)) {
6669
if (Idx % 2 == 0) {
67-
FromR = llvm::Regex(Str);
70+
FromMatch = Regex.match(FromName);
6871
} else {
69-
ToR = llvm::Regex(Str);
70-
if (FromR.match(FromName) && ToR.match(ToName))
72+
if (FromMatch && Regex.match(ToName))
7173
return;
7274
}
7375
}

clang-tools-extra/clang-tidy/bugprone/CastToStructCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class CastToStructCheck : public ClangTidyCheck {
3030

3131
private:
3232
std::vector<llvm::StringRef> IgnoredCasts;
33+
std::vector<llvm::Regex> IgnoredCastsRegex;
3334
};
3435

3536
} // namespace clang::tidy::bugprone

clang-tools-extra/docs/clang-tidy/checks/bugprone/cast-to-struct.rst

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,16 @@ Options
5252
types to ignore. The list should contain pairs of type names in a way that
5353
the first type is the "from" type, the second is the "to" type in a cast
5454
expression. The types in a pair and the pairs itself are separated by
55-
`;` characters. For example `char;Type1;char;Type2` specifies that the
56-
check does not produce warning for casts from ``char *`` to ``Type1 *`` and
57-
casts from ``char *`` to ``Type2 *``. The list entries can be regular
58-
expressions. The type name in the cast expression is matched without
59-
resolution of type aliases like ``typedef``. Default value is empty list.
60-
(Casts from ``void *`` are ignored always regardless of this list.)
55+
`;` characters. For example `char;struct Type1;char;struct Type2` specifies
56+
that the check does not produce warning for casts from ``char *`` to
57+
``struct Type1 *`` and casts from ``char *`` to ``struct Type2 *`` (the `*`
58+
character to indicate pointer should not be used in the list). The type name
59+
in the cast expression is matched without resolution of type aliases like
60+
``typedef``.
61+
62+
The list entries are matched as substring regular expressions. For example
63+
`char` would match `unsigned char` too. This problem can be avoided by using
64+
anchor characters (`^char$`).
65+
66+
Default value of the option is an empty list. (Casts from ``void *`` are
67+
ignored always regardless of this list.)

clang-tools-extra/test/clang-tidy/checkers/bugprone/cast-to-struct-ignore.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %check_clang_tidy %s bugprone-cast-to-struct %t -- \
2-
// RUN: -config="{CheckOptions: {bugprone-cast-to-struct.IgnoredCasts: 'char;S1;int;Other*'}}"
2+
// RUN: -config="{CheckOptions: {bugprone-cast-to-struct.IgnoredCasts: '^char$;^struct S1$;^int$;Other'}}"
33

44
struct S1 {
55
int a;
@@ -9,7 +9,7 @@ struct S2 {
99
char a;
1010
};
1111

12-
struct OtherS {
12+
struct SomeOtherS {
1313
int a;
1414
int b;
1515
};
@@ -22,10 +22,10 @@ void test1(char *p1, int *p2) {
2222
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: casting a 'char *' pointer to a 'struct S2 *'
2323
s2 = (struct S2 *)p2;
2424
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: casting a 'int *' pointer to a 'struct S2 *'
25-
struct OtherS *s3;
26-
s3 = (struct OtherS *)p2;
27-
s3 = (struct OtherS *)p1;
28-
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: casting a 'char *' pointer to a 'struct OtherS *'
25+
struct SomeOtherS *s3;
26+
s3 = (struct SomeOtherS *)p2;
27+
s3 = (struct SomeOtherS *)p1;
28+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: casting a 'char *' pointer to a 'struct SomeOtherS *'
2929
}
3030

3131
struct S2 *test_void_is_always_ignored(void *p) {

0 commit comments

Comments
 (0)