aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2012-08-29 16:56:24 +0000
committerAlexander Kornienko <alexfh@google.com>2012-08-29 16:56:24 +0000
commite40c4238a572bf8241a04e0005f70550cbfc1cfb (patch)
treea8310655aa26021dd16b9b1eb053a3ac8e8bb190
parent260e5067f3cca1630c6ed88757a15b23622b52d1 (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.h2
-rw-r--r--lib/Lex/PPDirectives.cpp5
-rw-r--r--lib/Lex/PPMacroExpansion.cpp9
-rw-r--r--lib/Lex/Pragma.cpp9
-rw-r--r--test/Preprocessor/pragma-pushpop-macro.c19
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;