llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: Alex Wang (aeft)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/180711.diff


2 Files Affected:

- (modified) 
clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp (+20-3) 
- (modified) clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp (+19) 


``````````diff
diff --git 
a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp
index 3e1188d5e2463..e655197185c2f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp
@@ -33,14 +33,31 @@ 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

``````````

</details>


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

Reply via email to