https://github.com/t-a-james updated 
https://github.com/llvm/llvm-project/pull/215239

>From cb8448b0054e402707be02464d9eed254d17653a Mon Sep 17 00:00:00 2001
From: Tom James <[email protected]>
Date: Mon, 10 Aug 2026 11:52:40 +0100
Subject: [PATCH] [clang-tidy] New portability-avoid-pragma-comment

Finds uses of `#pragma comment` and, for `lib` or `linker` comments,
suggests using the build system for improved portability.

`#pragma comment` is not widely supported outside of MSVC. Clang
supports the use of `#pragma comment` to link libraries on both Windows
and Linux, but other kinds are only supported on Windows.  Using `pragma
comment` to change link flags may be unexpected in projects that prefer
to set these flags in the build system.
---
 .../portability/AvoidPragmaCommentCheck.cpp   | 50 +++++++++++++++++++
 .../portability/AvoidPragmaCommentCheck.h     | 37 ++++++++++++++
 .../clang-tidy/portability/CMakeLists.txt     |  1 +
 .../portability/PortabilityTidyModule.cpp     |  3 ++
 clang-tools-extra/docs/ReleaseNotes.md        |  6 +++
 .../docs/clang-tidy/checks/list.md            |  1 +
 .../portability/avoid-pragma-comment.md       | 24 +++++++++
 .../portability/avoid-pragma-comment.cpp      | 49 ++++++++++++++++++
 8 files changed, 171 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-comment.md
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-comment.cpp

diff --git 
a/clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.cpp 
b/clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.cpp
new file mode 100644
index 0000000000000..1b2f5d92687b8
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "AvoidPragmaCommentCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+#include <string>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+static const internal::VariadicDynCastAllOfMatcher<Decl, PragmaCommentDecl>
+    // All other node matchers declared in this way are camelCase
+    // NOLINTNEXTLINE(readability-identifier-naming)
+    pragmaCommentDecl;
+
+void AvoidPragmaCommentCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(pragmaCommentDecl().bind("pragma"), this);
+}
+
+void AvoidPragmaCommentCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Pragma = Result.Nodes.getNodeAs<PragmaCommentDecl>("pragma");
+
+  std::string Msg{"avoid 'pragma comment' directive"};
+
+  // We can give specific advice about comments that add linker flags, but 
other
+  // kinds are too generic
+  const PragmaMSCommentKind &Kind = Pragma->getCommentKind();
+  switch (Kind) {
+  case PragmaMSCommentKind::PCK_Lib:
+    Msg.append("; use the build system to link libraries");
+    break;
+  case PragmaMSCommentKind::PCK_Linker:
+    Msg.append("; use the build system to set linker options");
+    break;
+  case PragmaMSCommentKind::PCK_Unknown:
+    llvm_unreachable("unexpected pragma comment kind");
+  default:
+    break;
+  }
+  diag(Pragma->getBeginLoc(), Msg);
+}
+
+} // namespace clang::tidy::portability
diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.h 
b/clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.h
new file mode 100644
index 0000000000000..8f11f9399f248
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/portability/AvoidPragmaCommentCheck.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_PORTABILITY_AVOIDPRAGMACOMMENTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPRAGMACOMMENTCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::portability {
+
+/// Finds uses of ``#pragma comment`` and for ``lib`` or ``linker`` comments
+/// suggests using the build system for improved portability.
+///
+/// Only the "lib" pragma comment type is implemented on Linux, the rest are
+/// Windows-only and should be caught by "-Wunknown-pragmas" on Linux.
+///
+/// For the user-facing documentation see:
+/// 
https://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-pragma-comment.html
+class AvoidPragmaCommentCheck : public ClangTidyCheck {
+public:
+  AvoidPragmaCommentCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus || LangOpts.C99;
+  }
+};
+
+} // namespace clang::tidy::portability
+
+#endif // 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPRAGMACOMMENTCHECK_H
diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
index 170fedf52130e..f9bcb149b8145 100644
--- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_clang_library(clangTidyPortabilityModule STATIC
+  AvoidPragmaCommentCheck.cpp
   AvoidPragmaOnceCheck.cpp
   NoAssemblerCheck.cpp
   PortabilityTidyModule.cpp
diff --git a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
index 1f2340502f685..c12ef3d20e871 100644
--- a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp
@@ -8,6 +8,7 @@
 
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
+#include "AvoidPragmaCommentCheck.h"
 #include "AvoidPragmaOnceCheck.h"
 #include "NoAssemblerCheck.h"
 #include "RestrictSystemIncludesCheck.h"
@@ -22,6 +23,8 @@ namespace {
 class PortabilityModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<AvoidPragmaCommentCheck>(
+        "portability-avoid-pragma-comment");
     CheckFactories.registerCheck<AvoidPragmaOnceCheck>(
         "portability-avoid-pragma-once");
     CheckFactories.registerCheck<NoAssemblerCheck>("portability-no-assembler");
diff --git a/clang-tools-extra/docs/ReleaseNotes.md 
b/clang-tools-extra/docs/ReleaseNotes.md
index 9cead803ad0e5..6b19d88c50be5 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -108,6 +108,12 @@ infrastructure are described first, followed by 
tool-specific sections.
   Finds calls to `value_or` (and alternative spellings `valueOr`,
   `ValueOr`) on optional types where the return type is expensive to copy.
 
+- New {doc}`portability-avoid-pragma-comment
+  <clang-tidy/checks/portability/avoid-pragma-comment>` check.
+
+  Finds uses of `#pragma comment` and, for `lib` or `linker` comments, suggests
+  using the build system for improved portability.
+
 - New {doc}`readability-redundant-zero-initializer
   <clang-tidy/checks/readability/redundant-zero-initializer>` check.
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.md 
b/clang-tools-extra/docs/clang-tidy/checks/list.md
index 8af70e55f18fb..a4696e192ef47 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.md
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.md
@@ -372,6 +372,7 @@ readability/*
 | {doc}`performance-unnecessary-copy-initialization 
<performance/unnecessary-copy-initialization>` | Yes |
 | {doc}`performance-unnecessary-value-param 
<performance/unnecessary-value-param>` | Yes |
 | {doc}`performance-use-std-move <performance/use-std-move>` | Yes |
+| {doc}`portability-avoid-pragma-comment <portability/avoid-pragma-comment>` | 
 |
 | {doc}`portability-avoid-pragma-once <portability/avoid-pragma-once>` |  |
 | {doc}`portability-no-assembler <portability/no-assembler>` |  |
 | {doc}`portability-restrict-system-includes 
<portability/restrict-system-includes>` | Yes |
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-comment.md 
b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-comment.md
new file mode 100644
index 0000000000000..46a43b6a2396e
--- /dev/null
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-pragma-comment.md
@@ -0,0 +1,24 @@
+```{title} clang-tidy - portability-avoid-pragma-comment
+```
+
+# portability-avoid-pragma-comment
+
+Finds uses of `#pragma comment` and, for `lib` or `linker` comments, suggests
+using the build system for improved portability.
+
+`#pragma comment` is not widely supported outside of MSVC. Clang supports the
+use of `#pragma comment` to link libraries on both Windows and Linux, but other
+kinds are only supported on Windows. Using `pragma comment` to change link 
flags
+may be unexpected in projects that prefer to set these flags in the build
+system.
+
+```c++
+// Clang supports the `lib` kind on Windows and Linux, but setting link flags
+// outside the build system may be unexpected
+#pragma comment(lib, "some_lib")
+#pragma comment(linker, "some_linker_flag")
+
+// Clang only supports the `compiler` and `user` kinds when targeting Windows
+#pragma comment(compiler)
+#pragma comment(user, "Some string")
+```
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-comment.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-comment.cpp
new file mode 100644
index 0000000000000..cb8cfbc0faf87
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-pragma-comment.cpp
@@ -0,0 +1,49 @@
+// Only the "lib" pragma comment type is implemented on Linux, the rest are
+// Windows-only.  We test for both platform targets.
+// RUN: %check_clang_tidy -check-suffixes=LINUX %s 
portability-avoid-pragma-comment %t -- -- -target x86_64-unknown-linux-gnu
+// RUN: %check_clang_tidy -check-suffixes=WINDOWS %s 
portability-avoid-pragma-comment %t -- -- -target x86_64-pc-windows-msvc
+
+#pragma comment(lib, "some_lib")
+// CHECK-MESSAGES-LINUX:   :[[@LINE-1]]:9: warning: avoid 'pragma comment' 
directive; use the build system to link libraries 
[portability-avoid-pragma-comment]
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-2]]:9: warning: avoid 'pragma comment' 
directive; use the build system to link libraries 
[portability-avoid-pragma-comment]
+
+_Pragma("comment(lib, \"some_lib\")")
+// CHECK-MESSAGES-LINUX:   :[[@LINE-1]]:1: warning: avoid 'pragma comment' 
directive; use the build system to link libraries 
[portability-avoid-pragma-comment]
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-2]]:1: warning: avoid 'pragma comment' 
directive; use the build system to link libraries 
[portability-avoid-pragma-comment]
+
+// The rest are Windows-only and should be caught by "-Wunknown-pragmas" or
+// "-Wignored-pragmas" on Linux.  On Linux they won't show up in the AST, so
+// portability-avoid-pragma-comment won't detect them.
+
+#pragma comment(linker, "some_linker_flag")
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:9: warning: avoid 'pragma comment' 
directive; use the build system to set linker options 
[portability-avoid-pragma-comment]
+
+#pragma comment(compiler)
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:9: warning: avoid 'pragma comment' 
directive [portability-avoid-pragma-comment]
+
+#pragma comment(user, "Some string")
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:9: warning: avoid 'pragma comment' 
directive [portability-avoid-pragma-comment]
+
+_Pragma("comment(linker, \"some_linker_flag\")")
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:1: warning: avoid 'pragma comment' 
directive; use the build system to set linker options 
[portability-avoid-pragma-comment]
+
+_Pragma("comment(compiler)")
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:1: warning: avoid 'pragma comment' 
directive [portability-avoid-pragma-comment]
+
+_Pragma("comment(user, \"Some string\")")
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:1: warning: avoid 'pragma comment' 
directive [portability-avoid-pragma-comment]
+
+// __pragma() is a Microsoft-specific extension
+#ifdef _MSC_VER 
+__pragma(comment(lib, "some_lib"))
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:10: warning: avoid 'pragma comment' 
directive; use the build system to link libraries 
[portability-avoid-pragma-comment]
+
+__pragma(comment(linker, "some_linker_flag"))
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:10: warning: avoid 'pragma comment' 
directive; use the build system to set linker options 
[portability-avoid-pragma-comment]
+
+__pragma(comment(compiler))
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:10: warning: avoid 'pragma comment' 
directive [portability-avoid-pragma-comment]
+
+__pragma(comment(user, "Some string"))
+// CHECK-MESSAGES-WINDOWS: :[[@LINE-1]]:10: warning: avoid 'pragma comment' 
directive [portability-avoid-pragma-comment]
+#endif

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to