Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -35,6 +35,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Regex.h" #include +#include #include using namespace clang; using namespace tidy; @@ -321,11 +322,11 @@ static bool isNOLINTFound(StringRef NolintDirectiveText, StringRef CheckName, StringRef Line, size_t *FoundNolintIndex = nullptr, - bool *SuppressionIsSpecific = nullptr) { + StringRef *FoundNolintChecksStr = nullptr) { if (FoundNolintIndex) *FoundNolintIndex = StringRef::npos; - if (SuppressionIsSpecific) - *SuppressionIsSpecific = false; + if (FoundNolintChecksStr) + *FoundNolintChecksStr = StringRef(); size_t NolintIndex = Line.find(NolintDirectiveText); if (NolintIndex == StringRef::npos) @@ -345,18 +346,13 @@ if (BracketEndIndex != StringRef::npos) { StringRef ChecksStr = Line.substr(BracketIndex, BracketEndIndex - BracketIndex); - // Allow disabling all the checks with "*". - if (ChecksStr != "*") { - // Allow specifying a few check names, delimited with comma. - SmallVector Checks; - ChecksStr.split(Checks, ',', -1, false); - llvm::transform(Checks, Checks.begin(), - [](StringRef S) { return S.trim(); }); - if (llvm::find(Checks, CheckName) == Checks.end()) - return false; - if (SuppressionIsSpecific) - *SuppressionIsSpecific = true; - } + if (FoundNolintChecksStr) + *FoundNolintChecksStr = ChecksStr; + // Allow specifying a few checks with a glob expression, ignoring + // negative globs (which would effectively disable the suppression) + GlobList Globs(ChecksStr, /*KeepNegativeGlobs=*/false); + if (!Globs.contains(CheckName)) + return false; } } @@ -388,28 +384,27 @@ return Error; } -static Optional -tallyNolintBegins(const ClangTidyContext &Context, const SourceManager &SM, - StringRef CheckName, SmallVector Lines, - SourceLocation LinesLoc, - SmallVector &SpecificNolintBegins, - SmallVector &GlobalNolintBegins) { - // Keep a running total of how many NOLINT(BEGIN...END) blocks are active. +static Optional tallyNolintBegins( + const ClangTidyContext &Context, const SourceManager &SM, + StringRef CheckName, SmallVector Lines, SourceLocation LinesLoc, + SmallVector> &NolintBegins) { + // Keep a running total of how many NOLINT(BEGIN...END) blocks are active, as + // well as the bracket expression (if any) that was used in the NOLINT + // expression. size_t NolintIndex; - bool SuppressionIsSpecific; - auto List = [&]() -> SmallVector * { - return SuppressionIsSpecific ? &SpecificNolintBegins : &GlobalNolintBegins; - }; + StringRef NolintChecksStr; for (const auto &Line : Lines) { if (isNOLINTFound("NOLINTBEGIN", CheckName, Line, &NolintIndex, - &SuppressionIsSpecific)) { + &NolintChecksStr)) { // Check if a new block is being started. - List()->emplace_back(LinesLoc.getLocWithOffset(NolintIndex)); + NolintBegins.emplace_back(std::make_pair( + LinesLoc.getLocWithOffset(NolintIndex), NolintChecksStr)); } else if (isNOLINTFound("NOLINTEND", CheckName, Line, &NolintIndex, - &SuppressionIsSpecific)) { + &NolintChecksStr)) { // Check if the previous block is being closed. - if (!List()->empty()) { - List()->pop_back(); + if (!NolintBegins.empty() && + (NolintBegins.back().second == NolintChecksStr)) { + NolintBegins.pop_back(); } else { // Trying to close a nonexistent block. Return a diagnostic about this // misuse that can be displayed along with the original clang-tidy check @@ -432,41 +427,32 @@ StringRef TextAfterDiag) { Loc = SM.getExpansionRange(Loc).getBegin(); SourceLocation FileStartLoc = SM.getLocForStartOfFile(SM.getFileID(Loc)); + SmallVector> NolintBegins; // Check if there's an open NOLINT(BEGIN...END) block on the previous lines. SmallVector PrevLines; TextBeforeDiag.split(PrevLines, '\n'); - SmallVector SpecificNolintBegins; - SmallVector GlobalNolintBegins; - auto Error = - tallyNolintBegins(Context, SM, CheckName, PrevLines, FileStartLoc, - SpecificNolintBegins, GlobalNolintBegins); + auto Error = tallyNolintBegins(Context, SM, CheckName, PrevLines, + FileStartLoc, NolintBegins); if (Error) { SuppressionErrors.emplace_back(Error.getValue()); - return false; } - bool WithinNolintBegin = - !SpecificNolintBegins.empty() || !GlobalNolintBegins.empty(); + bool WithinNolintBegin = !NolintBegins.empty(); // Check that every block is terminated correctly on the following lines. SmallVector FollowingLines; TextAfterDiag.split(FollowingLines, '\n'); Error = tallyNolintBegins(Context, SM, CheckName, FollowingLines, Loc, - SpecificNolintBegins, GlobalNolintBegins); + NolintBegins); if (Error) { SuppressionErrors.emplace_back(Error.getValue()); - return false; } // The following blocks were never closed. Return diagnostics for each // instance that can be displayed along with the original clang-tidy check // that the user was attempting to suppress. - for (const auto NolintBegin : SpecificNolintBegins) { - auto Error = createNolintError(Context, SM, NolintBegin, true); - SuppressionErrors.emplace_back(Error); - } - for (const auto NolintBegin : GlobalNolintBegins) { - auto Error = createNolintError(Context, SM, NolintBegin, true); + for (const auto NolintBegin : NolintBegins) { + auto Error = createNolintError(Context, SM, NolintBegin.first, true); SuppressionErrors.emplace_back(Error); } Index: clang-tools-extra/clang-tidy/GlobList.h =================================================================== --- clang-tools-extra/clang-tidy/GlobList.h +++ clang-tools-extra/clang-tidy/GlobList.h @@ -29,7 +29,10 @@ /// /// An empty \p Globs string is interpreted as one glob that matches an empty /// string. - GlobList(StringRef Globs); + /// + /// \p KeepNegativeGlobs a bool flag indicating whether to keep negative + /// globs from \p Globs or not. When false, negative globs are simply ignored. + GlobList(StringRef Globs, bool KeepNegativeGlobs = true); /// Returns \c true if the pattern matches \p S. The result is the last /// matching glob's Positive flag. Index: clang-tools-extra/clang-tidy/GlobList.cpp =================================================================== --- clang-tools-extra/clang-tidy/GlobList.cpp +++ clang-tools-extra/clang-tidy/GlobList.cpp @@ -42,13 +42,14 @@ return llvm::Regex(RegexText); } -GlobList::GlobList(StringRef Globs) { +GlobList::GlobList(StringRef Globs, bool KeepNegativeGlobs /* =true */) { Items.reserve(Globs.count(',') + 1); do { GlobListItem Item; Item.IsPositive = !consumeNegativeIndicator(Globs); Item.Regex = consumeGlob(Globs); - Items.push_back(std::move(Item)); + if (Item.IsPositive || KeepNegativeGlobs) + Items.push_back(std::move(Item)); } while (!Globs.empty()); } Index: clang-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -67,6 +67,9 @@ Improvements to clang-tidy -------------------------- +- Added support for globbing in `NOLINT*` expressions, to simplify suppressing + multiple warnings in the same line. + - Added support for `NOLINTBEGIN` ... `NOLINTEND` comments to suppress Clang-Tidy warnings over multiple lines. Index: clang-tools-extra/docs/clang-tidy/index.rst =================================================================== --- clang-tools-extra/docs/clang-tidy/index.rst +++ clang-tools-extra/docs/clang-tidy/index.rst @@ -173,11 +173,11 @@ errors were found. If compiler errors have attached fix-its, clang-tidy will apply them as well. - --fix-notes - - If a warning has no fix, but a single fix can - be found through an associated diagnostic note, - apply the fix. - Specifying this flag will implicitly enable the + --fix-notes - + If a warning has no fix, but a single fix can + be found through an associated diagnostic note, + apply the fix. + Specifying this flag will implicitly enable the '--fix' flag. --format-style= - Style for formatting code around applied fixes: @@ -308,7 +308,9 @@ comments). All comments can be followed by an optional list of check names in parentheses -(see below for the formal syntax). +(see below for the formal syntax). The list of check names supports globbing, +with the same format and semantics as for enabling checks. Note: negative globs +are ignored here, as they would effectively re-activate the warning. For example: @@ -324,6 +326,12 @@ // Silence only the specified checks for the line Foo(double param); // NOLINT(google-explicit-constructor, google-runtime-int) + // Silence all checks from the `google` module + Foo(bool param); // NOLINT(google*) + + // Silence all checks ending with `-avoid-c-arrays` + int array[10]; // NOLINT(*-avoid-c-arrays) + // Silence only the specified diagnostics for the next line // NOLINTNEXTLINE(google-explicit-constructor, google-runtime-int) Foo(bool param); Index: clang-tools-extra/test/clang-tidy/infrastructure/nolint.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/infrastructure/nolint.cpp +++ clang-tools-extra/test/clang-tidy/infrastructure/nolint.cpp @@ -1,5 +1,5 @@ // REQUIRES: static-analyzer -// RUN: %check_clang_tidy %s google-explicit-constructor,clang-diagnostic-unused-variable,clang-analyzer-core.UndefinedBinaryOperatorResult %t -- -extra-arg=-Wunused-variable -- -I%S/Inputs/nolint +// RUN: %check_clang_tidy %s google-explicit-constructor,clang-diagnostic-unused-variable,clang-analyzer-core.UndefinedBinaryOperatorResult,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays %t -- -extra-arg=-Wunused-variable -- -I%S/Inputs/nolint #include "trigger_warning.h" void I(int& Out) { @@ -17,17 +17,20 @@ class C { C(int i); }; // NOLINT(for-some-other-check) // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit -class C1 { C1(int i); }; // NOLINT(*) +class C1 { C1(int i); }; // NOLINT() +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit + +class C2 { C2(int i); }; // NOLINT(*) -class C2 { C2(int i); }; // NOLINT(not-closed-bracket-is-treated-as-skip-all +class C3 { C3(int i); }; // NOLINT(not-closed-bracket-is-treated-as-skip-all -class C3 { C3(int i); }; // NOLINT(google-explicit-constructor) +class C4 { C4(int i); }; // NOLINT(google-explicit-constructor) -class C4 { C4(int i); }; // NOLINT(some-check, google-explicit-constructor) +class C5 { C5(int i); }; // NOLINT(some-check, google-explicit-constructor) -class C5 { C5(int i); }; // NOLINT without-brackets-skip-all, another-check +class C6 { C6(int i); }; // NOLINT without-brackets-skip-all, another-check -class C6 { C6(int i); }; // NOLINTNEXTLINE doesn't get misconstrued as a NOLINT +class C7 { C7(int i); }; // NOLINTNEXTLINE doesn't get misconstrued as a NOLINT // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit void f() { @@ -51,4 +54,21 @@ #define DOUBLE_MACRO MACRO(H) // NOLINT DOUBLE_MACRO -// CHECK-MESSAGES: Suppressed 13 warnings (13 NOLINT) +class D1 { D1(int x); }; // NOLINT(google*) +class D2 { D2(int x); }; // NOLINT(*explicit-constructor) +class D3 { D3(int x); }; // NOLINT(*explicit*) +class D4 { D4(int x); }; // NOLINT(-explicit-constructor) +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit +class D5 { D5(int x); }; // NOLINT(google*,-google*) +class D6 { D6(int x); }; // NOLINT(*,-google*) + +int array1[10]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays] + +int array2[10]; // NOLINT(cppcoreguidelines-avoid-c-arrays) +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays] + +int array3[10]; // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays) +int array4[10]; // NOLINT(*-avoid-c-arrays) + +// CHECK-MESSAGES: Suppressed 23 warnings (23 NOLINT) Index: clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-begin-global-end-specific.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-begin-global-end-specific.cpp +++ clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-begin-global-end-specific.cpp @@ -11,3 +11,15 @@ // CHECK: :[[@LINE-6]]:4: error: unmatched 'NOLIN // CHECK: TEND' comment without a previous 'NOLIN // CHECK: TBEGIN' comment [clang-tidy-nolint] + +// NOLINTBEGIN +class B { B(int i); }; +// NOLINTEND(*) + +// Note: the expected output has been split over several lines so that clang-tidy +// does not see the "no lint" suppression comment and mistakenly assume it +// is meant for itself. +// CHECK: :[[@LINE-6]]:11: warning: single-argument constructors must be marked explicit +// CHECK: :[[@LINE-6]]:4: error: unmatched 'NOLIN +// CHECK: TEND' comment without a previous 'NOLIN +// CHECK: TBEGIN' comment [clang-tidy-nolint] Index: clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-begin-specific-end-global.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-begin-specific-end-global.cpp +++ clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-begin-specific-end-global.cpp @@ -11,3 +11,15 @@ // CHECK: :[[@LINE-6]]:4: error: unmatched 'NOLIN // CHECK: TEND' comment without a previous 'NOLIN // CHECK: TBEGIN' comment [clang-tidy-nolint] + +// NOLINTBEGIN(*) +class B { B(int i); }; +// NOLINTEND + +// Note: the expected output has been split over several lines so that clang-tidy +// does not see the "no lint" suppression comment and mistakenly assume it +// is meant for itself. +// CHECK: :[[@LINE-6]]:11: warning: single-argument constructors must be marked explicit +// CHECK: :[[@LINE-6]]:4: error: unmatched 'NOLIN +// CHECK: TEND' comment without a previous 'NOLIN +// CHECK: TBEGIN' comment [clang-tidy-nolint] Index: clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-mismatched-check-names.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-mismatched-check-names.cpp +++ clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend-mismatched-check-names.cpp @@ -16,3 +16,24 @@ // CHECK: :[[@LINE-10]]:4: error: unmatched 'NOLIN // CHECK: TEND' comment without a previous 'NOLIN // CHECK: TBEGIN' comment [clang-tidy-nolint] + +// NOLINTBEGIN(google-explicit-constructor,google-readability-casting) +class B { B(int i); }; +// NOLINTEND(google-explicit-constructor) +auto Num2 = (unsigned int)(-1); +// NOLINTEND(google-readability-casting) + +// Note: the expected output has been split over several lines so that clang-tidy +// does not see the "no lint" suppression comment and mistakenly assume it +// is meant for itself. +// CHECK: :[[@LINE-9]]:4: error: unmatched 'NOLIN +// CHECK: TBEGIN' comment without a subsequent 'NOLIN +// CHECK: TEND' comment [clang-tidy-nolint] +// CHECK: :[[@LINE-11]]:11: warning: single-argument constructors must be marked explicit +// CHECK: :[[@LINE-11]]:4: error: unmatched 'NOLIN +// CHECK: TEND' comment without a previous 'NOLIN +// CHECK: TBEGIN' comment [clang-tidy-nolint] +// CHECK: :[[@LINE-13]]:13: warning: C-style casts are discouraged; use static_cast +// CHECK: :[[@LINE-13]]:4: error: unmatched 'NOLIN +// CHECK: TEND' comment without a previous 'NOLIN +// CHECK: TBEGIN' comment [clang-tidy-nolint] Index: clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend.cpp +++ clang-tools-extra/test/clang-tidy/infrastructure/nolintbeginend.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s google-explicit-constructor %t +// RUN: %check_clang_tidy %s google-explicit-constructor,clang-diagnostic-unused-variable,cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays %t -- -extra-arg=-Wunused-variable class A { A(int i); }; // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit @@ -34,60 +34,54 @@ class C1 { C1(int i); }; // NOLINTEND(google-explicit-constructor) -// NOLINTBEGIN(*) +// NOLINTBEGIN() class C2 { C2(int i); }; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit +// NOLINTEND() + +// NOLINTBEGIN(*) +class C3 { C3(int i); }; // NOLINTEND(*) // NOLINTBEGIN(some-other-check) -class C3 { C3(int i); }; +class C4 { C4(int i); }; // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit // NOLINTEND(some-other-check) // NOLINTBEGIN(some-other-check, google-explicit-constructor) -class C4 { C4(int i); }; -// NOLINTEND(some-other-check, google-explicit-constructor) - -// NOLINTBEGIN(some-other-check, google-explicit-constructor) -// NOLINTEND(some-other-check) class C5 { C5(int i); }; -// NOLINTEND(google-explicit-constructor) - -// NOLINTBEGIN(some-other-check, google-explicit-constructor) -// NOLINTEND(google-explicit-constructor) -class C6 { C6(int i); }; -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit -// NOLINTEND(some-other-check) +// NOLINTEND(some-other-check, google-explicit-constructor) // NOLINTBEGIN(google-explicit-constructor) // NOLINTBEGIN(some-other-check) -class C7 { C7(int i); }; +class C6 { C6(int i); }; // NOLINTEND(some-other-check) // NOLINTEND(google-explicit-constructor) // NOLINTBEGIN(google-explicit-constructor) // NOLINTBEGIN(some-other-check) -class C8 { C8(int i); }; +class C7 { C7(int i); }; // NOLINTEND(google-explicit-constructor) // NOLINTEND(some-other-check) // NOLINTBEGIN(google-explicit-constructor) // NOLINTBEGIN -class C9 { C9(int i); }; +class C8 { C8(int i); }; // NOLINTEND // NOLINTEND(google-explicit-constructor) // NOLINTBEGIN // NOLINTBEGIN(google-explicit-constructor) -class C10 { C10(int i); }; +class C9 { C9(int i); }; // NOLINTEND(google-explicit-constructor) // NOLINTEND // NOLINTBEGIN(not-closed-bracket-is-treated-as-skip-all -class C11 { C11(int i); }; +class C10 { C10(int i); }; // NOLINTEND(not-closed-bracket-is-treated-as-skip-all // NOLINTBEGIN without-brackets-skip-all, another-check -class C12 { C12(int i); }; +class C11 { C11(int i); }; // NOLINTEND without-brackets-skip-all, another-check #define MACRO(X) class X { X(int i); }; @@ -119,4 +113,45 @@ MACRO_NO_LINT_INSIDE_MACRO -// CHECK-MESSAGES: Suppressed 18 warnings (18 NOLINT). +// NOLINTBEGIN(google*) +class C12 { C12(int i); }; +// NOLINTEND(google*) + +// NOLINTBEGIN(*explicit-constructor) +class C15 { C15(int i); }; +// NOLINTEND(*explicit-constructor) + +// NOLINTBEGIN(*explicit*) +class C16 { C16(int i); }; +// NOLINTEND(*explicit*) + +// NOLINTBEGIN(-explicit-constructor) +class C17 { C17(int x); }; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: single-argument constructors must be marked explicit +// NOLINTEND(-explicit-constructor) + +// NOLINTBEGIN(google*,-google*) +class C18 { C18(int x); }; +// NOLINTEND(google*,-google*) + +// NOLINTBEGIN(*,-google*) +class C19 { C19(int x); }; +// NOLINTEND(*,-google*) + +int array1[10]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays] + +// NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays) +int array2[10]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays] +// NOLINTEND(cppcoreguidelines-avoid-c-arrays) + +// NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays) +int array3[10]; +// NOLINTEND(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays) + +// NOLINTBEGIN(*-avoid-c-arrays) +int array4[10]; +// NOLINTEND(*-avoid-c-arrays) + +// CHECK-MESSAGES: Suppressed 27 warnings (27 NOLINT). Index: clang-tools-extra/test/clang-tidy/infrastructure/nolintnextline.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/infrastructure/nolintnextline.cpp +++ clang-tools-extra/test/clang-tidy/infrastructure/nolintnextline.cpp @@ -11,21 +11,25 @@ class D { D(int i); }; // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: single-argument constructors must be marked explicit -// NOLINTNEXTLINE(*) +// NOLINTNEXTLINE() class D1 { D1(int i); }; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit -// NOLINTNEXTLINE(not-closed-bracket-is-treated-as-skip-all +// NOLINTNEXTLINE(*) class D2 { D2(int i); }; -// NOLINTNEXTLINE(google-explicit-constructor) +// NOLINTNEXTLINE(not-closed-bracket-is-treated-as-skip-all class D3 { D3(int i); }; -// NOLINTNEXTLINE(some-check, google-explicit-constructor) +// NOLINTNEXTLINE(google-explicit-constructor) class D4 { D4(int i); }; -// NOLINTNEXTLINE without-brackets-skip-all, another-check +// NOLINTNEXTLINE(some-check, google-explicit-constructor) class D5 { D5(int i); }; +// NOLINTNEXTLINE without-brackets-skip-all, another-check +class D6 { D6(int i); }; + // NOLINTNEXTLINE class E { E(int i); }; @@ -46,6 +50,38 @@ // NOLINTNEXTLINE MACRO_NOARG -// CHECK-MESSAGES: Suppressed 9 warnings (9 NOLINT) +// NOLINTNEXTLINE(google*) +class I1 { I1(int i); }; + +// NOLINTNEXTLINE(*explicit-constructor) +class I2 { I2(int i); }; + +// NOLINTNEXTLINE(*explicit*) +class I3 { I3(int i); }; + +// NOLINTNEXTLINE(-explicit-constructor) +class I4 { I4(int x); }; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: single-argument constructors must be marked explicit + +// NOLINTNEXTLINE(google*,-google*) +class I5 { I5(int x); }; + +// NOLINTNEXTLINE(*,-google*) +class I6 { I6(int x); }; + +int array1[10]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays] + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) +int array2[10]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead [modernize-avoid-c-arrays] + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays) +int array3[10]; + +// NOLINTNEXTLINE(*-avoid-c-arrays) +int array4[10]; + +// CHECK-MESSAGES: Suppressed 19 warnings (19 NOLINT) -// RUN: %check_clang_tidy %s google-explicit-constructor %t -- +// RUN: %check_clang_tidy %s google-explicit-constructor,clang-diagnostic-unused-variable,cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays %t -- -extra-arg=-Wunused-variable