diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2019-05-08 15:57:46 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2019-05-21 08:58:15 +0000 |
commit | c12b012bb7465299490cf93c2ae90499a5c417d5 (patch) | |
tree | cee38ab622df44c9f864c5585981aa9e55ffa3bf /lib | |
parent | a59b84774f7c0b92f93a274d4f342c032b7ebda3 (diff) |
[backported/clang-9][Preamble] Stop circular inclusion of main file when building preamblerelease_80-based
--------------------------------------------------------------------------
https://reviews.llvm.org/D53866
--------------------------------------------------------------------------
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.
Fixes: QTCREATORBUG-20883
Change-Id: I02644ddb507db4033dd5c69920c8e10500f0121c
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/SourceManager.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 12 |
2 files changed, 13 insertions, 1 deletions
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 |