r348641 - [Preprocessor] Don't avoid entering included files after hitting a fatal error.

Volodymyr Sapsai via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 7 12:29:54 PST 2018


Author: vsapsai
Date: Fri Dec  7 12:29:54 2018
New Revision: 348641

URL: http://llvm.org/viewvc/llvm-project?rev=348641&view=rev
Log:
[Preprocessor] Don't avoid entering included files after hitting a fatal error.

Change in r337953 violated the contract for `CXTranslationUnit_KeepGoing`:

> Do not stop processing when fatal errors are encountered.

Use different approach to fix long processing times with multiple inclusion
cycles. Instead of stopping preprocessing for fatal errors, do this after
reaching the max allowed include depth and only for the files that were
processed already. It is likely but not guaranteed those files cause a cycle.

rdar://problem/46108547

Reviewers: erik.pilkington, arphaman

Reviewed By: erik.pilkington

Subscribers: jkorous, dexonsmith, ilya-biryukov, Dmitry.Kozhevnikov

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


Added:
    cfe/trunk/test/Index/Inputs/cycle.h
    cfe/trunk/test/Index/keep-going-include-cycle.c
Modified:
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/test/Index/keep-going.cpp

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=348641&r1=348640&r2=348641&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Dec  7 12:29:54 2018
@@ -319,6 +319,10 @@ class Preprocessor {
   /// This is used when loading a precompiled preamble.
   std::pair<int, bool> SkipMainFilePreamble;
 
+  /// Whether we hit an error due to reaching max allowed include depth. Allows
+  /// to avoid hitting the same error over and over again.
+  bool HasReachedMaxIncludeDepth = false;
+
 public:
   struct PreambleSkipInfo {
     SourceLocation HashTokenLoc;

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=348641&r1=348640&r2=348641&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Dec  7 12:29:54 2018
@@ -1707,6 +1707,7 @@ void Preprocessor::HandleIncludeDirectiv
   // Check that we don't have infinite #include recursion.
   if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
     Diag(FilenameTok, diag::err_pp_include_too_deep);
+    HasReachedMaxIncludeDepth = true;
     return;
   }
 
@@ -1855,10 +1856,11 @@ void Preprocessor::HandleIncludeDirectiv
   if (PPOpts->SingleFileParseMode)
     ShouldEnter = false;
 
-  // Any diagnostics after the fatal error will not be visible. As the
-  // compilation failed already and errors in subsequently included files won't
-  // be visible, avoid preprocessing those files.
-  if (ShouldEnter && Diags->hasFatalErrorOccurred())
+  // If we've reached the max allowed include depth, it is usually due to an
+  // include cycle. Don't enter already processed files again as it can lead to
+  // reaching the max allowed include depth again.
+  if (ShouldEnter && HasReachedMaxIncludeDepth && File &&
+      HeaderInfo.getFileInfo(File).NumIncludes)
     ShouldEnter = false;
 
   // Determine whether we should try to import the module for this #include, if

Added: cfe/trunk/test/Index/Inputs/cycle.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/cycle.h?rev=348641&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/cycle.h (added)
+++ cfe/trunk/test/Index/Inputs/cycle.h Fri Dec  7 12:29:54 2018
@@ -0,0 +1 @@
+#include "cycle.h"

Added: cfe/trunk/test/Index/keep-going-include-cycle.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/keep-going-include-cycle.c?rev=348641&view=auto
==============================================================================
--- cfe/trunk/test/Index/keep-going-include-cycle.c (added)
+++ cfe/trunk/test/Index/keep-going-include-cycle.c Fri Dec  7 12:29:54 2018
@@ -0,0 +1,10 @@
+#include "cycle.h"
+#include "foo.h"
+
+// RUN: env CINDEXTEST_KEEP_GOING=1 c-index-test -test-print-type -I%S/Inputs %s 2> %t.stderr.txt | FileCheck %s
+// RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt
+
+// Verify that we don't stop preprocessing after an include cycle.
+// CHECK: VarDecl=global_var:1:12 [type=int] [typekind=Int] [isPOD=1]
+
+// CHECK-DIAG: cycle.h:1:10: error: #include nested too deeply

Modified: cfe/trunk/test/Index/keep-going.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/keep-going.cpp?rev=348641&r1=348640&r2=348641&view=diff
==============================================================================
--- cfe/trunk/test/Index/keep-going.cpp (original)
+++ cfe/trunk/test/Index/keep-going.cpp Fri Dec  7 12:29:54 2018
@@ -9,11 +9,18 @@ class B : public A<int> { };
 
 class C : public A<float> { };
 
-// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_KEEP_GOING=1 c-index-test -test-print-type %s -std=c++03 2> %t.stderr.txt  | FileCheck %s
+// Not found includes shouldn't affect subsequent correct includes.
+#include "foo.h"
+
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_KEEP_GOING=1 c-index-test -test-print-type -I%S/Inputs %s -std=c++03 2> %t.stderr.txt  | FileCheck %s
 // RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt
 
+// Verify that even without CINDEXTEST_EDITING we don't stop processing after a fatal error.
+// RUN: env CINDEXTEST_KEEP_GOING=1 c-index-test -test-print-type -I%S/Inputs %s -std=c++03 2> %t.stderr.txt  | FileCheck -check-prefix CHECK-KEEP-GOING-ONLY %s
+
 // CHECK: inclusion directive=missing1.h ((null)) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: inclusion directive=missing2.h ((null)) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: inclusion directive=foo.h ({{.*[/\\]}}test{{[/\\]}}Index{{[/\\]}}Inputs{{[/\\]}}foo.h) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ClassTemplate=A:4:7 (Definition) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: TemplateTypeParameter=T:3:16 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: FieldDecl=a:4:13 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
@@ -25,5 +32,7 @@ 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-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




More information about the cfe-commits mailing list