diff options
author | Alexander Kornienko <alexfh@google.com> | 2012-08-29 16:56:24 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2012-08-29 16:56:24 +0000 |
commit | e40c4238a572bf8241a04e0005f70550cbfc1cfb (patch) | |
tree | a8310655aa26021dd16b9b1eb053a3ac8e8bb190 | |
parent | 260e5067f3cca1630c6ed88757a15b23622b52d1 (diff) |
Fixed a problem with #pragma push_macro/pop_macro implementation.
Summary:
The problem was with the following sequence:
#pragma push_macro("long")
#undef long
#pragma pop_macro("long")
in case when "long" didn't represent a macro.
Fixed crash and removed code duplication for #undef/pop_macro case. Added regression tests.
Reviewers: doug.gregor, klimek
Reviewed By: doug.gregor
CC: cfe-commits, chapuni
Differential Revision: http://llvm-reviews.chandlerc.com/D31
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162845 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 2 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 5 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 9 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 9 | ||||
-rw-r--r-- | test/Preprocessor/pragma-pushpop-macro.c | 19 |
5 files changed, 37 insertions, 7 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index fca5796068..adc6b240e9 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -470,6 +470,8 @@ public: /// \brief Specify a macro for this identifier. void setMacroInfo(IdentifierInfo *II, MacroInfo *MI, bool LoadedFromAST = false); + /// \brief Undefine a macro for this identifier. + void clearMacroInfo(IdentifierInfo *II); /// macro_iterator/macro_begin/macro_end - This allows you to walk the macro /// history table. Currently defined macros have diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 6de0e4a9f3..738bed36ba 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -1921,10 +1921,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); MI->setUndefLoc(MacroNameTok.getLocation()); - IdentifierInfo *II = MacroNameTok.getIdentifierInfo(); - II->setHasMacroDefinition(false); - if (II->isFromAST()) - II->setChangedSinceDeserialization(); + clearMacroInfo(MacroNameTok.getIdentifierInfo()); } diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 936b37009c..3f27236cac 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -57,6 +57,15 @@ void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI, II->setChangedSinceDeserialization(); } +/// \brief Undefine a macro for this identifier. +void Preprocessor::clearMacroInfo(IdentifierInfo *II) { + assert(II->hasMacroDefinition() && "Macro is not defined!"); + assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!"); + II->setHasMacroDefinition(false); + if (II->isFromAST()) + II->setChangedSinceDeserialization(); +} + /// RegisterBuiltinMacro - Register the specified identifier in the identifier /// table and mark it as a builtin macro to be expanded. static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index acf5c74556..62ef8bfbcd 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -737,13 +737,18 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { if (MacroInfo *CurrentMI = getMacroInfo(IdentInfo)) { if (CurrentMI->isWarnIfUnused()) WarnUnusedMacroLocs.erase(CurrentMI->getDefinitionLoc()); + CurrentMI->setUndefLoc(MessageLoc); } // Get the MacroInfo we want to reinstall. MacroInfo *MacroToReInstall = iter->second.back(); - // Reinstall the previously pushed macro. - setMacroInfo(IdentInfo, MacroToReInstall); + if (MacroToReInstall) { + // Reinstall the previously pushed macro. + setMacroInfo(IdentInfo, MacroToReInstall); + } else if (IdentInfo->hasMacroDefinition()) { + clearMacroInfo(IdentInfo); + } // Pop PragmaPushMacroInfo stack. iter->second.pop_back(); diff --git a/test/Preprocessor/pragma-pushpop-macro.c b/test/Preprocessor/pragma-pushpop-macro.c index 08a65704e4..0aee074c55 100644 --- a/test/Preprocessor/pragma-pushpop-macro.c +++ b/test/Preprocessor/pragma-pushpop-macro.c @@ -31,6 +31,22 @@ int pmy1 = Y; #define Y 4 int pmy2 = Y; +// The sequence push, define/undef, pop caused problems if macro was not +// previously defined. +#pragma push_macro("PREVIOUSLY_UNDEFINED1") +#undef PREVIOUSLY_UNDEFINED1 +#pragma pop_macro("PREVIOUSLY_UNDEFINED1") +#ifndef PREVIOUSLY_UNDEFINED1 +int Q; +#endif + +#pragma push_macro("PREVIOUSLY_UNDEFINED2") +#define PREVIOUSLY_UNDEFINED2 +#pragma pop_macro("PREVIOUSLY_UNDEFINED2") +#ifndef PREVIOUSLY_UNDEFINED2 +int P; +#endif + // CHECK: int pmx0 = 1 // CHECK: int pmy0 = 2 // CHECK: int pmx1 = 1 @@ -38,4 +54,5 @@ int pmy2 = Y; // CHECK: int pmx3 = 1 // CHECK: int pmy1 = 3 // CHECK: int pmy2 = 4 - +// CHECK: int Q; +// CHECK: int P; |