[clang-tools-extra] [clang-tidy] Fix bugprone-bad-signal-to-kill-thread not working in clangd (PR #180711)
Alex Wang via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 10 02:05:22 PST 2026
https://github.com/aeft updated https://github.com/llvm/llvm-project/pull/180711
>From 5fe305db9007a1a1d174dac86d732c184145f7c1 Mon Sep 17 00:00:00 2001
From: Alex Wang <yesterda9 at gmail.com>
Date: Tue, 10 Feb 2026 01:51:18 -0800
Subject: [PATCH] [clang-tidy] Fix bugprone-bad-signal-to-kill-thread not
working in clangd
After preamble deserialization, Token::getLiteralData() returns nullptr for macro tokens defined in headers. Fall back to SourceManager to retrieve the token text from the source buffer.
Fixes https://github.com/clangd/clangd/issues/2473
---
.../bugprone/BadSignalToKillThreadCheck.cpp | 24 ++++++++++++++++---
.../clangd/unittests/DiagnosticsTests.cpp | 19 +++++++++++++++
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp
index 3e1188d5e2463..4a5fdeeadcb86 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp
@@ -33,14 +33,32 @@ void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) {
KeyValue.first->hasMacroDefinition();
};
const auto TryExpandAsInteger =
- [](Preprocessor::macro_iterator It) -> std::optional<unsigned> {
+ [&Result](Preprocessor::macro_iterator It) -> std::optional<unsigned> {
if (It == PP->macro_end())
return std::nullopt;
const MacroInfo *MI = PP->getMacroInfo(It->first);
const Token &T = MI->tokens().back();
- if (!T.isLiteral() || !T.getLiteralData())
+
+ if (!T.isLiteral())
return std::nullopt;
- const StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+
+ StringRef ValueStr;
+ if (T.getLiteralData()) {
+ ValueStr = StringRef(T.getLiteralData(), T.getLength());
+ } else {
+ const SourceManager *SM = Result.SourceManager;
+ const SourceLocation Loc = T.getLocation();
+ if (Loc.isInvalid())
+ return std::nullopt;
+ std::optional<StringRef> Buffer =
+ SM->getBufferDataOrNone(SM->getFileID(Loc));
+ if (!Buffer)
+ return std::nullopt;
+ const unsigned Offset = SM->getFileOffset(Loc);
+ if (Offset + T.getLength() > Buffer->size())
+ return std::nullopt;
+ ValueStr = Buffer->substr(Offset, T.getLength());
+ }
llvm::APInt IntValue;
constexpr unsigned AutoSenseRadix = 0;
diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
index f9ff6f21009f3..84ceddbd4fc4b 100644
--- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -823,6 +823,25 @@ TEST(DiagnosticTest, ClangTidyNoLiteralDataInMacroToken) {
EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre()); // no-crash
}
+TEST(DiagnosticTest, BadSignalToKillThreadInPreamble) {
+ Annotations Main(R"cpp(
+ #include "signal.h"
+ using pthread_t = int;
+ int pthread_kill(pthread_t thread, int sig);
+ int func() {
+ pthread_t thread;
+ return pthread_kill(thread, 15);
+ }
+ )cpp");
+ TestTU TU = TestTU::withCode(Main.code());
+ TU.HeaderFilename = "signal.h";
+ TU.HeaderCode = "#define SIGTERM 15";
+ TU.ClangTidyProvider = addTidyChecks("bugprone-bad-signal-to-kill-thread");
+ EXPECT_THAT(TU.build().getDiagnostics(),
+ ifTidyChecks(UnorderedElementsAre(
+ diagName("bugprone-bad-signal-to-kill-thread"))));
+}
+
TEST(DiagnosticTest, ClangTidyMacroToEnumCheck) {
Annotations Main(R"cpp(
#if 1
More information about the cfe-commits
mailing list