https://github.com/anonymouspc updated 
https://github.com/llvm/llvm-project/pull/170415

>From 983aa785ee374c9c1dcbee4846dafa3ccc62b793 Mon Sep 17 00:00:00 2001
From: anonymouspc <[email protected]>
Date: Wed, 3 Dec 2025 11:27:53 +0800
Subject: [PATCH 1/2] [Clang][Diagnose] Minimal support on
 emit-include-location in sarif mode

Implement minimal relatedLocations support for include/module notes to avoid
crashes when using -fdiagnostics-format=sarif.
---
 clang/include/clang/Basic/Sarif.h             | 13 +++++
 .../include/clang/Frontend/SARIFDiagnostic.h  |  8 +++
 clang/lib/Basic/Sarif.cpp                     |  8 +++
 clang/lib/Frontend/SARIFDiagnostic.cpp        | 52 ++++++++++++++-----
 4 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/Sarif.h 
b/clang/include/clang/Basic/Sarif.h
index a88d1ee2965a9..3ecbe4754e0df 100644
--- a/clang/include/clang/Basic/Sarif.h
+++ b/clang/include/clang/Basic/Sarif.h
@@ -325,6 +325,7 @@ class SarifResult {
   std::string HostedViewerURI;
   llvm::SmallDenseMap<StringRef, std::string, 4> PartialFingerprints;
   llvm::SmallVector<CharSourceRange, 8> Locations;
+  llvm::SmallVector<CharSourceRange, 8> RelatedLocations;
   llvm::SmallVector<ThreadFlow, 8> ThreadFlows;
   std::optional<SarifResultLevel> LevelOverride;
 
@@ -364,6 +365,18 @@ class SarifResult {
     Locations.assign(DiagLocs.begin(), DiagLocs.end());
     return *this;
   }
+
+  SarifResult setRelatedLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) {
+#ifndef NDEBUG
+    for (const auto &Loc : DiagLocs) {
+      assert(Loc.isCharRange() &&
+             "SARIF RelatedLocations require character granular source 
ranges!");
+    }
+#endif
+    RelatedLocations.assign(DiagLocs.begin(), DiagLocs.end());
+    return *this;
+  }
+
   SarifResult setThreadFlows(llvm::ArrayRef<ThreadFlow> ThreadFlowResults) {
     ThreadFlows.assign(ThreadFlowResults.begin(), ThreadFlowResults.end());
     return *this;
diff --git a/clang/include/clang/Frontend/SARIFDiagnostic.h 
b/clang/include/clang/Frontend/SARIFDiagnostic.h
index 780f36c874109..2762ad962da59 100644
--- a/clang/include/clang/Frontend/SARIFDiagnostic.h
+++ b/clang/include/clang/Frontend/SARIFDiagnostic.h
@@ -63,10 +63,18 @@ class SARIFDiagnostic : public DiagnosticRenderer {
                                   ArrayRef<CharSourceRange> Ranges,
                                   const Diagnostic &Diag);
 
+  SarifResult addRelatedLocationToResult(SarifResult Result, 
+                                         FullSourceLoc Loc, PresumedLoc PLoc);
+                                  
+  llvm::SmallVector<CharSourceRange> getSarifLocation(FullSourceLoc Loc, 
PresumedLoc PLoc,
+                                                      
ArrayRef<CharSourceRange> Ranges);
+
   SarifRule addDiagnosticLevelToRule(SarifRule Rule,
                                      DiagnosticsEngine::Level Level);
 
   llvm::StringRef emitFilename(StringRef Filename, const SourceManager &SM);
+  
+  llvm::SmallVector<std::pair<FullSourceLoc, PresumedLoc>> 
RelatedLocationsCache;
 };
 
 } // end namespace clang
diff --git a/clang/lib/Basic/Sarif.cpp b/clang/lib/Basic/Sarif.cpp
index b3fb9a21249e9..448de96d474af 100644
--- a/clang/lib/Basic/Sarif.cpp
+++ b/clang/lib/Basic/Sarif.cpp
@@ -404,6 +404,14 @@ void SarifDocumentWriter::appendResult(const SarifResult 
&Result) {
     Ret["locations"] = std::move(Locs);
   }
 
+  if (!Result.RelatedLocations.empty()) {
+    json::Array ReLocs;
+    for (auto &Range : Result.RelatedLocations) {
+      ReLocs.emplace_back(createLocation(createPhysicalLocation(Range)));
+    }
+    Ret["relatedLocations"] = std::move(ReLocs);
+  }
+
   if (!Result.PartialFingerprints.empty()) {
     json::Object fingerprints = {};
     for (auto &pair : Result.PartialFingerprints) {
diff --git a/clang/lib/Frontend/SARIFDiagnostic.cpp 
b/clang/lib/Frontend/SARIFDiagnostic.cpp
index ac27d7480de3e..684238d246026 100644
--- a/clang/lib/Frontend/SARIFDiagnostic.cpp
+++ b/clang/lib/Frontend/SARIFDiagnostic.cpp
@@ -58,12 +58,46 @@ void SARIFDiagnostic::emitDiagnosticMessage(
   if (Loc.isValid())
     Result = addLocationToResult(Result, Loc, PLoc, Ranges, *Diag);
 
+  for (auto& [RelLoc, RelPLoc] : RelatedLocationsCache)
+    Result = addRelatedLocationToResult(Result, RelLoc, RelPLoc);
+  RelatedLocationsCache.clear();
+
   Writer->appendResult(Result);
 }
 
+void SARIFDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) 
{
+  // We always emit include location before results, for example:
+  //
+  // In file included from ...
+  // In file included from ...
+  // error: ...
+  //
+  // At this time We cannot peek the SarifRule. But what we
+  // do is to push it into a cache and wait for next time
+  // \ref SARIFDiagnostic::emitDiagnosticMessage to pick it up.
+  RelatedLocationsCache.push_back({Loc, PLoc});
+}
+
+void SARIFDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, 
+                                         StringRef ModuleName) {
+  RelatedLocationsCache.push_back({Loc, PLoc});
+}
+
 SarifResult SARIFDiagnostic::addLocationToResult(
     SarifResult Result, FullSourceLoc Loc, PresumedLoc PLoc,
     ArrayRef<CharSourceRange> Ranges, const Diagnostic &Diag) {
+  auto Locations = getSarifLocation(Loc, PLoc, Ranges);
+  return Result.setLocations(Locations);
+}
+
+SarifResult SARIFDiagnostic::addRelatedLocationToResult(
+    SarifResult Result, FullSourceLoc Loc, PresumedLoc PLoc) {
+  auto Locations = getSarifLocation(Loc, PLoc, {});
+  return Result.setRelatedLocations(Locations);
+}
+
+llvm::SmallVector<CharSourceRange> SARIFDiagnostic::getSarifLocation(
+    FullSourceLoc Loc, PresumedLoc PLoc, ArrayRef<CharSourceRange> Ranges) {
   SmallVector<CharSourceRange> Locations = {};
 
   if (PLoc.isInvalid()) {
@@ -75,7 +109,7 @@ SarifResult SARIFDiagnostic::addLocationToResult(
         // FIXME(llvm-project/issues/57366): File-only locations
       }
     }
-    return Result;
+    return {};
   }
 
   FileID CaretFileID = Loc.getExpansionLoc().getFileID();
@@ -127,10 +161,11 @@ SarifResult SARIFDiagnostic::addLocationToResult(
   SourceLocation DiagLoc = SM.translateLineCol(FID, PLoc.getLine(), ColNo);
 
   // FIXME(llvm-project/issues/57366): Properly process #line directives.
-  Locations.push_back(
-      CharSourceRange{SourceRange{DiagLoc, DiagLoc}, /* ITR = */ false});
+  CharSourceRange Range = {SourceRange{DiagLoc, DiagLoc}, /* ITR = */false};
+  if (Range.isValid())
+    Locations.push_back(std::move(Range));
 
-  return Result.setLocations(Locations);
+  return Locations;
 }
 
 SarifRule
@@ -207,15 +242,6 @@ void SARIFDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, 
PresumedLoc PLoc,
   assert(false && "Not implemented in SARIF mode");
 }
 
-void SARIFDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) 
{
-  assert(false && "Not implemented in SARIF mode");
-}
-
-void SARIFDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
-                                         StringRef ModuleName) {
-  assert(false && "Not implemented in SARIF mode");
-}
-
 void SARIFDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc,
                                                  PresumedLoc PLoc,
                                                  StringRef ModuleName) {

>From af0685432bcb868630c53afd4ef9a238be114d6c Mon Sep 17 00:00:00 2001
From: anonymouspc <[email protected]>
Date: Fri, 5 Dec 2025 17:43:06 +0800
Subject: [PATCH 2/2] clang-format

---
 clang/include/clang/Basic/Sarif.h              |  5 +++--
 clang/include/clang/Frontend/SARIFDiagnostic.h | 16 +++++++++-------
 clang/lib/Frontend/SARIFDiagnostic.cpp         | 16 +++++++++-------
 3 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/Sarif.h 
b/clang/include/clang/Basic/Sarif.h
index 3ecbe4754e0df..b4f3610cc7568 100644
--- a/clang/include/clang/Basic/Sarif.h
+++ b/clang/include/clang/Basic/Sarif.h
@@ -369,8 +369,9 @@ class SarifResult {
   SarifResult setRelatedLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) {
 #ifndef NDEBUG
     for (const auto &Loc : DiagLocs) {
-      assert(Loc.isCharRange() &&
-             "SARIF RelatedLocations require character granular source 
ranges!");
+      assert(
+          Loc.isCharRange() &&
+          "SARIF RelatedLocations require character granular source ranges!");
     }
 #endif
     RelatedLocations.assign(DiagLocs.begin(), DiagLocs.end());
diff --git a/clang/include/clang/Frontend/SARIFDiagnostic.h 
b/clang/include/clang/Frontend/SARIFDiagnostic.h
index 2762ad962da59..7a6f27eb3b9fa 100644
--- a/clang/include/clang/Frontend/SARIFDiagnostic.h
+++ b/clang/include/clang/Frontend/SARIFDiagnostic.h
@@ -63,18 +63,20 @@ class SARIFDiagnostic : public DiagnosticRenderer {
                                   ArrayRef<CharSourceRange> Ranges,
                                   const Diagnostic &Diag);
 
-  SarifResult addRelatedLocationToResult(SarifResult Result, 
-                                         FullSourceLoc Loc, PresumedLoc PLoc);
-                                  
-  llvm::SmallVector<CharSourceRange> getSarifLocation(FullSourceLoc Loc, 
PresumedLoc PLoc,
-                                                      
ArrayRef<CharSourceRange> Ranges);
+  SarifResult addRelatedLocationToResult(SarifResult Result, FullSourceLoc Loc,
+                                         PresumedLoc PLoc);
+
+  llvm::SmallVector<CharSourceRange>
+  getSarifLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+                   ArrayRef<CharSourceRange> Ranges);
 
   SarifRule addDiagnosticLevelToRule(SarifRule Rule,
                                      DiagnosticsEngine::Level Level);
 
   llvm::StringRef emitFilename(StringRef Filename, const SourceManager &SM);
-  
-  llvm::SmallVector<std::pair<FullSourceLoc, PresumedLoc>> 
RelatedLocationsCache;
+
+  llvm::SmallVector<std::pair<FullSourceLoc, PresumedLoc>>
+      RelatedLocationsCache;
 };
 
 } // end namespace clang
diff --git a/clang/lib/Frontend/SARIFDiagnostic.cpp 
b/clang/lib/Frontend/SARIFDiagnostic.cpp
index 684238d246026..fd765f0eacbb2 100644
--- a/clang/lib/Frontend/SARIFDiagnostic.cpp
+++ b/clang/lib/Frontend/SARIFDiagnostic.cpp
@@ -58,7 +58,7 @@ void SARIFDiagnostic::emitDiagnosticMessage(
   if (Loc.isValid())
     Result = addLocationToResult(Result, Loc, PLoc, Ranges, *Diag);
 
-  for (auto& [RelLoc, RelPLoc] : RelatedLocationsCache)
+  for (auto &[RelLoc, RelPLoc] : RelatedLocationsCache)
     Result = addRelatedLocationToResult(Result, RelLoc, RelPLoc);
   RelatedLocationsCache.clear();
 
@@ -78,7 +78,7 @@ void SARIFDiagnostic::emitIncludeLocation(FullSourceLoc Loc, 
PresumedLoc PLoc) {
   RelatedLocationsCache.push_back({Loc, PLoc});
 }
 
-void SARIFDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, 
+void SARIFDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
                                          StringRef ModuleName) {
   RelatedLocationsCache.push_back({Loc, PLoc});
 }
@@ -90,14 +90,16 @@ SarifResult SARIFDiagnostic::addLocationToResult(
   return Result.setLocations(Locations);
 }
 
-SarifResult SARIFDiagnostic::addRelatedLocationToResult(
-    SarifResult Result, FullSourceLoc Loc, PresumedLoc PLoc) {
+SarifResult SARIFDiagnostic::addRelatedLocationToResult(SarifResult Result,
+                                                        FullSourceLoc Loc,
+                                                        PresumedLoc PLoc) {
   auto Locations = getSarifLocation(Loc, PLoc, {});
   return Result.setRelatedLocations(Locations);
 }
 
-llvm::SmallVector<CharSourceRange> SARIFDiagnostic::getSarifLocation(
-    FullSourceLoc Loc, PresumedLoc PLoc, ArrayRef<CharSourceRange> Ranges) {
+llvm::SmallVector<CharSourceRange>
+SARIFDiagnostic::getSarifLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+                                  ArrayRef<CharSourceRange> Ranges) {
   SmallVector<CharSourceRange> Locations = {};
 
   if (PLoc.isInvalid()) {
@@ -161,7 +163,7 @@ llvm::SmallVector<CharSourceRange> 
SARIFDiagnostic::getSarifLocation(
   SourceLocation DiagLoc = SM.translateLineCol(FID, PLoc.getLine(), ColNo);
 
   // FIXME(llvm-project/issues/57366): Properly process #line directives.
-  CharSourceRange Range = {SourceRange{DiagLoc, DiagLoc}, /* ITR = */false};
+  CharSourceRange Range = {SourceRange{DiagLoc, DiagLoc}, /* ITR = */ false};
   if (Range.isValid())
     Locations.push_back(std::move(Range));
 

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

Reply via email to