Skip to content

Commit f94ed6f

Browse files
authored
[clang-tidy] Improved --verify-config when using literal style in config file (#85591)
Specifying checks using the literal style (|) in the clang-tidy config file is currently supported but was not implemented for the --verify-config options. This means that clang-tidy would work properly but, using the --verify-config option would raise an error due to some checks not being parsed properly. Fixes #53737
1 parent 9c9dea9 commit f94ed6f

File tree

5 files changed

+45
-45
lines changed

5 files changed

+45
-45
lines changed

clang-tools-extra/clang-tidy/GlobList.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ static bool consumeNegativeIndicator(StringRef &GlobList) {
1919
return GlobList.consume_front("-");
2020
}
2121

22-
// Converts first glob from the comma-separated list of globs to Regex and
23-
// removes it and the trailing comma from the GlobList.
24-
static llvm::Regex consumeGlob(StringRef &GlobList) {
22+
// Extracts the first glob from the comma-separated list of globs,
23+
// removes it and the trailing comma from the GlobList and
24+
// returns the extracted glob.
25+
static llvm::StringRef extractNextGlob(StringRef &GlobList) {
2526
StringRef UntrimmedGlob = GlobList.substr(0, GlobList.find_first_of(",\n"));
2627
StringRef Glob = UntrimmedGlob.trim();
2728
GlobList = GlobList.substr(UntrimmedGlob.size() + 1);
29+
return Glob;
30+
}
31+
32+
static llvm::Regex createRegexFromGlob(StringRef &Glob) {
2833
SmallString<128> RegexText("^");
2934
StringRef MetaChars("()^$|*+?.[]\\{}");
3035
for (char C : Glob) {
@@ -43,7 +48,8 @@ GlobList::GlobList(StringRef Globs, bool KeepNegativeGlobs /* =true */) {
4348
do {
4449
GlobListItem Item;
4550
Item.IsPositive = !consumeNegativeIndicator(Globs);
46-
Item.Regex = consumeGlob(Globs);
51+
Item.Text = extractNextGlob(Globs);
52+
Item.Regex = createRegexFromGlob(Item.Text);
4753
if (Item.IsPositive || KeepNegativeGlobs)
4854
Items.push_back(std::move(Item));
4955
} while (!Globs.empty());

clang-tools-extra/clang-tidy/GlobList.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,12 @@ class GlobList {
4444
struct GlobListItem {
4545
bool IsPositive;
4646
llvm::Regex Regex;
47+
llvm::StringRef Text;
4748
};
4849
SmallVector<GlobListItem, 0> Items;
50+
51+
public:
52+
const SmallVectorImpl<GlobListItem> &getItems() const { return Items; };
4953
};
5054

5155
/// A \p GlobList that caches search results, so that search is performed only

clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -454,52 +454,27 @@ static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n";
454454

455455
static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob,
456456
StringRef Source) {
457-
llvm::StringRef Cur, Rest;
457+
GlobList Globs(CheckGlob);
458458
bool AnyInvalid = false;
459-
for (std::tie(Cur, Rest) = CheckGlob.split(',');
460-
!(Cur.empty() && Rest.empty()); std::tie(Cur, Rest) = Rest.split(',')) {
461-
Cur = Cur.trim();
462-
if (Cur.empty())
459+
for (const auto &Item : Globs.getItems()) {
460+
if (Item.Text.starts_with("clang-diagnostic"))
463461
continue;
464-
Cur.consume_front("-");
465-
if (Cur.starts_with("clang-diagnostic"))
466-
continue;
467-
if (Cur.contains('*')) {
468-
SmallString<128> RegexText("^");
469-
StringRef MetaChars("()^$|*+?.[]\\{}");
470-
for (char C : Cur) {
471-
if (C == '*')
472-
RegexText.push_back('.');
473-
else if (MetaChars.contains(C))
474-
RegexText.push_back('\\');
475-
RegexText.push_back(C);
476-
}
477-
RegexText.push_back('$');
478-
llvm::Regex Glob(RegexText);
479-
std::string Error;
480-
if (!Glob.isValid(Error)) {
481-
AnyInvalid = true;
482-
llvm::WithColor::error(llvm::errs(), Source)
483-
<< "building check glob '" << Cur << "' " << Error << "'\n";
484-
continue;
485-
}
486-
if (llvm::none_of(AllChecks.keys(),
487-
[&Glob](StringRef S) { return Glob.match(S); })) {
488-
AnyInvalid = true;
462+
if (llvm::none_of(AllChecks.keys(),
463+
[&Item](StringRef S) { return Item.Regex.match(S); })) {
464+
AnyInvalid = true;
465+
if (Item.Text.contains('*'))
489466
llvm::WithColor::warning(llvm::errs(), Source)
490-
<< "check glob '" << Cur << "' doesn't match any known check"
467+
<< "check glob '" << Item.Text << "' doesn't match any known check"
491468
<< VerifyConfigWarningEnd;
469+
else {
470+
llvm::raw_ostream &Output =
471+
llvm::WithColor::warning(llvm::errs(), Source)
472+
<< "unknown check '" << Item.Text << '\'';
473+
llvm::StringRef Closest = closest(Item.Text, AllChecks);
474+
if (!Closest.empty())
475+
Output << "; did you mean '" << Closest << '\'';
476+
Output << VerifyConfigWarningEnd;
492477
}
493-
} else {
494-
if (AllChecks.contains(Cur))
495-
continue;
496-
AnyInvalid = true;
497-
llvm::raw_ostream &Output = llvm::WithColor::warning(llvm::errs(), Source)
498-
<< "unknown check '" << Cur << '\'';
499-
llvm::StringRef Closest = closest(Cur, AllChecks);
500-
if (!Closest.empty())
501-
Output << "; did you mean '" << Closest << '\'';
502-
Output << VerifyConfigWarningEnd;
503478
}
504479
}
505480
return AnyInvalid;

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ Improvements to clang-tidy
103103
- Improved :program:`check_clang_tidy.py` script. Added argument `-export-fixes`
104104
to aid in clang-tidy and test development.
105105

106+
- Fixed ``--verify-config`` option not properly parsing checks when using the
107+
literal operator in the ``.clang-tidy`` config.
108+
106109
New checks
107110
^^^^^^^^^^
108111

clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,15 @@
1818
// CHECK-VERIFY: command-line option '-checks': warning: check glob 'bad*glob' doesn't match any known check [-verify-config]
1919
// CHECK-VERIFY: command-line option '-checks': warning: unknown check 'llvm-includeorder'; did you mean 'llvm-include-order' [-verify-config]
2020
// CHECK-VERIFY: command-line option '-checks': warning: unknown check 'my-made-up-check' [-verify-config]
21+
22+
// RUN: echo -e 'Checks: |\n bugprone-argument-comment\n bugprone-assert-side-effect,\n bugprone-bool-pointer-implicit-conversion\n readability-use-anyof*' > %T/MyClangTidyConfig
23+
// RUN: clang-tidy -verify-config \
24+
// RUN: --config-file=%T/MyClangTidyConfig | FileCheck %s -check-prefix=CHECK-VERIFY-BLOCK-OK
25+
// CHECK-VERIFY-BLOCK-OK: No config errors detected.
26+
27+
// RUN: echo -e 'Checks: |\n bugprone-arguments-*\n bugprone-assert-side-effects\n bugprone-bool-pointer-implicit-conversion' > %T/MyClangTidyConfigBad
28+
// RUN: not clang-tidy -verify-config \
29+
// RUN: --config-file=%T/MyClangTidyConfigBad 2>&1 | FileCheck %s -check-prefix=CHECK-VERIFY-BLOCK-BAD
30+
// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: check glob 'bugprone-arguments-*' doesn't match any known check [-verify-config]
31+
// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: unknown check 'bugprone-assert-side-effects'; did you mean 'bugprone-assert-side-effect' [-verify-config]
32+

0 commit comments

Comments
 (0)