]> granicus.if.org Git - clang/commitdiff
[libclang] Fix CXTranslationUnit_KeepGoing
authorIvan Donchevskii <ivan.donchevskii@qt.io>
Thu, 7 Mar 2019 10:13:50 +0000 (10:13 +0000)
committerIvan Donchevskii <ivan.donchevskii@qt.io>
Thu, 7 Mar 2019 10:13:50 +0000 (10:13 +0000)
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.

Patch by Nikolai Kosjar.

Differential Revision: https://reviews.llvm.org/D58501

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355586 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Diagnostic.h
lib/Basic/DiagnosticIDs.cpp
test/Index/Inputs/keep-going-template-instantiations.h [new file with mode: 0644]
test/Index/keep-going-template-instantiations.cpp [new file with mode: 0644]
test/Index/keep-going.cpp
tools/libclang/CIndex.cpp
unittests/Basic/DiagnosticTest.cpp

index 88947b7ed68801bb10663270dfa0906830df613c..2cd68ea1524bfbc641408e4a26e3200c6ed6a590 100644 (file)
@@ -209,8 +209,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;
@@ -614,9 +614,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) {
index a7473d8bb5d41b6d1c82eb0d14a0efc219c7e13f..e8a99d08a9138aac8b0da77011844b98787678fb 100644 (file)
@@ -481,6 +481,11 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
       Result = diag::Severity::Fatal;
   }
 
+  // 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;
@@ -660,7 +665,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 (file)
index 0000000..042918b
--- /dev/null
@@ -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 (file)
index 0000000..7deef21
--- /dev/null
@@ -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
index b3f29c5d3dae0b539f2c42b1240bb47f6046d214..0b2df725a5a73dbe998e10395b702251f54604d7 100644 (file)
@@ -34,5 +34,5 @@ class C : public A<float> { };
 
 // CHECK-KEEP-GOING-ONLY: VarDecl=global_var:1:12 [type=int] [typekind=Int] [isPOD=1]
 
-// 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
index cdcdfc167b2ed5f51236314904e879c5a459b73d..07e052bf0c13e991e01c81f3047c39b984b9ee3a 100644 (file)
@@ -3408,7 +3408,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);
 
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
index 6377e57b3557bbbddb4b86dc3d5075e06b50cb16..ffb750bdaae3430f0a4db41fb7b927fbcceb232c 100644 (file)
@@ -46,13 +46,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";
@@ -62,16 +62,15 @@ 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);
   }
 }
-
 TEST(DiagnosticTest, diagnosticError) {
   DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
                           new IgnoringDiagConsumer());