[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2020-11-05 Thread Jan Wassenberg via Phabricator via cfe-commits
jan-wassenberg added a comment.

@nik here's an unusual but real-world example that triggers this.
https://github.com/google/highway compiles the same source multiple times (with 
different macros set) for generating code for multiple SIMD instruction sets.
The main source file sets a macro to its filename and includes a 
"foreach_target.h" which includes the file identified by that macro.

I understand this is complicated for analysis, so foreach_target.h does nothing 
if it detects that an IDE/analyzer are parsing. This relies on predefined 
macros such as
__CDT_PARSER__ __INTELLISENSE__ Q_CREATOR_RUN. Is there such a macro for clangd?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-13 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

I guess using `Edit Related Object -> Edit Commits` should do the trick.
I'm not sure what the "Lean Into Action" is either.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-10 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik closed this revision.
nik added a comment.

Huch, I forgot to add "Differential Revision: " to the commit message, so 
I'll close this manually once I know how to add the svn revision number to 
this. https://llvm.org/docs/Phabricator.html states:

> In the web UI, under “Leap Into Action” put the SVN revision number in the 
> Comment, set the Action to “Close Revision” and click Submit.

Where is the "Lean Into Action" thingy? Can't find it.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-10 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik updated this revision to Diff 198997.
nik marked an inline comment as done and an inline comment as not done.
nik added a comment.

Renamed to err_pp_including_mainfile_in_preamble.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866

Files:
  include/clang/Basic/DiagnosticLexKinds.td
  lib/Basic/SourceManager.cpp
  lib/Lex/PPDirectives.cpp
  test/Index/preamble-cyclic-include.cpp


Index: test/Index/preamble-cyclic-include.cpp
===
--- /dev/null
+++ test/Index/preamble-cyclic-include.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test 
-test-annotate-tokens=%s:5:1:10:1 %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: unterminated conditional directive
+// CHECK-NOT: Skipping: [4:1 - 8:7]
+// CHECK: error: main file cannot be included recursively when building a 
preamble
+#ifndef A_H
+#define A_H
+#  include "preamble-cyclic-include.cpp"
+int bar();
+#endif
Index: lib/Lex/PPDirectives.cpp
===
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -1871,6 +1871,18 @@
 return {ImportAction::None};
   }
 
+  // Check for circular inclusion of the main file.
+  // We can't generate a consistent preamble with regard to the conditional
+  // stack if the main file is included again as due to the preamble bounds
+  // some directives (e.g. #endif of a header guard) will never be seen.
+  // Since this will lead to confusing errors, avoid the inclusion.
+  if (File && PreambleConditionalStack.isRecording() &&
+  SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
+Diag(FilenameTok.getLocation(),
+ diag::err_pp_including_mainfile_in_preamble);
+return {ImportAction::None};
+  }
+
   // Should we enter the source file? Set to Skip if either the source file is
   // known to have no effect beyond its effect on module visibility -- that is,
   // if it's got an include guard that is already defined, set to Import if it
Index: lib/Basic/SourceManager.cpp
===
--- lib/Basic/SourceManager.cpp
+++ lib/Basic/SourceManager.cpp
@@ -1582,7 +1582,7 @@
 if (MainSLoc.isFile()) {
   const ContentCache *MainContentCache
 = MainSLoc.getFile().getContentCache();
-  if (!MainContentCache) {
+  if (!MainContentCache || !MainContentCache->OrigEntry) {
 // Can't do anything
   } else if (MainContentCache->OrigEntry == SourceFile) {
 FirstFID = MainFileID;
Index: include/clang/Basic/DiagnosticLexKinds.td
===
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -426,6 +426,8 @@
   "did not find header '%0' in framework '%1' (loaded from '%2')">;
 def err_pp_error_opening_file : Error<
   "error opening file '%0': %1">, DefaultFatal;
+def err_pp_including_mainfile_in_preamble : Error<
+  "main file cannot be included recursively when building a preamble">;
 def err_pp_empty_filename : Error<"empty filename">;
 def err_pp_include_too_deep : Error<"#include nested too deeply">;
 def err_pp_expects_filename : Error<"expected \"FILENAME\" or ">;


Index: test/Index/preamble-cyclic-include.cpp
===
--- /dev/null
+++ test/Index/preamble-cyclic-include.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-annotate-tokens=%s:5:1:10:1 %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: unterminated conditional directive
+// CHECK-NOT: Skipping: [4:1 - 8:7]
+// CHECK: error: main file cannot be included recursively when building a preamble
+#ifndef A_H
+#define A_H
+#  include "preamble-cyclic-include.cpp"
+int bar();
+#endif
Index: lib/Lex/PPDirectives.cpp
===
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -1871,6 +1871,18 @@
 return {ImportAction::None};
   }
 
+  // Check for circular inclusion of the main file.
+  // We can't generate a consistent preamble with regard to the conditional
+  // stack if the main file is included again as due to the preamble bounds
+  // some directives (e.g. #endif of a header guard) will never be seen.
+  // Since this will lead to confusing errors, avoid the inclusion.
+  if (File && PreambleConditionalStack.isRecording() &&
+  SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
+Diag(FilenameTok.getLocation(),
+ diag::err_pp_including_mainfile_in_preamble);
+return {ImportAction::None};
+  }
+
   // Should we enter the source file? Set to Skip if either the source file is
   // known to have no effect beyond its effect on module visibility -- that is,
   // if it's got an include guard that is already defined, set to Import if it
Index: lib/Basic/SourceManager.cpp

[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-09 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov accepted this revision.
ilya-biryukov marked an inline comment as done.
ilya-biryukov added a comment.
This revision is now accepted and ready to land.

LGTM. See the nit about naming of an error, though




Comment at: include/clang/Basic/DiagnosticLexKinds.td:429
   "error opening file '%0': %1">, DefaultFatal;
+def err_pp_including_mainfile_for_preamble : Error<
+  "main file cannot be included recursively when building a preamble">;

NIT: Maybe change to err_pp_including_mainfile_**in**_preamble?




Comment at: lib/Basic/SourceManager.cpp:1594
 SourceFileName = llvm::sys::path::filename(SourceFile->getName());
-if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) 
{
+if (MainFile && *SourceFileName == 
llvm::sys::path::filename(MainFile->getName())) {
   SourceFileUID = getActualFileUID(SourceFile);

nik wrote:
> ilya-biryukov wrote:
> > nik wrote:
> > > ilya-biryukov wrote:
> > > > Can this actually be`null`? 
> > > The comment for OrigEntry states that it might be null:
> > > 
> > > /// Reference to the file entry representing this ContentCache.
> > > ///
> > > /// This reference does not own the FileEntry object.
> > > ///
> > > /// It is possible for this to be NULL if the ContentCache 
> > > encapsulates
> > > /// an imaginary text buffer.
> > > const FileEntry *OrigEntry;
> > > 
> > > Note also that further down in this function, a null check for 
> > > MainContentCache->OrigEntry is done, so I believe that this was just 
> > > forgotten here (since there is also no assert) and we are the first one 
> > > running into this with the introduced call to 
> > > SourceMgr.translateFile(File).
> > > 
> > > I've tried to understand why we end up with a nullptr here, but this goes 
> > > beyond me in the time I've taken for this. What I've observed is that 
> > > module code path (LibclangReparseTest.ReparseWithModule vs 
> > > LibclangReparseTest.Reparse) creates at least a MemoryBuffer more (in 
> > > ModuleMap::parseModuleMapFile; possibly the one referred with "imaginary 
> > > text buffer" from the comment) and I suspect this to be somehow related 
> > > with the OrigEntry nullptr.
> > Should we check for equality of `MainContentCache->ContentsEntry` in that 
> > case? I guess this is what should be set for "imaginary" files.
> Does not help in this particular case as ContentsEntry is also a nullptr. All 
> the members of the ContentsCache seem to be either nullptr or 0 as that 
> particular point of execution.
> 
> How to continue?
> 
> a) Accept as is.
> b) Ask someone knowledgeable for whom this could be a no-brainer that could 
> respond hopefully soon. Any candidate?
> c) Or should I dig deeper? This can take quite some time as this area is new 
> for me.
> 
Wow, I guess I don't understand this code deep enough.
Your change looks ok, I'm happy to LGTM this. But if you're actually interested 
in digging deeper, that would be super-useful.

Based on what you're describe, it feels like "imaginary" main file works by 
accident rather than being properly handled in this function.

BTW, thanks for moving the check up, it definitely looks nicer this way.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-09 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik marked an inline comment as done.
nik added inline comments.



Comment at: lib/Basic/SourceManager.cpp:1594
 SourceFileName = llvm::sys::path::filename(SourceFile->getName());
-if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) 
{
+if (MainFile && *SourceFileName == 
llvm::sys::path::filename(MainFile->getName())) {
   SourceFileUID = getActualFileUID(SourceFile);

ilya-biryukov wrote:
> nik wrote:
> > ilya-biryukov wrote:
> > > Can this actually be`null`? 
> > The comment for OrigEntry states that it might be null:
> > 
> > /// Reference to the file entry representing this ContentCache.
> > ///
> > /// This reference does not own the FileEntry object.
> > ///
> > /// It is possible for this to be NULL if the ContentCache encapsulates
> > /// an imaginary text buffer.
> > const FileEntry *OrigEntry;
> > 
> > Note also that further down in this function, a null check for 
> > MainContentCache->OrigEntry is done, so I believe that this was just 
> > forgotten here (since there is also no assert) and we are the first one 
> > running into this with the introduced call to SourceMgr.translateFile(File).
> > 
> > I've tried to understand why we end up with a nullptr here, but this goes 
> > beyond me in the time I've taken for this. What I've observed is that 
> > module code path (LibclangReparseTest.ReparseWithModule vs 
> > LibclangReparseTest.Reparse) creates at least a MemoryBuffer more (in 
> > ModuleMap::parseModuleMapFile; possibly the one referred with "imaginary 
> > text buffer" from the comment) and I suspect this to be somehow related 
> > with the OrigEntry nullptr.
> Should we check for equality of `MainContentCache->ContentsEntry` in that 
> case? I guess this is what should be set for "imaginary" files.
Does not help in this particular case as ContentsEntry is also a nullptr. All 
the members of the ContentsCache seem to be either nullptr or 0 as that 
particular point of execution.

How to continue?

a) Accept as is.
b) Ask someone knowledgeable for whom this could be a no-brainer that could 
respond hopefully soon. Any candidate?
c) Or should I dig deeper? This can take quite some time as this area is new 
for me.



Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-09 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added inline comments.



Comment at: lib/Basic/SourceManager.cpp:1594
 SourceFileName = llvm::sys::path::filename(SourceFile->getName());
-if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) 
{
+if (MainFile && *SourceFileName == 
llvm::sys::path::filename(MainFile->getName())) {
   SourceFileUID = getActualFileUID(SourceFile);

nik wrote:
> ilya-biryukov wrote:
> > Can this actually be`null`? 
> The comment for OrigEntry states that it might be null:
> 
> /// Reference to the file entry representing this ContentCache.
> ///
> /// This reference does not own the FileEntry object.
> ///
> /// It is possible for this to be NULL if the ContentCache encapsulates
> /// an imaginary text buffer.
> const FileEntry *OrigEntry;
> 
> Note also that further down in this function, a null check for 
> MainContentCache->OrigEntry is done, so I believe that this was just 
> forgotten here (since there is also no assert) and we are the first one 
> running into this with the introduced call to SourceMgr.translateFile(File).
> 
> I've tried to understand why we end up with a nullptr here, but this goes 
> beyond me in the time I've taken for this. What I've observed is that module 
> code path (LibclangReparseTest.ReparseWithModule vs 
> LibclangReparseTest.Reparse) creates at least a MemoryBuffer more (in 
> ModuleMap::parseModuleMapFile; possibly the one referred with "imaginary text 
> buffer" from the comment) and I suspect this to be somehow related with the 
> OrigEntry nullptr.
Should we check for equality of `MainContentCache->ContentsEntry` in that case? 
I guess this is what should be set for "imaginary" files.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-09 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik updated this revision to Diff 198799.
nik added a comment.

Moved the MainFile / MainContentCache->OrigEntry check a bit further up, for
consistency with the same test further down in SourceManager::translateFile().


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866

Files:
  include/clang/Basic/DiagnosticLexKinds.td
  lib/Basic/SourceManager.cpp
  lib/Lex/PPDirectives.cpp
  test/Index/preamble-cyclic-include.cpp


Index: test/Index/preamble-cyclic-include.cpp
===
--- /dev/null
+++ test/Index/preamble-cyclic-include.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test 
-test-annotate-tokens=%s:5:1:10:1 %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: unterminated conditional directive
+// CHECK-NOT: Skipping: [4:1 - 8:7]
+// CHECK: error: main file cannot be included recursively when building a 
preamble
+#ifndef A_H
+#define A_H
+#  include "preamble-cyclic-include.cpp"
+int bar();
+#endif
Index: lib/Lex/PPDirectives.cpp
===
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -1871,6 +1871,18 @@
 return {ImportAction::None};
   }
 
+  // Check for circular inclusion of the main file.
+  // We can't generate a consistent preamble with regard to the conditional
+  // stack if the main file is included again as due to the preamble bounds
+  // some directives (e.g. #endif of a header guard) will never be seen.
+  // Since this will lead to confusing errors, avoid the inclusion.
+  if (File && PreambleConditionalStack.isRecording() &&
+  SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
+Diag(FilenameTok.getLocation(),
+ diag::err_pp_including_mainfile_for_preamble);
+return {ImportAction::None};
+  }
+
   // Should we enter the source file? Set to Skip if either the source file is
   // known to have no effect beyond its effect on module visibility -- that is,
   // if it's got an include guard that is already defined, set to Import if it
Index: lib/Basic/SourceManager.cpp
===
--- lib/Basic/SourceManager.cpp
+++ lib/Basic/SourceManager.cpp
@@ -1582,7 +1582,7 @@
 if (MainSLoc.isFile()) {
   const ContentCache *MainContentCache
 = MainSLoc.getFile().getContentCache();
-  if (!MainContentCache) {
+  if (!MainContentCache || !MainContentCache->OrigEntry) {
 // Can't do anything
   } else if (MainContentCache->OrigEntry == SourceFile) {
 FirstFID = MainFileID;
Index: include/clang/Basic/DiagnosticLexKinds.td
===
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -426,6 +426,8 @@
   "did not find header '%0' in framework '%1' (loaded from '%2')">;
 def err_pp_error_opening_file : Error<
   "error opening file '%0': %1">, DefaultFatal;
+def err_pp_including_mainfile_for_preamble : Error<
+  "main file cannot be included recursively when building a preamble">;
 def err_pp_empty_filename : Error<"empty filename">;
 def err_pp_include_too_deep : Error<"#include nested too deeply">;
 def err_pp_expects_filename : Error<"expected \"FILENAME\" or ">;


Index: test/Index/preamble-cyclic-include.cpp
===
--- /dev/null
+++ test/Index/preamble-cyclic-include.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-annotate-tokens=%s:5:1:10:1 %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: unterminated conditional directive
+// CHECK-NOT: Skipping: [4:1 - 8:7]
+// CHECK: error: main file cannot be included recursively when building a preamble
+#ifndef A_H
+#define A_H
+#  include "preamble-cyclic-include.cpp"
+int bar();
+#endif
Index: lib/Lex/PPDirectives.cpp
===
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -1871,6 +1871,18 @@
 return {ImportAction::None};
   }
 
+  // Check for circular inclusion of the main file.
+  // We can't generate a consistent preamble with regard to the conditional
+  // stack if the main file is included again as due to the preamble bounds
+  // some directives (e.g. #endif of a header guard) will never be seen.
+  // Since this will lead to confusing errors, avoid the inclusion.
+  if (File && PreambleConditionalStack.isRecording() &&
+  SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
+Diag(FilenameTok.getLocation(),
+ diag::err_pp_including_mainfile_for_preamble);
+return {ImportAction::None};
+  }
+
   // Should we enter the source file? Set to Skip if either the source file is
   // known to have no effect beyond its effect on module visibility -- that is,
   // if it's got an include guard that is already defined, set to Import if it

[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-09 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik marked an inline comment as done.
nik added inline comments.



Comment at: lib/Basic/SourceManager.cpp:1594
 SourceFileName = llvm::sys::path::filename(SourceFile->getName());
-if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) 
{
+if (MainFile && *SourceFileName == 
llvm::sys::path::filename(MainFile->getName())) {
   SourceFileUID = getActualFileUID(SourceFile);

ilya-biryukov wrote:
> Can this actually be`null`? 
The comment for OrigEntry states that it might be null:

/// Reference to the file entry representing this ContentCache.
///
/// This reference does not own the FileEntry object.
///
/// It is possible for this to be NULL if the ContentCache encapsulates
/// an imaginary text buffer.
const FileEntry *OrigEntry;

Note also that further down in this function, a null check for 
MainContentCache->OrigEntry is done, so I believe that this was just forgotten 
here (since there is also no assert) and we are the first one running into this 
with the introduced call to SourceMgr.translateFile(File).

I've tried to understand why we end up with a nullptr here, but this goes 
beyond me in the time I've taken for this. What I've observed is that module 
code path (LibclangReparseTest.ReparseWithModule vs 
LibclangReparseTest.Reparse) creates at least a MemoryBuffer more (in 
ModuleMap::parseModuleMapFile; possibly the one referred with "imaginary text 
buffer" from the comment) and I suspect this to be somehow related with the 
OrigEntry nullptr.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-08 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

Sorry for losing this.
Neat change, minimal and focused, thanks!

Just wanted to clarify why we need the change in `SourceManager.cpp`, will LGTM 
as soon as we resolve this




Comment at: lib/Basic/SourceManager.cpp:1594
 SourceFileName = llvm::sys::path::filename(SourceFile->getName());
-if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) 
{
+if (MainFile && *SourceFileName == 
llvm::sys::path::filename(MainFile->getName())) {
   SourceFileUID = getActualFileUID(SourceFile);

Can this actually be`null`? 


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-05-08 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik updated this revision to Diff 198654.
nik edited the summary of this revision.
nik added a comment.

Rebased for current trunk.

If I miss something obvious, please tell me. Otherwise I'm waiting.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866

Files:
  include/clang/Basic/DiagnosticLexKinds.td
  lib/Basic/SourceManager.cpp
  lib/Lex/PPDirectives.cpp
  test/Index/preamble-cyclic-include.cpp


Index: test/Index/preamble-cyclic-include.cpp
===
--- /dev/null
+++ test/Index/preamble-cyclic-include.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test 
-test-annotate-tokens=%s:5:1:10:1 %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: unterminated conditional directive
+// CHECK-NOT: Skipping: [4:1 - 8:7]
+// CHECK: error: main file cannot be included recursively when building a 
preamble
+#ifndef A_H
+#define A_H
+#  include "preamble-cyclic-include.cpp"
+int bar();
+#endif
Index: lib/Lex/PPDirectives.cpp
===
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -1871,6 +1871,18 @@
 return {ImportAction::None};
   }
 
+  // Check for circular inclusion of the main file.
+  // We can't generate a consistent preamble with regard to the conditional
+  // stack if the main file is included again as due to the preamble bounds
+  // some directives (e.g. #endif of a header guard) will never be seen.
+  // Since this will lead to confusing errors, avoid the inclusion.
+  if (File && PreambleConditionalStack.isRecording() &&
+  SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
+Diag(FilenameTok.getLocation(),
+ diag::err_pp_including_mainfile_for_preamble);
+return {ImportAction::None};
+  }
+
   // Should we enter the source file? Set to Skip if either the source file is
   // known to have no effect beyond its effect on module visibility -- that is,
   // if it's got an include guard that is already defined, set to Import if it
Index: lib/Basic/SourceManager.cpp
===
--- lib/Basic/SourceManager.cpp
+++ lib/Basic/SourceManager.cpp
@@ -1591,7 +1591,7 @@
 // as the main file.
 const FileEntry *MainFile = MainContentCache->OrigEntry;
 SourceFileName = llvm::sys::path::filename(SourceFile->getName());
-if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) 
{
+if (MainFile && *SourceFileName == 
llvm::sys::path::filename(MainFile->getName())) {
   SourceFileUID = getActualFileUID(SourceFile);
   if (SourceFileUID) {
 if (Optional MainFileUID =
Index: include/clang/Basic/DiagnosticLexKinds.td
===
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -426,6 +426,8 @@
   "did not find header '%0' in framework '%1' (loaded from '%2')">;
 def err_pp_error_opening_file : Error<
   "error opening file '%0': %1">, DefaultFatal;
+def err_pp_including_mainfile_for_preamble : Error<
+  "main file cannot be included recursively when building a preamble">;
 def err_pp_empty_filename : Error<"empty filename">;
 def err_pp_include_too_deep : Error<"#include nested too deeply">;
 def err_pp_expects_filename : Error<"expected \"FILENAME\" or ">;


Index: test/Index/preamble-cyclic-include.cpp
===
--- /dev/null
+++ test/Index/preamble-cyclic-include.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-annotate-tokens=%s:5:1:10:1 %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: unterminated conditional directive
+// CHECK-NOT: Skipping: [4:1 - 8:7]
+// CHECK: error: main file cannot be included recursively when building a preamble
+#ifndef A_H
+#define A_H
+#  include "preamble-cyclic-include.cpp"
+int bar();
+#endif
Index: lib/Lex/PPDirectives.cpp
===
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -1871,6 +1871,18 @@
 return {ImportAction::None};
   }
 
+  // Check for circular inclusion of the main file.
+  // We can't generate a consistent preamble with regard to the conditional
+  // stack if the main file is included again as due to the preamble bounds
+  // some directives (e.g. #endif of a header guard) will never be seen.
+  // Since this will lead to confusing errors, avoid the inclusion.
+  if (File && PreambleConditionalStack.isRecording() &&
+  SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
+Diag(FilenameTok.getLocation(),
+ diag::err_pp_including_mainfile_for_preamble);
+return {ImportAction::None};
+  }
+
   // Should we enter the source file? Set to Skip if either the source file is
   // known to have no effect beyond its 

[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-04-18 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping. Ilya?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-02-21 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53866: [Preamble] Stop circular inclusion of main file when building preamble

2019-02-14 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53866/new/

https://reviews.llvm.org/D53866



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits