From e3d6b3e537bd5b00a346e3832864a5ccbbcdc720 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 4 Apr 2023 16:21:53 +0100 Subject: [PATCH 1/2] Swift: route compiler diagnostics through our log (cherry picked from commit b8c55612e5e5c6eda3435b40760a87e9bf789c88) --- .../invocation/SwiftDiagnosticsConsumer.cpp | 40 ++++++++++++++++--- .../invocation/SwiftDiagnosticsConsumer.h | 10 +++++ swift/extractor/main.cpp | 2 + 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp b/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp index 9d5aa4654d5..cee6f7caf55 100644 --- a/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp +++ b/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp @@ -1,5 +1,5 @@ #include "swift/extractor/invocation/SwiftDiagnosticsConsumer.h" -#include "swift/extractor/trap/generated/TrapEntries.h" +#include "swift/extractor/trap/generated/TrapClasses.h" #include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/infra/SwiftDiagnosticKind.h" @@ -13,13 +13,17 @@ using namespace codeql; void SwiftDiagnosticsConsumer::handleDiagnostic(swift::SourceManager& sourceManager, const swift::DiagnosticInfo& diagInfo) { - auto message = getDiagMessage(sourceManager, diagInfo); - DiagnosticsTrap diag{}; - diag.id = trap.createTypedLabel(); + if (diagInfo.IsChildNote) return; + Diagnostics diag{trap.createTypedLabel()}; diag.kind = translateDiagnosticsKind(diagInfo.Kind); - diag.text = message; + diag.text = getDiagMessage(sourceManager, diagInfo); trap.emit(diag); locationExtractor.attachLocation(sourceManager, diagInfo, diag.id); + + forwardToLog(sourceManager, diagInfo, diag.text); + for (const auto& child : diagInfo.ChildDiagnosticInfo) { + forwardToLog(sourceManager, *child); + } } std::string SwiftDiagnosticsConsumer::getDiagMessage(swift::SourceManager& sourceManager, @@ -29,3 +33,29 @@ std::string SwiftDiagnosticsConsumer::getDiagMessage(swift::SourceManager& sourc swift::DiagnosticEngine::formatDiagnosticText(out, diagInfo.FormatString, diagInfo.FormatArgs); return text.str().str(); } + +void SwiftDiagnosticsConsumer::forwardToLog(swift::SourceManager& sourceManager, + const swift::DiagnosticInfo& diagInfo, + const std::string& message) { + auto file = sourceManager.getDisplayNameForLoc(diagInfo.Loc); + auto [line, column] = sourceManager.getLineAndColumnInBuffer(diagInfo.Loc); + using Kind = swift::DiagnosticKind; + switch (diagInfo.Kind) { + case Kind::Error: + LOG_ERROR("{}:{}:{} {}", file, line, column, message); + break; + case Kind::Warning: + LOG_WARNING("{}:{}:{} {}", file, line, column, message); + break; + case Kind::Remark: + LOG_INFO("{}:{}:{} {}", file, line, column, message); + break; + case Kind::Note: + LOG_DEBUG("{}:{}:{} {}", file, line, column, message); + break; + default: + LOG_ERROR("unknown diagnostic kind {}, {}:{}:{} {}", diagInfo.Kind, file, line, column, + message); + break; + } +} diff --git a/swift/extractor/invocation/SwiftDiagnosticsConsumer.h b/swift/extractor/invocation/SwiftDiagnosticsConsumer.h index c85233348fd..e2817981f76 100644 --- a/swift/extractor/invocation/SwiftDiagnosticsConsumer.h +++ b/swift/extractor/invocation/SwiftDiagnosticsConsumer.h @@ -2,6 +2,7 @@ #include #include "swift/extractor/infra/SwiftLocationExtractor.h" +#include "swift/logging/SwiftLogging.h" namespace codeql { @@ -17,8 +18,17 @@ class SwiftDiagnosticsConsumer : public swift::DiagnosticConsumer { private: static std::string getDiagMessage(swift::SourceManager& sourceManager, const swift::DiagnosticInfo& diagInfo); + void forwardToLog(swift::SourceManager& sourceManager, + const swift::DiagnosticInfo& diagInfo, + const std::string& message); + + void forwardToLog(swift::SourceManager& sourceManager, const swift::DiagnosticInfo& diagInfo) { + forwardToLog(sourceManager, diagInfo, getDiagMessage(sourceManager, diagInfo)); + } + TrapDomain& trap; SwiftLocationExtractor locationExtractor; + Logger logger{"compiler"}; }; } // namespace codeql diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index 4f1dd990be9..0abb5404035 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -91,6 +91,8 @@ class Observer : public swift::FrontendObserver { } void configuredCompiler(swift::CompilerInstance& instance) override { + // remove default consumers to avoid double messaging + instance.getDiags().takeConsumers(); instance.addDiagnosticConsumer(&diagConsumer); } From 7e05551f1662b7876060ea08644a2c70994a5252 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov Date: Thu, 24 Aug 2023 18:14:34 +0100 Subject: [PATCH 2/2] Swift: Check whether a SourceLoc is valid before using it. --- .../invocation/SwiftDiagnosticsConsumer.cpp | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp b/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp index cee6f7caf55..0cc5959aebc 100644 --- a/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp +++ b/swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp @@ -11,6 +11,24 @@ using namespace codeql; +namespace { +struct DisplayLoc { + llvm::StringRef file; + unsigned line; + unsigned column; + + static DisplayLoc from(swift::SourceManager& sourceManager, swift::SourceLoc loc) { + if (loc.isInvalid()) { + return {"", 0, 0}; + } + auto file = sourceManager.getDisplayNameForLoc(loc); + auto [line, column] = sourceManager.getLineAndColumnInBuffer(loc); + return {file, line, column}; + } +}; + +} // namespace + void SwiftDiagnosticsConsumer::handleDiagnostic(swift::SourceManager& sourceManager, const swift::DiagnosticInfo& diagInfo) { if (diagInfo.IsChildNote) return; @@ -37,8 +55,7 @@ std::string SwiftDiagnosticsConsumer::getDiagMessage(swift::SourceManager& sourc void SwiftDiagnosticsConsumer::forwardToLog(swift::SourceManager& sourceManager, const swift::DiagnosticInfo& diagInfo, const std::string& message) { - auto file = sourceManager.getDisplayNameForLoc(diagInfo.Loc); - auto [line, column] = sourceManager.getLineAndColumnInBuffer(diagInfo.Loc); + auto [file, line, column] = DisplayLoc::from(sourceManager, diagInfo.Loc); using Kind = swift::DiagnosticKind; switch (diagInfo.Kind) { case Kind::Error: