https://github.com/anonymouspc updated https://github.com/llvm/llvm-project/pull/170415
>From 49adc295407650f1da1b70ffb1c596907564e0b4 Mon Sep 17 00:00:00 2001 From: anonymouspc <[email protected]> Date: Wed, 3 Dec 2025 11:27:53 +0800 Subject: [PATCH] [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 | 14 +++++ .../include/clang/Frontend/SARIFDiagnostic.h | 10 ++++ clang/lib/Basic/Sarif.cpp | 8 +++ clang/lib/Frontend/SARIFDiagnostic.cpp | 54 ++++++++++++++----- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Basic/Sarif.h b/clang/include/clang/Basic/Sarif.h index a88d1ee2965a9..b4f3610cc7568 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,19 @@ 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..7a6f27eb3b9fa 100644 --- a/clang/include/clang/Frontend/SARIFDiagnostic.h +++ b/clang/include/clang/Frontend/SARIFDiagnostic.h @@ -63,10 +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); + 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..fd765f0eacbb2 100644 --- a/clang/lib/Frontend/SARIFDiagnostic.cpp +++ b/clang/lib/Frontend/SARIFDiagnostic.cpp @@ -58,12 +58,48 @@ 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 +111,7 @@ SarifResult SARIFDiagnostic::addLocationToResult( // FIXME(llvm-project/issues/57366): File-only locations } } - return Result; + return {}; } FileID CaretFileID = Loc.getExpansionLoc().getFileID(); @@ -127,10 +163,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 +244,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) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
