https://github.com/aeft updated https://github.com/llvm/llvm-project/pull/180711
>From 814eb399deab6443a8001bdbf351bbe9785712ac Mon Sep 17 00:00:00 2001 From: Alex Wang <[email protected]> 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..18985024e7c72 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; + SourceLocation Loc = T.getLocation(); + if (Loc.isInvalid()) + return std::nullopt; + std::optional<StringRef> Buffer = + SM->getBufferDataOrNone(SM->getFileID(Loc)); + if (!Buffer) + return std::nullopt; + 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
