https://github.com/localspook updated https://github.com/llvm/llvm-project/pull/173196
>From 34c52f3abe4786aaedecf30c916713b365691952 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <[email protected]> Date: Sun, 21 Dec 2025 10:05:40 -0700 Subject: [PATCH 1/2] [clang-tidy] Add first-class C support to `misc-use-internal-linkage` --- .../misc/UseInternalLinkageCheck.cpp | 6 ++-- .../checks/misc/use-internal-linkage.rst | 17 ++++++---- .../misc/use-internal-linkage-consteval.cpp | 2 +- .../use-internal-linkage-fix-mode-none.cpp | 4 +-- .../misc/use-internal-linkage-func.cpp | 24 +++++++------- .../misc/use-internal-linkage-var.cpp | 10 +++--- .../checkers/misc/use-internal-linkage.c | 33 +++++++++++++++++++ 7 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage.c diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp index bad51c600f1cb..254de05e5e464 100644 --- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp @@ -137,13 +137,13 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) { } static constexpr StringRef Message = - "%0 %1 can be made static or moved into an anonymous namespace " + "%0 %1 can be made static %select{|or moved into an anonymous namespace }2" "to enforce internal linkage"; void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("fn")) { const DiagnosticBuilder DB = diag(FD->getLocation(), Message) - << "function" << FD; + << "function" << FD << getLangOpts().CPlusPlus; const SourceLocation FixLoc = FD->getInnerLocStart(); if (FixLoc.isInvalid() || FixLoc.isMacroID()) return; @@ -159,7 +159,7 @@ void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) { return; const DiagnosticBuilder DB = diag(VD->getLocation(), Message) - << "variable" << VD; + << "variable" << VD << getLangOpts().CPlusPlus; const SourceLocation FixLoc = VD->getInnerLocStart(); if (FixLoc.isInvalid() || FixLoc.isMacroID()) return; diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst index 224ad21ecc5c3..9e08e0c12d644 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst @@ -3,8 +3,8 @@ misc-use-internal-linkage ========================= -Detects variables and functions that can be marked as static or moved into -an anonymous namespace to enforce internal linkage. +Detects variables and functions that can be marked as static or (in C++) +moved into an anonymous namespace to enforce internal linkage. Static functions and variables are scoped to a single file. Marking functions and variables as static helps to better remove dead code. In addition, it gives @@ -18,17 +18,20 @@ Example: void fn1() {} // can be marked as static - namespace { - // already in anonymous namespace - int v2; - void fn2(); - } // already declared as extern extern int v2; void fn3(); // without function body in all declaration, maybe external linkage void fn3(); + // === C++-specific === + + namespace { + // already in anonymous namespace + int v2; + void fn2(); + } + // export declarations export void fn4() {} export namespace t { void fn5() {} } diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-consteval.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-consteval.cpp index 62c9818e07c4f..b63e87da25cea 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-consteval.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-consteval.cpp @@ -3,5 +3,5 @@ consteval void gh122096() {} constexpr void cxf() {} -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: function 'cxf' +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: function 'cxf' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static constexpr void cxf() {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-fix-mode-none.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-fix-mode-none.cpp index 3f2f5897bf718..8eb4a40d2d7d6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-fix-mode-none.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-fix-mode-none.cpp @@ -2,9 +2,9 @@ // RUN: -config="{CheckOptions: {misc-use-internal-linkage.FixMode: 'None'}}" -- -I%S/Inputs/use-internal-linkage void func() {} -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func' +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES-NOT: static void func() {} int global; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global' +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES-NOT: static int global; diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp index abf95b857c192..9ec851b8ac0d6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp @@ -5,51 +5,51 @@ #include "func.h" void func() {} -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func' +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static void func() {} template<class T> void func_template() {} -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_template' +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_template' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static void func_template() {} void func_cpp_inc() {} -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc' +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static void func_cpp_inc() {} int* func_cpp_inc_return_ptr() { return nullptr; } -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc_return_ptr' +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc_return_ptr' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static int* func_cpp_inc_return_ptr() { return nullptr; } const int* func_cpp_inc_return_const_ptr() { return nullptr; } -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'func_cpp_inc_return_const_ptr' +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'func_cpp_inc_return_const_ptr' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static const int* func_cpp_inc_return_const_ptr() { return nullptr; } int const* func_cpp_inc_return_ptr_const() { return nullptr; } -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'func_cpp_inc_return_ptr_const' +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'func_cpp_inc_return_ptr_const' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static int const* func_cpp_inc_return_ptr_const() { return nullptr; } int * const func_cpp_inc_return_const() { return nullptr; } -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: function 'func_cpp_inc_return_const' +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: function 'func_cpp_inc_return_const' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static int * const func_cpp_inc_return_const() { return nullptr; } volatile const int* func_cpp_inc_return_volatile_const_ptr() { return nullptr; } -// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: function 'func_cpp_inc_return_volatile_const_ptr' +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: function 'func_cpp_inc_return_volatile_const_ptr' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static volatile const int* func_cpp_inc_return_volatile_const_ptr() { return nullptr; } [[nodiscard]] void func_nodiscard() {} -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: function 'func_nodiscard' +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: function 'func_nodiscard' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: {{\[\[nodiscard\]\]}} static void func_nodiscard() {} #define NDS [[nodiscard]] #define NNDS NDS void func_nds() {} -// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'func_nds' +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'func_nds' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: NDS static void func_nds() {} NNDS void func_nnds() {} -// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'func_nnds' +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'func_nnds' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: NNDS static void func_nnds() {} #include "func_cpp.inc" @@ -78,7 +78,7 @@ extern "C" void func_extern_c_2() {} namespace gh117488 { void func_with_body(); -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_with_body' +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_with_body' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static void func_with_body(); void func_with_body() {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp index 3da05c71dd94f..548f585fcbd31 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp @@ -5,24 +5,24 @@ #include "var.h" int global; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global' +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static int global; template<class T> T global_template; -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: variable 'global_template' +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: variable 'global_template' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static T global_template; int const* ptr_const_star; -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'ptr_const_star' +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'ptr_const_star' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static int const* ptr_const_star; const int* const_ptr_star; -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'const_ptr_star' +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'const_ptr_star' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static const int* const_ptr_star; const volatile int* const_volatile_ptr_star; -// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: variable 'const_volatile_ptr_star' +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: variable 'const_volatile_ptr_star' can be made static or moved into an anonymous namespace to enforce internal linkage // CHECK-FIXES: static const volatile int* const_volatile_ptr_star; int gloabl_header; diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage.c b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage.c new file mode 100644 index 0000000000000..a1b431e1bb28a --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage.c @@ -0,0 +1,33 @@ +// RUN: %check_clang_tidy %s misc-use-internal-linkage %t -- -- -I%S/Inputs/use-internal-linkage +// RUN: %check_clang_tidy %s misc-use-internal-linkage %t -- \ +// RUN: -config="{CheckOptions: {misc-use-internal-linkage.FixMode: 'UseStatic'}}" -- -I%S/Inputs/use-internal-linkage + +#include "func.h" + +void func() {} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func' can be made static to enforce internal linkage +// CHECK-FIXES: static void func() {} + +void func_header() {} +extern void func_extern() {} +static void func_static() {} + +int main() {} + + +#include "var.h" + +int global; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global' can be made static to enforce internal linkage +// CHECK-FIXES: static int global; + +const int const_global = 123; +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: variable 'const_global' can be made static to enforce internal linkage +// CHECK-FIXES: static const int const_global = 123; + +int gloabl_header; +extern int global_extern; +static int global_static; +#if __STDC_VERSION__ >= 201112L +_Thread_local int global_thread_local; +#endif >From 9e541f77f4b4bd09dff1386495caf90ef08ca7a8 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <[email protected]> Date: Sun, 21 Dec 2025 11:53:27 -0700 Subject: [PATCH 2/2] TMP --- clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp index 254de05e5e464..ca09235014ad0 100644 --- a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp @@ -68,7 +68,7 @@ AST_MATCHER(FunctionDecl, hasBody) { return Node.hasBody(); } AST_MATCHER_P(Decl, isAllRedeclsInMainFile, FileExtensionsSet, HeaderFileExtensions) { return llvm::all_of(Node.redecls(), [&](const Decl *D) { - return isInMainFile(D->getLocation(), + return isInMainFile(D->getLocation(),isInMainFile Finder->getASTContext().getSourceManager(), HeaderFileExtensions); }); @@ -115,7 +115,7 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) { // 1. internal linkage isStaticStorageClass(), isInAnonymousNamespace(), // 2. explicit external linkage - isExternStorageClass(), isExternC(), + // isExternStorageClass(), isExternC(), // 3. template isExplicitTemplateSpecialization(), hasAncestor(decl(anyOf( _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
