https://github.com/thorsten-klein updated https://github.com/llvm/llvm-project/pull/177315
>From d9248398b6765a9c934bb8d3c609b03add7fb8c2 Mon Sep 17 00:00:00 2001 From: Thorsten Klein <[email protected]> Date: Thu, 22 Jan 2026 08:33:13 +0100 Subject: [PATCH 1/2] [clang-tidy] Add a new check `misc-header-guard` Find and fix header guards It respects option `misc-header-guard.HeaderDirs`, which contains a list of one or more header directory names. --- .../clang-tidy/misc/CMakeLists.txt | 1 + .../clang-tidy/misc/HeaderGuardCheck.cpp | 55 ++++++ .../clang-tidy/misc/HeaderGuardCheck.h | 34 ++++ .../clang-tidy/misc/MiscTidyModule.cpp | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 8 + .../clang-tidy/checks/misc/header-guard.rst | 20 +++ .../clang-tidy/checkers/misc/header-guard.cpp | 165 ++++++++++++++++++ .../misc/header-guard/include/correct.hpp | 7 + .../misc/header-guard/include/missing.hpp | 3 + .../header-guard/include/other/correct.hpp | 7 + .../header-guard/include/other/missing.hpp | 3 + .../misc/header-guard/include/other/wrong.hpp | 7 + .../misc/header-guard/include/wrong.hpp | 7 + 13 files changed, 319 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/misc/header-guard.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/correct.hpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/missing.hpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/correct.hpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/missing.hpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/wrong.hpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/wrong.hpp diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index e34b0cf687be3..f8cb11bd3b8c1 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -23,6 +23,7 @@ add_clang_library(clangTidyMiscModule STATIC CoroutineHostileRAIICheck.cpp DefinitionsInHeadersCheck.cpp ConfusableIdentifierCheck.cpp + HeaderGuardCheck.cpp HeaderIncludeCycleCheck.cpp IncludeCleanerCheck.cpp MiscTidyModule.cpp diff --git a/clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.cpp b/clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.cpp new file mode 100644 index 0000000000000..8c3c090828821 --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "HeaderGuardCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Support/Path.h" + +namespace clang::tidy::misc { + +HeaderGuardCheck::HeaderGuardCheck(StringRef Name, ClangTidyContext *Context) + : clang::tidy::utils::HeaderGuardCheck(Name, Context), + HeaderDirs(utils::options::parseStringList( + Options.get("HeaderDirs", "include"))), + Prefix(Options.get("Prefix", "")) {} + +std::string HeaderGuardCheck::getHeaderGuard(StringRef Filename, + StringRef OldGuard) { + std::string Guard = tooling::getAbsolutePath(Filename); + + // When running under Windows, need to convert the path separators from + // `\` to `/`. + Guard = llvm::sys::path::convert_to_slash(Guard); + + // consider all directories from HeaderDirs option. Stop at first found. + for (const StringRef HeaderDir : HeaderDirs) { + const size_t PosHeaderDir = Guard.rfind(HeaderDir.str() + "/"); + if (PosHeaderDir != StringRef::npos) { + // We don't want the header dir in our guards, i.e. _INCLUDE_ + Guard = Guard.substr(PosHeaderDir + HeaderDir.size() + 1); + break; // stop at first found + } + } + + llvm::replace(Guard, '/', '_'); + llvm::replace(Guard, '.', '_'); + llvm::replace(Guard, '-', '_'); + + Guard = Prefix.str() + Guard; + + return StringRef(Guard).upper(); +} + +void HeaderGuardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "HeaderDirs", + utils::options::serializeStringList(HeaderDirs)); + Options.store(Opts, "Prefix", Prefix); +} + +} // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.h b/clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.h new file mode 100644 index 0000000000000..0aff3be7e44df --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/HeaderGuardCheck.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_HEADERGUARDCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_HEADERGUARDCHECK_H + +#include "../utils/HeaderGuard.h" + +namespace clang::tidy::misc { + +/// Finds and fixes header guards. +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/header-guard.html +class HeaderGuardCheck : public utils::HeaderGuardCheck { +public: + HeaderGuardCheck(StringRef Name, ClangTidyContext *Context); + + bool shouldSuggestEndifComment(StringRef Filename) override { return false; } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + std::string getHeaderGuard(StringRef Filename, StringRef OldGuard) override; + +private: + const std::vector<StringRef> HeaderDirs; + const StringRef Prefix; +}; + +} // namespace clang::tidy::misc + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_HEADERGUARDCHECK_H diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp index f8550b30b9789..8523031ef820e 100644 --- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp @@ -13,6 +13,7 @@ #include "ConstCorrectnessCheck.h" #include "CoroutineHostileRAIICheck.h" #include "DefinitionsInHeadersCheck.h" +#include "HeaderGuardCheck.h" #include "HeaderIncludeCycleCheck.h" #include "IncludeCleanerCheck.h" #include "MisleadingBidirectionalCheck.h" @@ -53,6 +54,7 @@ class MiscModule : public ClangTidyModule { "misc-coroutine-hostile-raii"); CheckFactories.registerCheck<DefinitionsInHeadersCheck>( "misc-definitions-in-headers"); + CheckFactories.registerCheck<HeaderGuardCheck>("misc-header-guard"); CheckFactories.registerCheck<HeaderIncludeCycleCheck>( "misc-header-include-cycle"); CheckFactories.registerCheck<IncludeCleanerCheck>("misc-include-cleaner"); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 5af634c77f54d..e943ff53acb41 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -103,6 +103,14 @@ New checks Finds and removes redundant conversions from ``std::[w|u8|u16|u32]string_view`` to ``std::[...]string`` in call expressions expecting ``std::[...]string_view``. +- New :doc:`misc-header-guard <clang-tidy/checks/misc/header-guard>` check. + + Finds and fixes header guards. + The option ``misc-header-guard.HeaderDirs`` allows configuring one or more + header directory names. Default value is ``include``. + The option ``misc-header-guard.Prefix`` allows specifying an optional prefix + that is applied to each header guard. By default, no prefix is used. + New check aliases ^^^^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/header-guard.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/header-guard.rst new file mode 100644 index 0000000000000..ee625871d7e5e --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/header-guard.rst @@ -0,0 +1,20 @@ +.. title:: clang-tidy - llvm-header-guard + +misc-header-guard +================= + +Finds and fixes header guards. + +Options +------- + +.. option:: HeaderDirs + + A list of one or more header directory names. The list is searched for the + first matching directory. The header guard string will start from there. + Default value is `include`. + +.. option:: Prefix + + A string specifying an optional prefix that is applied to each header guard. + Default is an empty string. diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard.cpp new file mode 100644 index 0000000000000..682e27b9638e5 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard.cpp @@ -0,0 +1,165 @@ +#include "header-guard/include/correct.hpp" +#include "header-guard/include/missing.hpp" +#include "header-guard/include/wrong.hpp" + +#include "header-guard/include/other/correct.hpp" +#include "header-guard/include/other/missing.hpp" +#include "header-guard/include/other/wrong.hpp" + +// --------------------------------------- +// TEST 1: Use no config options (default) +// --------------------------------------- +// RUN: %check_clang_tidy %s misc-header-guard %t -export-fixes=%t.1.yaml --header-filter=.* -- -I%S > %t.1.msg 2>&1 +// RUN: FileCheck -input-file=%t.1.msg -check-prefix=CHECK-MESSAGES1 %s +// RUN: FileCheck -input-file=%t.1.yaml -check-prefix=CHECK-YAML1 %s + +// CHECK-MESSAGES1: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES1: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES1: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES1: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] + +// CHECK-YAML1: Message: header is missing header guard +// CHECK-YAML1: FilePath: '{{.*header-guard.include.}}missing.hpp' +// CHECK-YAML1: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n" +// CHECK-YAML1: ReplacementText: "\n#endif\n" + +// CHECK-YAML1: Message: header is missing header guard +// CHECK-YAML1: FilePath: '{{.*header-guard.include.other.}}missing.hpp' +// CHECK-YAML1: ReplacementText: "#ifndef OTHER_MISSING_HPP\n#define OTHER_MISSING_HPP\n\n" +// CHECK-YAML1: ReplacementText: "\n#endif\n" + +// CHECK-YAML1: Message: header guard does not follow preferred style +// CHECK-YAML1: FilePath: '{{.*header-guard.include.other.}}wrong.hpp' +// CHECK-YAML1: ReplacementText: OTHER_WRONG_HPP + +// CHECK-YAML1: Message: header guard does not follow preferred style +// CHECK-YAML1: FilePath: '{{.*header-guard.include.}}wrong.hpp' +// CHECK-YAML1: ReplacementText: WRONG_HPP + + +// --------------------------------------- +// TEST 2: Set option HeaderDirs=other +// --------------------------------------- +// RUN: %check_clang_tidy %s misc-header-guard %t -export-fixes=%t.2.yaml --header-filter=.* \ +// RUN: --config='{CheckOptions: { \ +// RUN: misc-header-guard.HeaderDirs: other, \ +// RUN: }}' -- -I%S > %t.2.msg 2>&1 +// RUN: FileCheck -input-file=%t.2.msg -check-prefix=CHECK-MESSAGES2 %s +// RUN: FileCheck -input-file=%t.2.yaml -check-prefix=CHECK-YAML2 %s + +// CHECK-MESSAGES2: correct.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES2: correct.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES2: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES2: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES2: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES2: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] + +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*header-guard.include.}}correct.hpp' +// CHECK-YAML2: ReplacementText: {{.*}}CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_MISC_HEADER_GUARD_INCLUDE_CORRECT_HPP + +// CHECK-YAML2: Message: header is missing header guard +// CHECK-YAML2: FilePath: '{{.*header-guard.include.}}missing.hpp' +// CHECK-YAML2: ReplacementText: "#ifndef {{.*}}CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_MISC_HEADER_GUARD_INCLUDE_MISSING_HPP\n#define {{.*}}CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_MISC_HEADER_GUARD_INCLUDE_MISSING_HPP\n\n" +// CHECK-YAML2: ReplacementText: "\n#endif\n" + +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*header-guard.include.other.}}correct.hpp' +// CHECK-YAML2: ReplacementText: CORRECT_HPP + +// CHECK-YAML2: Message: header is missing header guard +// CHECK-YAML2: FilePath: '{{.*header-guard.include.other.}}missing.hpp' +// CHECK-YAML2: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n" +// CHECK-YAML2: ReplacementText: "\n#endif\n" + +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*header-guard.include.other.}}wrong.hpp' +// CHECK-YAML2: ReplacementText: WRONG_HPP + +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*header-guard.include.}}wrong.hpp' +// CHECK-YAML2: ReplacementText: {{.*}}CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_MISC_HEADER_GUARD_INCLUDE_WRONG_HPP + + +// --------------------------------------- +// TEST 3: Set option HeaderDirs=other;include +// --------------------------------------- +// RUN: %check_clang_tidy %s misc-header-guard %t -export-fixes=%t.3.yaml --header-filter=.* \ +// RUN: --config='{CheckOptions: { \ +// RUN: misc-header-guard.HeaderDirs: other;include, \ +// RUN: }}' -- -I%S > %t.3.msg 2>&1 +// RUN: FileCheck -input-file=%t.3.msg -check-prefix=CHECK-MESSAGES3 %s +// RUN: FileCheck -input-file=%t.3.yaml -check-prefix=CHECK-YAML3 %s + +// CHECK-MESSAGES3: correct.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES3: correct.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES3: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES3: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES3: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES3: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] + +// CHECK-YAML3: Message: header is missing header guard +// CHECK-YAML3: FilePath: '{{.*header-guard.include.}}missing.hpp' +// CHECK-YAML3: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n" +// CHECK-YAML3: ReplacementText: "\n#endif\n" + +// CHECK-YAML3: Message: header guard does not follow preferred style +// CHECK-YAML3: FilePath: '{{.*header-guard.include.other.}}correct.hpp' +// CHECK-YAML3: ReplacementText: CORRECT_HPP + +// CHECK-YAML3: Message: header is missing header guard +// CHECK-YAML3: FilePath: '{{.*header-guard.include.other.}}missing.hpp' +// CHECK-YAML3: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n" +// CHECK-YAML3: ReplacementText: "\n#endif\n" + +// CHECK-YAML3: Message: header guard does not follow preferred style +// CHECK-YAML3: FilePath: '{{.*header-guard.include.other.}}wrong.hpp' +// CHECK-YAML3: ReplacementText: WRONG_HPP + +// CHECK-YAML3: Message: header guard does not follow preferred style +// CHECK-YAML3: FilePath: '{{.*header-guard.include.}}wrong.hpp' +// CHECK-YAML3: ReplacementText: WRONG_HPP + + +// ------------------------------------------------------------------- +// TEST 4: Set option HeaderDirs=other;include and Prefix=SOME_PREFIX_ +// ------------------------------------------------------------------- +// RUN: %check_clang_tidy %s misc-header-guard %t -export-fixes=%t.4.yaml --header-filter=.* \ +// RUN: --config='{CheckOptions: { \ +// RUN: misc-header-guard.Prefix: SOME_PREFIX_, \ +// RUN: }}' -- -I%S > %t.4.msg 2>&1 +// RUN: FileCheck -input-file=%t.4.msg -check-prefix=CHECK-MESSAGES4 %s +// RUN: FileCheck -input-file=%t.4.yaml -check-prefix=CHECK-YAML4 %s + +// CHECK-MESSAGES4: correct.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES4: correct.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES4: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES4: missing.hpp:1:1: warning: header is missing header guard [misc-header-guard] +// CHECK-MESSAGES4: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] +// CHECK-MESSAGES4: wrong.hpp:1:9: warning: header guard does not follow preferred style [misc-header-guard] + +// CHECK-YAML4: Message: header guard does not follow preferred style +// CHECK-YAML4: FilePath: '{{.*header-guard.include.}}correct.hpp' +// CHECK-YAML4: ReplacementText: SOME_PREFIX_CORRECT_HPP + +// CHECK-YAML4: Message: header is missing header guard +// CHECK-YAML4: FilePath: '{{.*header-guard.include.}}missing.hpp' +// CHECK-YAML4: ReplacementText: "#ifndef SOME_PREFIX_MISSING_HPP\n#define SOME_PREFIX_MISSING_HPP\n\n" +// CHECK-YAML4: ReplacementText: "\n#endif\n" + +// CHECK-YAML4: Message: header guard does not follow preferred style +// CHECK-YAML4: FilePath: '{{.*header-guard.include.other.}}correct.hpp' +// CHECK-YAML4: ReplacementText: SOME_PREFIX_OTHER_CORRECT_HPP + +// CHECK-YAML4: Message: header is missing header guard +// CHECK-YAML4: FilePath: '{{.*header-guard.include.other.}}missing.hpp' +// CHECK-YAML4: ReplacementText: "#ifndef SOME_PREFIX_OTHER_MISSING_HPP\n#define SOME_PREFIX_OTHER_MISSING_HPP\n\n" +// CHECK-YAML4: ReplacementText: "\n#endif\n" + +// CHECK-YAML4: Message: header guard does not follow preferred style +// CHECK-YAML4: FilePath: '{{.*header-guard.include.other.}}wrong.hpp' +// CHECK-YAML4: ReplacementText: SOME_PREFIX_OTHER_WRONG_HPP + +// CHECK-YAML4: Message: header guard does not follow preferred style +// CHECK-YAML4: FilePath: '{{.*header-guard.include.}}wrong.hpp' +// CHECK-YAML4: ReplacementText: SOME_PREFIX_WRONG_HPP diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/correct.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/correct.hpp new file mode 100644 index 0000000000000..7eeead99748e9 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/correct.hpp @@ -0,0 +1,7 @@ +#ifndef CORRECT_HPP +#define CORRECT_HPP +#endif + +// RUN: %check_clang_tidy %s misc-header-guard correct -export-fixes=%t.yaml > %t.msg 2>&1 +// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MSG %s +// CHECK-MSG: warning: code/includes outside of area guarded by header guard; consider moving it [misc-header-guard] diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/missing.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/missing.hpp new file mode 100644 index 0000000000000..4a5a3a495a2b1 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/missing.hpp @@ -0,0 +1,3 @@ +// RUN: %check_clang_tidy %s misc-header-guard missing -export-fixes=%t.yaml > %t.msg 2>&1 +// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MSG %s +// CHECK-MSG: :1:1: warning: header is missing header guard [misc-header-guard] diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/correct.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/correct.hpp new file mode 100644 index 0000000000000..97ea9db05cd41 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/correct.hpp @@ -0,0 +1,7 @@ +#ifndef OTHER_CORRECT_HPP +#define OTHER_CORRECT_HPP +#endif + +// RUN: %check_clang_tidy %s misc-header-guard correct -export-fixes=%t.yaml > %t.msg 2>&1 +// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MSG %s +// CHECK-MSG: warning: code/includes outside of area guarded by header guard; consider moving it [misc-header-guard] diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/missing.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/missing.hpp new file mode 100644 index 0000000000000..4a5a3a495a2b1 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/missing.hpp @@ -0,0 +1,3 @@ +// RUN: %check_clang_tidy %s misc-header-guard missing -export-fixes=%t.yaml > %t.msg 2>&1 +// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MSG %s +// CHECK-MSG: :1:1: warning: header is missing header guard [misc-header-guard] diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/wrong.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/wrong.hpp new file mode 100644 index 0000000000000..a9afba832a10a --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/other/wrong.hpp @@ -0,0 +1,7 @@ +#ifndef SOME_WRONG_HEADER_GUARD_HPP +#define SOME_WRONG_HEADER_GUARD_HPP +#endif + +// RUN: %check_clang_tidy %s misc-header-guard wrong -export-fixes=%t.yaml > %t.msg 2>&1 +// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MSG %s +// CHECK-MSG: warning: header guard does not follow preferred style [misc-header-guard] diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/wrong.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/wrong.hpp new file mode 100644 index 0000000000000..e5ca81da6a680 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-guard/include/wrong.hpp @@ -0,0 +1,7 @@ +#ifndef HERE_IS_SOMETHING_WRONG_HPP +#define HERE_IS_SOMETHING_WRONG_HPP +#endif + +// RUN: %check_clang_tidy %s misc-header-guard wrong -export-fixes=%t.yaml > %t.msg 2>&1 +// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MSG %s +// CHECK-MSG: warning: header guard does not follow preferred style [misc-header-guard] >From 94ce341ed2775e11c97aac9cb32763c604f4838e Mon Sep 17 00:00:00 2001 From: Thorsten Klein <[email protected]> Date: Thu, 22 Jan 2026 08:15:20 +0100 Subject: [PATCH 2/2] Disable clang-tidy misc-header-guard This does not apply well to LLVM which intentionally have own llvm-header-guard check. --- .clang-tidy | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-tidy b/.clang-tidy index 2cda1b81de808..bb404c291cd13 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,6 +4,7 @@ Checks: > clang-diagnostic-*, llvm-*, misc-*, + -misc-header-guard, -misc-const-correctness, -misc-include-cleaner, -misc-no-recursion, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
