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 | 4d10b40ea8ee489c7b9194aa2b025df4ecd2ab01 (patch) | |
tree | 7adfd8cc2aa293a71835909050723cd420c73933 /lib/Lex/Lexer.cpp | |
parent | 3185d4ac30378995ef70421e2848f77524c2b5d5 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167801 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/Lexer.cpp')
-rw-r--r-- | lib/Lex/Lexer.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index e6e7ca5ee1..7983a6b3e8 100644 --- a/lib/Lex/Lexer.cpp +++ b/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); } |