summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Lex/PPDirectives.cpp17
-rw-r--r--clang/test/Preprocessor/mi_opt2.c15
-rw-r--r--clang/test/Preprocessor/mi_opt2.h5
3 files changed, 30 insertions, 7 deletions
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index b0e784bcd96..4803c5ab85d 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1514,18 +1514,21 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
// Check to see if this is the last token on the #if[n]def line.
CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef");
+ IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
+ MacroInfo *MI = getMacroInfo(MII);
+
if (CurPPLexer->getConditionalStackDepth() == 0) {
- // If the start of a top-level #ifdef, inform MIOpt.
- if (!ReadAnyTokensBeforeDirective) {
+ // If the start of a top-level #ifdef and if the macro is not defined,
+ // inform MIOpt that this might be the start of a proper include guard.
+ // Otherwise it is some other form of unknown conditional which we can't
+ // handle.
+ if (!ReadAnyTokensBeforeDirective && MI == 0) {
assert(isIfndef && "#ifdef shouldn't reach here");
- CurPPLexer->MIOpt.EnterTopLevelIFNDEF(MacroNameTok.getIdentifierInfo());
+ CurPPLexer->MIOpt.EnterTopLevelIFNDEF(MII);
} else
CurPPLexer->MIOpt.EnterTopLevelConditional();
}
- IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
- MacroInfo *MI = getMacroInfo(MII);
-
// If there is a macro, process it.
if (MI) // Mark it used.
MI->setIsUsed(true);
@@ -1558,7 +1561,7 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
// If this condition is equivalent to #ifndef X, and if this is the first
// directive seen, handle it for the multiple-include optimization.
if (CurPPLexer->getConditionalStackDepth() == 0) {
- if (!ReadAnyTokensBeforeDirective && IfNDefMacro)
+ if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
CurPPLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro);
else
CurPPLexer->MIOpt.EnterTopLevelConditional();
diff --git a/clang/test/Preprocessor/mi_opt2.c b/clang/test/Preprocessor/mi_opt2.c
new file mode 100644
index 00000000000..198d19fdb7a
--- /dev/null
+++ b/clang/test/Preprocessor/mi_opt2.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -E %s | FileCheck %s
+// PR6282
+// This test should not trigger the include guard optimization since
+// the guard macro is defined on the first include.
+
+#define ITERATING 1
+#define X 1
+#include "mi_opt2.h"
+#undef X
+#define X 2
+#include "mi_opt2.h"
+
+// CHECK: b: 1
+// CHECK: b: 2
+
diff --git a/clang/test/Preprocessor/mi_opt2.h b/clang/test/Preprocessor/mi_opt2.h
new file mode 100644
index 00000000000..df37eba8187
--- /dev/null
+++ b/clang/test/Preprocessor/mi_opt2.h
@@ -0,0 +1,5 @@
+#ifndef ITERATING
+a: X
+#else
+b: X
+#endif
OpenPOWER on IntegriCloud