summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2019-02-20 17:13:14 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2019-03-07 12:56:01 +0000
commitdba0adcfe0fec308a047cca79b1be0b1436f6fad (patch)
treecd086e0eba2b36b88d2146e4a90ceab61a52f4f3
parentd1408d8177f7553097d1efd9d62c75868340266b (diff)
[backported/clang-9][libclang] Fix CXTranslationUnit_KeepGoingrelease_70-based
-------------------------------------------------------------------------- https://reviews.llvm.org/D58501 -------------------------------------------------------------------------- Since commit 56f548bbbb7e4387a69708f70724d00e9e076153 [modules] Round-trip -Werror flag through explicit module build. the behavior of CXTranslationUnit_KeepGoing changed: Unresolved #includes are fatal errors again. As a consequence, some templates are not instantiated and lead to confusing errors. Revert to the old behavior: With CXTranslationUnit_KeepGoing fatal errors are mapped to errors. Subscribers: arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58501 Fixes: QTCREATORBUG-21892 Change-Id: I6b5c2490922a798fcc9080fa73fa1fdaecf7bddd Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
-rw-r--r--include/clang/Basic/Diagnostic.h12
-rw-r--r--lib/Basic/DiagnosticIDs.cpp7
-rw-r--r--test/Index/Inputs/keep-going-template-instantiations.h3
-rw-r--r--test/Index/keep-going-template-instantiations.cpp5
-rw-r--r--test/Index/keep-going.cpp4
-rw-r--r--tools/libclang/CIndex.cpp2
-rw-r--r--unittests/Basic/DiagnosticTest.cpp12
7 files changed, 30 insertions, 15 deletions
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 89ccb3e0e2..255e921920 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -207,8 +207,8 @@ private:
// Used by __extension__
unsigned char AllExtensionsSilenced = 0;
- // Suppress diagnostics after a fatal error?
- bool SuppressAfterFatalError = true;
+ // Treat fatal errors like errors.
+ bool FatalsAsError = false;
// Suppress all diagnostics.
bool SuppressAllDiagnostics = false;
@@ -617,9 +617,11 @@ public:
void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; }
bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; }
- /// When set to true (the default), suppress further diagnostics after
- /// a fatal error.
- void setSuppressAfterFatalError(bool Val) { SuppressAfterFatalError = Val; }
+ /// \brief When set to true, any fatal error reported is made an error.
+ ///
+ /// This setting takes precedence over the setErrorsAsFatal setting above.
+ void setFatalsAsError(bool Val) { FatalsAsError = Val; }
+ bool getFatalsAsError() const { return FatalsAsError; }
/// When set to true mask warnings that come from system headers.
void setSuppressSystemWarnings(bool Val) {
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index c50da06d3b..93d13849ba 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -485,6 +485,11 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
return diag::Severity::Ignored;
}
+ // If explicitly requested, map fatal errors to errors.
+ if (Result == diag::Severity::Fatal &&
+ Diag.CurDiagID != diag::fatal_too_many_errors && Diag.FatalsAsError)
+ Result = diag::Severity::Error;
+
// Custom diagnostics always are emitted in system headers.
bool ShowInSystemHeader =
!GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
@@ -664,7 +669,7 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
// If a fatal error has already been emitted, silence all subsequent
// diagnostics.
- if (Diag.FatalErrorOccurred && Diag.SuppressAfterFatalError) {
+ if (Diag.FatalErrorOccurred) {
if (DiagLevel >= DiagnosticIDs::Error &&
Diag.Client->IncludeInDiagnosticCounts()) {
++Diag.NumErrors;
diff --git a/test/Index/Inputs/keep-going-template-instantiations.h b/test/Index/Inputs/keep-going-template-instantiations.h
new file mode 100644
index 0000000000..042918b1f8
--- /dev/null
+++ b/test/Index/Inputs/keep-going-template-instantiations.h
@@ -0,0 +1,3 @@
+template<typename T, T v> struct c {};
+using d = c<bool, false>;
+struct foo : public d {};
diff --git a/test/Index/keep-going-template-instantiations.cpp b/test/Index/keep-going-template-instantiations.cpp
new file mode 100644
index 0000000000..7deef2120e
--- /dev/null
+++ b/test/Index/keep-going-template-instantiations.cpp
@@ -0,0 +1,5 @@
+#include "missing.h"
+#include <keep-going-template-instantiations.h>
+
+// RUN: env CINDEXTEST_KEEP_GOING=1 c-index-test -test-load-source none -I%S/Inputs %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: expected class name
diff --git a/test/Index/keep-going.cpp b/test/Index/keep-going.cpp
index dbfcad32d3..82987c6cf1 100644
--- a/test/Index/keep-going.cpp
+++ b/test/Index/keep-going.cpp
@@ -25,5 +25,5 @@ class C : public A<float> { };
// CHECK: C++ base class specifier=A<float>:4:7 [access=public isVirtual=false] [type=A<float>] [typekind=Unexposed] [templateargs/1= [type=float] [typekind=Float]] [canonicaltype=A<float>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=float] [typekind=Float]] [isPOD=0] [nbFields=1]
// CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
-// CHECK-DIAG: keep-going.cpp:1:10: fatal error: 'missing1.h' file not found
-// CHECK-DIAG: keep-going.cpp:8:10: fatal error: 'missing2.h' file not found
+// CHECK-DIAG: keep-going.cpp:1:10: error: 'missing1.h' file not found
+// CHECK-DIAG: keep-going.cpp:8:10: error: 'missing2.h' file not found
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 4b508ad22f..33c074632f 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -3397,7 +3397,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
if (options & CXTranslationUnit_KeepGoing)
- Diags->setSuppressAfterFatalError(false);
+ Diags->setFatalsAsError(true);
if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
Diags->setSuppressNonErrorsFromIncludedFiles(true);
diff --git a/unittests/Basic/DiagnosticTest.cpp b/unittests/Basic/DiagnosticTest.cpp
index 3068e1c340..42555097a6 100644
--- a/unittests/Basic/DiagnosticTest.cpp
+++ b/unittests/Basic/DiagnosticTest.cpp
@@ -47,13 +47,13 @@ TEST(DiagnosticTest, suppressAndTrap) {
EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred());
}
-// Check that SuppressAfterFatalError works as intended
-TEST(DiagnosticTest, suppressAfterFatalError) {
- for (unsigned Suppress = 0; Suppress != 2; ++Suppress) {
+// Check that FatalsAsError works as intended
+TEST(DiagnosticTest, fatalsAsError) {
+ for (unsigned FatalsAsError = 0; FatalsAsError != 2; ++FatalsAsError) {
DiagnosticsEngine Diags(new DiagnosticIDs(),
new DiagnosticOptions,
new IgnoringDiagConsumer());
- Diags.setSuppressAfterFatalError(Suppress);
+ Diags.setFatalsAsError(FatalsAsError);
// Diag that would set UnrecoverableErrorOccurred and ErrorOccurred.
Diags.Report(diag::err_cannot_open_file) << "file" << "error";
@@ -63,13 +63,13 @@ TEST(DiagnosticTest, suppressAfterFatalError) {
Diags.Report(diag::warn_mt_message) << "warning";
EXPECT_TRUE(Diags.hasErrorOccurred());
- EXPECT_TRUE(Diags.hasFatalErrorOccurred());
+ EXPECT_EQ(Diags.hasFatalErrorOccurred(), FatalsAsError ? 0u : 1u);
EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());
// The warning should be emitted and counted only if we're not suppressing
// after fatal errors.
- EXPECT_EQ(Diags.getNumWarnings(), Suppress ? 0u : 1u);
+ EXPECT_EQ(Diags.getNumWarnings(), FatalsAsError);
}
}