summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td2
-rw-r--r--lib/Basic/SourceManager.cpp2
-rw-r--r--lib/Lex/PPDirectives.cpp12
-rw-r--r--test/Index/preamble-cyclic-include.cpp9
4 files changed, 24 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 14e306246b..35df2d3826 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -421,6 +421,8 @@ def err_pp_file_not_found_typo_not_fatal
: Error<"'%0' file not found, did you mean '%1'?">;
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 <FILENAME>">;
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index ce8aa5d112..5a6d530054 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -1581,7 +1581,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
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;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index d62a3513c7..b3cc9df60c 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1855,6 +1855,18 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
return;
}
+ // 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;
+ }
+
// Should we enter the source file? Set to false 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 or is a modular header
diff --git a/test/Index/preamble-cyclic-include.cpp b/test/Index/preamble-cyclic-include.cpp
new file mode 100644
index 0000000000..cb057f62d5
--- /dev/null
+++ b/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