From: Lauro Ramos Venancio Date: Mon, 25 Feb 2008 19:03:15 +0000 (+0000) Subject: Fix PR2086. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0184cc719f06d2c5da6ae0725847ef875c6128cd;p=clang 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 7bd359ae18..dbff1ec281 100644 --- a/Lex/Preprocessor.cpp +++ b/Lex/Preprocessor.cpp @@ -2422,14 +2422,16 @@ 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"); - - // 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 @@ void Preprocessor::HandleIfDirective(Token &IfToken, 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 @@ void Preprocessor::HandleEndifDirective(Token &EndifToken) { // 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 @@ void Preprocessor::HandleElseDirective(Token &Result) { // 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 @@ void Preprocessor::HandleElifDirective(Token &ElifToken) { // 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 08bb259fda..94d4677f9d 100644 --- a/include/clang/Lex/MultipleIncludeOpt.h +++ b/include/clang/Lex/MultipleIncludeOpt.h @@ -93,11 +93,11 @@ public: 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 0000000000..ddf2c166cd --- /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 0000000000..b98b996d6c --- /dev/null +++ b/test/Preprocessor/pr2086.h @@ -0,0 +1,6 @@ +#ifndef test +#endif + +#ifdef test +#undef test +#endif