From: Chris Lattner Date: Sun, 22 Jul 2007 01:16:55 +0000 (+0000) Subject: Fix a really subtle bug in the macro expander caching code, where X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c683062752a26014197df1c8792a19efa9e93cf;p=clang Fix a really subtle bug in the macro expander caching code, where redefinition of a macro could cause invalid memory to be deleted. Found preprocessing 253.perlbmk. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40380 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Lex/MacroExpander.cpp b/Lex/MacroExpander.cpp index fade854657..57bdfccc11 100644 --- a/Lex/MacroExpander.cpp +++ b/Lex/MacroExpander.cpp @@ -245,6 +245,7 @@ void MacroExpander::Init(Token &Tok, MacroArgs *Actuals) { AtStartOfLine = Tok.isAtStartOfLine(); HasLeadingSpace = Tok.hasLeadingSpace(); MacroTokens = &*Macro->tokens_begin(); + OwnsMacroTokens = false; NumMacroTokens = Macro->tokens_end()-Macro->tokens_begin(); // If this is a function-like macro, expand the arguments and change @@ -270,6 +271,7 @@ void MacroExpander::Init(const Token *TokArray, unsigned NumToks) { Macro = 0; ActualArgs = 0; MacroTokens = TokArray; + OwnsMacroTokens = false; NumMacroTokens = NumToks; CurToken = 0; InstantiateLoc = SourceLocation(); @@ -288,8 +290,10 @@ void MacroExpander::Init(const Token *TokArray, unsigned NumToks) { void MacroExpander::destroy() { // If this was a function-like macro that actually uses its arguments, delete // the expanded tokens. - if (Macro && MacroTokens != &*Macro->tokens_begin()) + if (OwnsMacroTokens) { delete [] MacroTokens; + MacroTokens = 0; + } // MacroExpander owns its formal arguments. if (ActualArgs) ActualArgs->destroy(); @@ -455,6 +459,7 @@ void MacroExpander::ExpandFunctionArguments() { if (NumMacroTokens) memcpy(Res, &ResultToks[0], NumMacroTokens*sizeof(Token)); MacroTokens = Res; + OwnsMacroTokens = true; } } diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index ff84ac7c23..bb772fa182 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -191,7 +191,7 @@ 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = ""; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = ""; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; }; - 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = ""; }; DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = ""; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = ""; }; diff --git a/include/clang/Lex/MacroExpander.h b/include/clang/Lex/MacroExpander.h index acc9fc6238..b0027bbb96 100644 --- a/include/clang/Lex/MacroExpander.h +++ b/include/clang/Lex/MacroExpander.h @@ -134,7 +134,12 @@ class MacroExpander { /// Lexical information about the expansion point of the macro: the identifier /// that the macro expanded from had these properties. - bool AtStartOfLine, HasLeadingSpace; + bool AtStartOfLine : 1; + bool HasLeadingSpace : 1; + + /// OwnsMacroTokens - This is true if this macroexpander allocated the + /// MacroTokens array, and thus needs to free it when destroyed. + bool OwnsMacroTokens : 1; MacroExpander(const MacroExpander&); // DO NOT IMPLEMENT void operator=(const MacroExpander&); // DO NOT IMPLEMENT @@ -142,7 +147,7 @@ public: /// Create a macro expander for the specified macro with the specified actual /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. MacroExpander(Token &Tok, MacroArgs *ActualArgs, Preprocessor &pp) - : Macro(0), ActualArgs(0), PP(pp) { + : Macro(0), ActualArgs(0), PP(pp), OwnsMacroTokens(false) { Init(Tok, ActualArgs); } @@ -154,7 +159,7 @@ public: /// Create a macro expander for the specified token stream. This does not /// take ownership of the specified token vector. MacroExpander(const Token *TokArray, unsigned NumToks, Preprocessor &pp) - : Macro(0), ActualArgs(0), PP(pp) { + : Macro(0), ActualArgs(0), PP(pp), OwnsMacroTokens(false) { Init(TokArray, NumToks); }