Skip to content

Commit 3c28a2d

Browse files
committed
[Preamble] Stop circular inclusion of main file when building preamble
If a header file was processed for the second time, we could end up with a wrong conditional stack and skipped ranges: In the particular example, if the header guard is evaluated the second time and it is decided to skip the conditional block, the corresponding "#endif" is never seen since the preamble does not include it and we end up in the Tok.is(tok::eof) case with a wrong conditional stack. Detect the circular inclusion, emit a diagnostic and stop processing the inclusion. llvm-svn: 360418
1 parent a2ab528 commit 3c28a2d

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ def note_pp_framework_without_header : Note<
426426
"did not find header '%0' in framework '%1' (loaded from '%2')">;
427427
def err_pp_error_opening_file : Error<
428428
"error opening file '%0': %1">, DefaultFatal;
429+
def err_pp_including_mainfile_in_preamble : Error<
430+
"main file cannot be included recursively when building a preamble">;
429431
def err_pp_empty_filename : Error<"empty filename">;
430432
def err_pp_include_too_deep : Error<"#include nested too deeply">;
431433
def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;

clang/lib/Basic/SourceManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1582,7 +1582,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
15821582
if (MainSLoc.isFile()) {
15831583
const ContentCache *MainContentCache
15841584
= MainSLoc.getFile().getContentCache();
1585-
if (!MainContentCache) {
1585+
if (!MainContentCache || !MainContentCache->OrigEntry) {
15861586
// Can't do anything
15871587
} else if (MainContentCache->OrigEntry == SourceFile) {
15881588
FirstFID = MainFileID;

clang/lib/Lex/PPDirectives.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,18 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
18711871
return {ImportAction::None};
18721872
}
18731873

1874+
// Check for circular inclusion of the main file.
1875+
// We can't generate a consistent preamble with regard to the conditional
1876+
// stack if the main file is included again as due to the preamble bounds
1877+
// some directives (e.g. #endif of a header guard) will never be seen.
1878+
// Since this will lead to confusing errors, avoid the inclusion.
1879+
if (File && PreambleConditionalStack.isRecording() &&
1880+
SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) {
1881+
Diag(FilenameTok.getLocation(),
1882+
diag::err_pp_including_mainfile_in_preamble);
1883+
return {ImportAction::None};
1884+
}
1885+
18741886
// Should we enter the source file? Set to Skip if either the source file is
18751887
// known to have no effect beyond its effect on module visibility -- that is,
18761888
// if it's got an include guard that is already defined, set to Import if it

0 commit comments

Comments
 (0)