summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-08-23 19:56:39 +0000
committerHans Wennborg <hans@hanshq.net>2017-08-23 19:56:39 +0000
commite5cdfe0ea82a4f97d01175d67ac1cb6b87d0a56e (patch)
tree6b046baae6c81b76060f4a83a091b2f87e04e58f
parent29cf62cecf5ac6fcad53dcd300c3b5c90dfeea77 (diff)
Merging r311330:
------------------------------------------------------------------------ r311330 | ibiryukov | 2017-08-21 05:03:08 -0700 (Mon, 21 Aug 2017) | 16 lines Fixed a crash on replaying Preamble's PP conditional stack. Summary: The crash occurs when the first token after a preamble is a macro expansion. Fixed by moving replayPreambleConditionalStack from Parser into Preprocessor. It is now called right after the predefines file is processed. Reviewers: erikjv, bkramer, klimek, yvvan Reviewed By: bkramer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D36872 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_50@311591 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Lex/Preprocessor.h8
-rw-r--r--lib/Lex/PPLexerChange.cpp13
-rw-r--r--lib/Lex/Preprocessor.cpp2
-rw-r--r--lib/Parse/Parser.cpp2
-rw-r--r--test/Index/preamble-conditionals-crash.cpp12
-rw-r--r--test/Index/preamble-conditionals.cpp8
6 files changed, 38 insertions, 7 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index a058fbfbb4..dba4b80f60 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1048,10 +1048,6 @@ public:
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
- /// \brief After parser warm-up, initialize the conditional stack from
- /// the preamble.
- void replayPreambleConditionalStack();
-
/// \brief Inform the preprocessor callbacks that processing is complete.
void EndSourceFile();
@@ -2025,6 +2021,10 @@ public:
}
private:
+ /// \brief After processing predefined file, initialize the conditional stack from
+ /// the preamble.
+ void replayPreambleConditionalStack();
+
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
void HandleUndefDirective();
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 5a589d6a17..36d7028da6 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -458,10 +458,16 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs);
}
+ bool ExitedFromPredefinesFile = false;
FileID ExitedFID;
- if (Callbacks && !isEndOfMacro && CurPPLexer)
+ if (!isEndOfMacro && CurPPLexer) {
ExitedFID = CurPPLexer->getFileID();
+ assert(PredefinesFileID.isValid() &&
+ "HandleEndOfFile is called before PredefinesFileId is set");
+ ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);
+ }
+
if (LeavingSubmodule) {
// We're done with this submodule.
Module *M = LeaveSubmodule(/*ForPragma*/false);
@@ -489,6 +495,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
PPCallbacks::ExitFile, FileType, ExitedFID);
}
+ // Restore conditional stack from the preamble right after exiting from the
+ // predefines file.
+ if (ExitedFromPredefinesFile)
+ replayPreambleConditionalStack();
+
// Client should lex another token unless we generated an EOM.
return LeavingSubmodule;
}
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index d1dc8e1c00..7979be773a 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -540,6 +540,8 @@ void Preprocessor::EnterMainSourceFile() {
void Preprocessor::replayPreambleConditionalStack() {
// Restore the conditional stack from the preamble, if there is one.
if (PreambleConditionalStack.isReplaying()) {
+ assert(CurPPLexer &&
+ "CurPPLexer is null when calling replayPreambleConditionalStack.");
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack());
PreambleConditionalStack.doneReplaying();
}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 4aa9a59719..1ed7ef9663 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -516,8 +516,6 @@ void Parser::Initialize() {
// Prime the lexer look-ahead.
ConsumeToken();
-
- PP.replayPreambleConditionalStack();
}
void Parser::LateTemplateParserCleanupCallback(void *P) {
diff --git a/test/Index/preamble-conditionals-crash.cpp b/test/Index/preamble-conditionals-crash.cpp
new file mode 100644
index 0000000000..6b18c87d19
--- /dev/null
+++ b/test/Index/preamble-conditionals-crash.cpp
@@ -0,0 +1,12 @@
+#ifndef HEADER_GUARD
+
+#define FOO int aba;
+FOO
+
+#endif
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 \
+// RUN: local -std=c++14 %s 2>&1 \
+// RUN: | FileCheck %s --implicit-check-not "libclang: crash detected" \
+// RUN: --implicit-check-not "error:"
+// CHECK: macro expansion=FOO:3:9 Extent=[4:1 - 4:4]
+// CHECK: VarDecl=aba:4:1 (Definition) Extent=[4:1 - 4:4]
diff --git a/test/Index/preamble-conditionals.cpp b/test/Index/preamble-conditionals.cpp
new file mode 100644
index 0000000000..81ef8265e8
--- /dev/null
+++ b/test/Index/preamble-conditionals.cpp
@@ -0,0 +1,8 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source local %s 2>&1 \
+// RUN: | FileCheck %s --implicit-check-not "error:"
+#ifndef FOO_H
+#define FOO_H
+
+void foo();
+
+#endif