forked from OSchip/llvm-project
[clang] Fix serialized diagnostics edge-cases
The Clang frontend sometimes fails on the following assertion when launched with `-serialize-diagnostic-file <x>`: ``` Assertion failed: (BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance"), function ~BitstreamWriter, file BitstreamWriter.h, line 125. ``` This was first noticed when passing an unknown command-line argument to `-cc1`. It turns out the `DiagnosticConsumer::finish()` function should be called as soon as processing of all source files ends, but there are some code paths where that doesn't happen: 1. when command line parsing fails in `cc1_main()`, 2. when `!Act.PrepareToExecute(*this)` or `!createTarget()` evaluate to `true` in `CompilerInstance::ExecuteAction` and the function returns early. This patch ensures `finish()` is called in all those code paths. Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D118150
This commit is contained in:
parent
600c6714ac
commit
76cb4cd074
|
@ -37,6 +37,7 @@
|
|||
#include "clang/Serialization/ASTReader.h"
|
||||
#include "clang/Serialization/GlobalModuleIndex.h"
|
||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Support/BuryPointer.h"
|
||||
#include "llvm/Support/CrashRecoveryContext.h"
|
||||
|
@ -996,6 +997,11 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
|
|||
// DesiredStackSpace available.
|
||||
noteBottomOfStack();
|
||||
|
||||
auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {
|
||||
// Notify the diagnostic client that all files were processed.
|
||||
getDiagnosticClient().finish();
|
||||
});
|
||||
|
||||
raw_ostream &OS = getVerboseOutputStream();
|
||||
|
||||
if (!Act.PrepareToExecute(*this))
|
||||
|
@ -1034,9 +1040,6 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
|
|||
}
|
||||
}
|
||||
|
||||
// Notify the diagnostic client that all files were processed.
|
||||
getDiagnostics().getClient()->finish();
|
||||
|
||||
if (getDiagnosticOpts().ShowCarets) {
|
||||
// We can have multiple diagnostics sharing one diagnostic client.
|
||||
// Get the total number of warnings/errors from the client.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
// RUN: rm -rf %t && mkdir %t
|
||||
// RUN: not %clang_cc1 -emit-header-module %s -o %t/out.pcm -serialize-diagnostic-file %t/diag 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: header module compilation requires '-fmodules', '-std=c++20', or '-fmodules-ts'
|
|
@ -0,0 +1,4 @@
|
|||
// RUN: rm -rf %t && mkdir %t
|
||||
// RUN: not %clang_cc1 %s -unknown-argument -serialize-diagnostic-file %t/diag -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: unknown argument: '-unknown-argument'
|
|
@ -0,0 +1,4 @@
|
|||
// RUN: rm -rf %t && mkdir %t
|
||||
// RUN: not %clang_cc1 %s -triple blah-unknown-unknown -serialize-diagnostic-file %t/diag -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: unknown target triple 'blah-unknown-unknown', please use -triple or -arch
|
|
@ -237,8 +237,10 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
|
|||
static_cast<void*>(&Clang->getDiagnostics()));
|
||||
|
||||
DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
|
||||
if (!Success)
|
||||
if (!Success) {
|
||||
Clang->getDiagnosticClient().finish();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Execute the frontend actions.
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue