[clang-format] fix crash involving invalid preprocessor line

Summary:
This (invalid) fragment is crashing clang-format:
```
#if 1
int x;
#elif
int y;
#endif
```

The reason being that the parser expects a token after `#elif`, and the
subsequent parsing of the next line does not check if `CurrentToken` is null.

Reviewers: gribozavr

Reviewed By: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65940

llvm-svn: 368280
This commit is contained in:
Krasimir Georgiev 2019-08-08 11:56:18 +00:00
parent 0de33de813
commit 9ab051bdda
2 changed files with 11 additions and 0 deletions

View File

@ -1099,6 +1099,8 @@ private:
public: public:
LineType parseLine() { LineType parseLine() {
if (!CurrentToken)
return LT_Invalid;
NonTemplateLess.clear(); NonTemplateLess.clear();
if (CurrentToken->is(tok::hash)) if (CurrentToken->is(tok::hash))
return parsePreprocessorDirective(); return parsePreprocessorDirective();

View File

@ -3087,6 +3087,15 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) {
"#endif\n" "#endif\n"
"#endif\n", "#endif\n",
Style); Style);
// Don't crash if there is an #elif directive without a condition.
verifyFormat("#if 1\n"
"int x;\n"
"#elif\n"
"int y;\n"
"#else\n"
"int z;\n"
"#endif",
Style);
// FIXME: This doesn't handle the case where there's code between the // FIXME: This doesn't handle the case where there's code between the
// #ifndef and #define but all other conditions hold. This is because when // #ifndef and #define but all other conditions hold. This is because when
// the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the // the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the