Fix PR2086.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47551 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Lex/Preprocessor.cpp b/Lex/Preprocessor.cpp
index 7bd359a..dbff1ec 100644
--- a/Lex/Preprocessor.cpp
+++ b/Lex/Preprocessor.cpp
@@ -2422,14 +2422,16 @@
// Check to see if this is the last token on the #if[n]def line.
CheckEndOfDirective(isIfndef ? "#ifndef" : "#ifdef");
-
- // If the start of a top-level #ifdef, inform MIOpt.
- if (!ReadAnyTokensBeforeDirective &&
- CurLexer->getConditionalStackDepth() == 0) {
- assert(isIfndef && "#ifdef shouldn't reach here");
- CurLexer->MIOpt.EnterTopLevelIFNDEF(MacroNameTok.getIdentifierInfo());
+
+ if (CurLexer->getConditionalStackDepth() == 0) {
+ // If the start of a top-level #ifdef, inform MIOpt.
+ if (!ReadAnyTokensBeforeDirective) {
+ assert(isIfndef && "#ifdef shouldn't reach here");
+ CurLexer->MIOpt.EnterTopLevelIFNDEF(MacroNameTok.getIdentifierInfo());
+ } else
+ CurLexer->MIOpt.EnterTopLevelConditional();
}
-
+
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
MacroInfo *MI = getMacroInfo(MII);
@@ -2482,9 +2484,12 @@
if (ConditionalTrue) {
// If this condition is equivalent to #ifndef X, and if this is the first
// directive seen, handle it for the multiple-include optimization.
- if (!ReadAnyTokensBeforeDirective &&
- CurLexer->getConditionalStackDepth() == 0 && IfNDefMacro)
- CurLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro);
+ if (CurLexer->getConditionalStackDepth() == 0) {
+ if (!ReadAnyTokensBeforeDirective && IfNDefMacro)
+ CurLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro);
+ else
+ CurLexer->MIOpt.EnterTopLevelConditional();
+ }
// Yes, remember that we are inside a conditional, then lex the next token.
CurLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
@@ -2512,7 +2517,7 @@
// If this the end of a top-level #endif, inform MIOpt.
if (CurLexer->getConditionalStackDepth() == 0)
- CurLexer->MIOpt.ExitTopLevelConditional();
+ CurLexer->MIOpt.EnterTopLevelConditional();
assert(!CondInfo.WasSkipping && !CurLexer->LexingRawMode &&
"This code should only be reachable in the non-skipping case!");
@@ -2531,7 +2536,7 @@
// If this is a top-level #else, inform the MIOpt.
if (CurLexer->getConditionalStackDepth() == 0)
- CurLexer->MIOpt.FoundTopLevelElse();
+ CurLexer->MIOpt.EnterTopLevelConditional();
// If this is a #else with a #else before it, report the error.
if (CI.FoundElse) Diag(Result, diag::pp_err_else_after_else);
@@ -2556,7 +2561,7 @@
// If this is a top-level #elif, inform the MIOpt.
if (CurLexer->getConditionalStackDepth() == 0)
- CurLexer->MIOpt.FoundTopLevelElse();
+ CurLexer->MIOpt.EnterTopLevelConditional();
// If this is a #elif with a #else before it, report the error.
if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index 08bb259..94d4677 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -93,11 +93,11 @@
TheMacro = M;
}
- /// FoundTopLevelElse - This is invoked when an #else/#elif directive is found
- /// in the top level conditional in the file.
- void FoundTopLevelElse() {
- /// If a #else directive is found at the top level, there is a chunk of the
- /// file not guarded by the controlling macro.
+ /// EnterTopLevelConditional - This is invoked when a top level conditional
+ /// (except #ifndef) is found.
+ void EnterTopLevelConditional() {
+ /// If a conditional directive (except #ifndef) is found at the top level,
+ /// there is a chunk of the file not guarded by the controlling macro.
Invalidate();
}
diff --git a/test/Preprocessor/pr2086.c b/test/Preprocessor/pr2086.c
new file mode 100644
index 0000000..ddf2c16
--- /dev/null
+++ b/test/Preprocessor/pr2086.c
@@ -0,0 +1,11 @@
+// RUN: clang -E %s
+
+#define test
+#include "pr2086.h"
+#define test
+#include "pr2086.h"
+
+#ifdef test
+#error
+#endif
+
diff --git a/test/Preprocessor/pr2086.h b/test/Preprocessor/pr2086.h
new file mode 100644
index 0000000..b98b996
--- /dev/null
+++ b/test/Preprocessor/pr2086.h
@@ -0,0 +1,6 @@
+#ifndef test
+#endif
+
+#ifdef test
+#undef test
+#endif