]> granicus.if.org Git - clang/commitdiff
[Frontend] SetUpDiagnosticLog should handle unowned diagnostic consumer
authorAlex Lorenz <arphaman@gmail.com>
Mon, 10 Jun 2019 23:32:42 +0000 (23:32 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Mon, 10 Jun 2019 23:32:42 +0000 (23:32 +0000)
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

lib/Frontend/CompilerInstance.cpp
unittests/Frontend/CompilerInstanceTest.cpp

index 9c70a70ed7e7162316a2ffe8e8e4dff7586ad391..fd33b85b31d3f9cd3a9b0890d2319949bc6da12d 100644 (file)
@@ -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,
index 1c3803289b949487e4051fba4897611550f16a9f..3ef13d32ca45cf7411ceaf8a18e25b8d3e5e07ac 100644 (file)
@@ -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<TextDiagnosticPrinter>(
+      DiagnosticsOS, new DiagnosticOptions());
+  CompilerInstance Instance;
+  IntrusiveRefCntPtr<DiagnosticsEngine> 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