summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/Preprocessor.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-05-09 18:09:42 +0000
committerNico Weber <nicolasweber@gmx.de>2014-05-09 18:09:42 +0000
commit5f5b94141c9e6c8086a2fac6d04377a2f91658a1 (patch)
tree7e9e142f588d522b4855a5bbd1bc351d3b66143d /clang/lib/Lex/Preprocessor.cpp
parent7005e347a25aafdb3740741068f2805fbde53d49 (diff)
downloadbcm5719-llvm-5f5b94141c9e6c8086a2fac6d04377a2f91658a1.tar.gz
bcm5719-llvm-5f5b94141c9e6c8086a2fac6d04377a2f91658a1.zip
Don't leak MacroArgs when using code completion, PR19688.
MacroArgs are owned by TokenLexer, and when a TokenLexer is destroyed, it'll call its MacroArgs's destroy() method. destroy() only appends the MacroArg to Preprocessor's MacroArgCache list, and Preprocessor's destructor then calls deallocate() on all MacroArgs in that list. This method then ends up freeing the MacroArgs's memory. In a code completion context, Parser::cutOffParsing() gets called when a code completion token is hit, which changes the type of the current token to tok::eof. eof tokens aren't always ConsumeToken()ed, so Preprocessor::HandleEndOfFile() isn't always called, and that function is responsible for popping the macro stack. Due to this, Preprocessor::CurTokenLexer can be non-NULL when ~Preprocessor runs. It's a unique_ptr, so it ended up being destructed after ~Preprocessor completed, and its MacroArgs thus got added to the freelist after the code freeing things on the freelist had already completed. The fix is to explicitly call reset() before the freelist processing happens. (See the bug for more notes.) llvm-svn: 208438
Diffstat (limited to 'clang/lib/Lex/Preprocessor.cpp')
-rw-r--r--clang/lib/Lex/Preprocessor.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 56eabf41ffe..d263e7d2a09 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -143,14 +143,17 @@ Preprocessor::~Preprocessor() {
I->MI.Destroy();
// Free any cached macro expanders.
+ // This populates MacroArgCache, so all TokenLexers need to be destroyed
+ // before the code below that frees up the MacroArgCache list.
for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
delete TokenLexerCache[i];
+ CurTokenLexer.reset();
for (DeserializedMacroInfoChain *I = DeserialMIChainHead ; I ; I = I->Next)
I->MI.Destroy();
// Free any cached MacroArgs.
- for (MacroArgs *ArgList = MacroArgCache; ArgList; )
+ for (MacroArgs *ArgList = MacroArgCache; ArgList;)
ArgList = ArgList->deallocate();
// Release pragma information.
OpenPOWER on IntegriCloud