diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-11-13 01:03:15 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-11-13 01:03:15 +0000 |
commit | 4f10a3e9f058bb8fdcfc3799a1939d1391b96de3 (patch) | |
tree | 8e3cdce46ca059f14eba4564188387e61a0113b5 /clang/lib/Lex/Lexer.cpp | |
parent | 36675b75fbeb6578d510db29ade03596b4bc32af (diff) | |
download | bcm5719-llvm-4f10a3e9f058bb8fdcfc3799a1939d1391b96de3.tar.gz bcm5719-llvm-4f10a3e9f058bb8fdcfc3799a1939d1391b96de3.zip |
[preprocessor] When #including something that contributes no tokens at all,
don't recursively continue lexing.
This avoids a stack overflow with a sequence of many empty #includes.
rdar://11988695
llvm-svn: 167801
Diffstat (limited to 'clang/lib/Lex/Lexer.cpp')
-rw-r--r-- | clang/lib/Lex/Lexer.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index e6e7ca5ee17..7983a6b3e86 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -2595,8 +2595,14 @@ LexNextToken: // Read the PP instance variable into an automatic variable, because // LexEndOfFile will often delete 'this'. Preprocessor *PPCache = PP; + bool EnableIncludedEOFCache = EnableIncludedEOF; if (LexEndOfFile(Result, CurPtr-1)) // Retreat back into the file. return; // Got a token to return. + + if (EnableIncludedEOFCache) { + Result.setKind(tok::included_eof); + return; + } assert(PPCache && "Raw buffer::LexEndOfFile should return a token"); return PPCache->Lex(Result); } @@ -3234,5 +3240,21 @@ HandleDirective: } goto LexNextToken; // GCC isn't tail call eliminating. } + + if (PreprocessorLexer *PPLex = PP->getCurrentLexer()) { + // If we #include something that contributes no tokens at all, return with + // a tok::included_eof instead of recursively continuing lexing. + // This avoids a stack overflow with a sequence of many empty #includes. + PPLex->setEnableIncludedEOF(true); + PP->Lex(Result); + if (Result.isNot(tok::included_eof)) { + if (Result.isNot(tok::eof) && Result.isNot(tok::eod)) + PPLex->setEnableIncludedEOF(false); + return; + } + if (PP->isCurrentLexer(this)) + goto LexNextToken; + } + return PP->Lex(Result); } |