vsapsai created this revision. vsapsai added reviewers: akyrtzi, doug.gregor. Herald added subscribers: kbarton, nemanjai.
This fixes PR32732 by updating CurLexerKind to reflect available lexers. We were hitting null pointer in Preprocessor::Lex because CurLexerKind was CLK_Lexer but CurLexer was null. And we set it to null in Preprocessor::HandleEndOfFile when exiting a file with code completion point. To reproduce the crash it is important for a comment to be inside a class specifier. In this case in Parser::ParseClassSpecifier we improve error recovery by pushing a semicolon token back into the preprocessor and later on try to lex a token because we haven't reached the end of file. Also clang crashes only on code completion in included file, i.e. when IncludeMacroStack is not empty. Though we reset CurLexer even if include stack is empty. The difference is that during pushing back a semicolon token, preprocessor calls EnterCachingLexMode which decides it is already in caching mode because various lexers are null and IncludeMacroStack is not empty. As the result, CurLexerKind remains CLK_Lexer instead of updating to CLK_CachingLexer. rdar://problem/34787685 https://reviews.llvm.org/D41688 Files: clang/lib/Lex/PPCaching.cpp clang/lib/Lex/PPLexerChange.cpp clang/test/CodeCompletion/Inputs/comments.h clang/test/CodeCompletion/comments.cpp Index: clang/test/CodeCompletion/comments.cpp =================================================================== --- /dev/null +++ clang/test/CodeCompletion/comments.cpp @@ -0,0 +1,13 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +#include "comments.h" + +struct A { + // <- code completion + /* <- code completion */ +}; + +// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%s:7:6 %s +// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%s:8:6 %s +// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%S/Inputs/comments.h:3:6 %s Index: clang/test/CodeCompletion/Inputs/comments.h =================================================================== --- /dev/null +++ clang/test/CodeCompletion/Inputs/comments.h @@ -0,0 +1,4 @@ +// PR32732 +struct B { + // <- code completion +}; Index: clang/lib/Lex/PPLexerChange.cpp =================================================================== --- clang/lib/Lex/PPLexerChange.cpp +++ clang/lib/Lex/PPLexerChange.cpp @@ -444,6 +444,7 @@ } CurPPLexer = nullptr; + recomputeCurLexerKind(); return true; } Index: clang/lib/Lex/PPCaching.cpp =================================================================== --- clang/lib/Lex/PPCaching.cpp +++ clang/lib/Lex/PPCaching.cpp @@ -105,8 +105,10 @@ } void Preprocessor::EnterCachingLexMode() { - if (InCachingLexMode()) + if (InCachingLexMode()) { + assert(CurLexerKind == CLK_CachingLexer && "Unexpected lexer kind"); return; + } PushIncludeMacroStack(); CurLexerKind = CLK_CachingLexer;
Index: clang/test/CodeCompletion/comments.cpp =================================================================== --- /dev/null +++ clang/test/CodeCompletion/comments.cpp @@ -0,0 +1,13 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +#include "comments.h" + +struct A { + // <- code completion + /* <- code completion */ +}; + +// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%s:7:6 %s +// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%s:8:6 %s +// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%S/Inputs/comments.h:3:6 %s Index: clang/test/CodeCompletion/Inputs/comments.h =================================================================== --- /dev/null +++ clang/test/CodeCompletion/Inputs/comments.h @@ -0,0 +1,4 @@ +// PR32732 +struct B { + // <- code completion +}; Index: clang/lib/Lex/PPLexerChange.cpp =================================================================== --- clang/lib/Lex/PPLexerChange.cpp +++ clang/lib/Lex/PPLexerChange.cpp @@ -444,6 +444,7 @@ } CurPPLexer = nullptr; + recomputeCurLexerKind(); return true; } Index: clang/lib/Lex/PPCaching.cpp =================================================================== --- clang/lib/Lex/PPCaching.cpp +++ clang/lib/Lex/PPCaching.cpp @@ -105,8 +105,10 @@ } void Preprocessor::EnterCachingLexMode() { - if (InCachingLexMode()) + if (InCachingLexMode()) { + assert(CurLexerKind == CLK_CachingLexer && "Unexpected lexer kind"); return; + } PushIncludeMacroStack(); CurLexerKind = CLK_CachingLexer;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits