[clang] [Clang][Diagnose] Minimal support on emit-include-location in sarif mode (PR #170415)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 5 01:43:51 PST 2025
https://github.com/anonymouspc updated https://github.com/llvm/llvm-project/pull/170415
>From 983aa785ee374c9c1dcbee4846dafa3ccc62b793 Mon Sep 17 00:00:00 2001
From: anonymouspc <shyeyian at petalmail.com>
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 <shyeyian at petalmail.com>
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));
More information about the cfe-commits
mailing list