[clang-format] Fix an assertion failure in block parsing

This assertion failure was introduced in 9ed2e68c9a and is
manifested when both RemoveBracesLLVM and MacroBlockBegin are set.

Fixes #59335.

Differential Revision: https://reviews.llvm.org/D139281
This commit is contained in:
Owen Pan
2022-12-04 13:52:01 -08:00
parent 1b1df15538
commit 15f121e853
4 changed files with 19 additions and 9 deletions

View File

@@ -1785,12 +1785,6 @@ struct AdditionalKeywords {
kw_input, kw_output, kw_sequence)));
}
/// Whether the token begins a block.
bool isBlockBegin(const FormatToken &Tok, const FormatStyle &Style) const {
return Tok.is(TT_MacroBlockBegin) ||
(Style.isVerilog() ? isVerilogBegin(Tok) : Tok.is(tok::l_brace));
}
private:
/// The JavaScript keywords beyond the C++ keyword set.
std::unordered_set<IdentifierInfo *> JsExtraKeywords;

View File

@@ -2739,6 +2739,14 @@ bool UnwrappedLineParser::handleCppAttributes() {
return false;
}
/// Returns whether \c Tok begins a block.
bool UnwrappedLineParser::isBlockBegin(const FormatToken &Tok) const {
// FIXME: rename the function or make
// Tok.isOneOf(tok::l_brace, TT_MacroBlockBegin) work.
return Style.isVerilog() ? Keywords.isVerilogBegin(Tok)
: Tok.is(tok::l_brace);
}
FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
bool KeepBraces) {
assert(FormatTok->is(tok::kw_if) && "'if' expected");
@@ -2764,7 +2772,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
FormatToken *IfLeftBrace = nullptr;
IfStmtKind IfBlockKind = IfStmtKind::NotIf;
if (Keywords.isBlockBegin(*FormatTok, Style)) {
if (isBlockBegin(*FormatTok)) {
FormatTok->setFinalizedType(TT_ControlStatementLBrace);
IfLeftBrace = FormatTok;
CompoundStatementIndenter Indenter(this, Style, Line->Level);
@@ -2796,7 +2804,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
}
nextToken();
handleAttributes();
if (Keywords.isBlockBegin(*FormatTok, Style)) {
if (isBlockBegin(*FormatTok)) {
const bool FollowedByIf = Tokens->peekNextToken()->is(tok::kw_if);
FormatTok->setFinalizedType(TT_ElseLBrace);
ElseLeftBrace = FormatTok;
@@ -3063,7 +3071,7 @@ void UnwrappedLineParser::parseNew() {
void UnwrappedLineParser::parseLoopBody(bool KeepBraces, bool WrapRightBrace) {
keepAncestorBraces();
if (Keywords.isBlockBegin(*FormatTok, Style)) {
if (isBlockBegin(*FormatTok)) {
if (!KeepBraces)
FormatTok->setFinalizedType(TT_ControlStatementLBrace);
FormatToken *LeftBrace = FormatTok;

View File

@@ -143,6 +143,7 @@ private:
void parseUnbracedBody(bool CheckEOF = false);
void handleAttributes();
bool handleCppAttributes();
bool isBlockBegin(const FormatToken &Tok) const;
FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
void parseTryCatch();
void parseLoopBody(bool KeepBraces, bool WrapRightBrace);

View File

@@ -6602,6 +6602,13 @@ TEST_F(FormatTest, FormatBeginBlockEndMacros) {
" x = 1;\n"
"FOO_END(Baz)",
Style);
Style.RemoveBracesLLVM = true;
verifyNoCrash("for (;;)\n"
" FOO_BEGIN\n"
" foo();\n"
" FOO_END",
Style);
}
//===----------------------------------------------------------------------===//