diff options
-rw-r--r-- | include/clang/Basic/DiagnosticLexKinds.td | 2 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 12 | ||||
-rw-r--r-- | test/Index/preamble-cyclic-include.cpp | 9 |
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 |