From: Alex Lorenz Date: Mon, 10 Jun 2019 23:32:42 +0000 (+0000) Subject: [Frontend] SetUpDiagnosticLog should handle unowned diagnostic consumer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5414c69f61c330aa24248fa914c8e6b8777ec00b;p=clang [Frontend] SetUpDiagnosticLog should handle unowned diagnostic consumer in the compiler The function SetUpDiagnosticLog that was called from createDiagnostics didn't handle the case where the diagnostics engine didn't own the diagnostics consumer. This is a potential problem for a clang tool, in particular some of the follow-up patches for clang-scan-deps will need this fix. Differential Revision: https://reviews.llvm.org/D63101 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@363009 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 9c70a70ed7..fd33b85b31 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -232,9 +232,13 @@ static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, std::move(StreamOwner)); if (CodeGenOpts) Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); - assert(Diags.ownsClient()); - Diags.setClient( - new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); + if (Diags.ownsClient()) { + Diags.setClient( + new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); + } else { + Diags.setClient( + new ChainedDiagnosticConsumer(Diags.getClient(), std::move(Logger))); + } } static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, diff --git a/unittests/Frontend/CompilerInstanceTest.cpp b/unittests/Frontend/CompilerInstanceTest.cpp index 1c3803289b..3ef13d32ca 100644 --- a/unittests/Frontend/CompilerInstanceTest.cpp +++ b/unittests/Frontend/CompilerInstanceTest.cpp @@ -8,6 +8,7 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/ToolOutputFile.h" @@ -70,4 +71,21 @@ TEST(CompilerInstance, DefaultVFSOverlayFromInvocation) { ASSERT_TRUE(Instance.getFileManager().getFile("vfs-virtual.file")); } +TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) { + auto DiagOpts = new DiagnosticOptions(); + DiagOpts->DiagnosticLogFile = "log.diags"; + + // Create the diagnostic engine with unowned consumer. + std::string DiagnosticOutput; + llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput); + auto DiagPrinter = llvm::make_unique( + DiagnosticsOS, new DiagnosticOptions()); + CompilerInstance Instance; + IntrusiveRefCntPtr Diags = Instance.createDiagnostics( + DiagOpts, DiagPrinter.get(), /*ShouldOwnClient=*/false); + + Diags->Report(diag::err_expected) << "no crash"; + ASSERT_EQ(DiagnosticsOS.str(), "error: expected no crash\n"); +} + } // anonymous namespace