summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-02-12 08:03:27 +0000
committerChris Lattner <sabre@nondot.org>2010-02-12 08:03:27 +0000
commitaa1cccbbef2bc52457666334bee0ea264b330295 (patch)
treef82bd50f08e54f7f0b5e6d824a0667df71b69112
parent0e4df63bd5544cb48f07028b3d0cc5e3155dfdee (diff)
downloadbcm5719-llvm-aa1cccbbef2bc52457666334bee0ea264b330295.tar.gz
bcm5719-llvm-aa1cccbbef2bc52457666334bee0ea264b330295.zip
Fix PR6282: the include guard optimization cannot happen if the
guard macro is already defined for the first occurrence of the header. If it is, the body will be skipped and not be properly analyzed for the include guard optimization. llvm-svn: 95972
-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