https://github.com/mygitljf updated https://github.com/llvm/llvm-project/pull/199098
>From 08edf9e90a4d4e6c812a8b52c43ee58dc8c4591a Mon Sep 17 00:00:00 2001 From: mygitljf <[email protected]> Date: Thu, 21 May 2026 19:31:48 +0000 Subject: [PATCH 1/2] [clang-format] Fix a crash on unbalanced `?` inside nested braces When `parseConditional` searches for the `:` of a ternary expression, it would unconditionally feed every token to `consumeToken`. On malformed input where a `}` reaches the ternary parser before any `:`, `consumeToken`'s `tok::r_brace` branch pops a `Scopes` frame owned by an enclosing `parseBrace`, leaving `Scopes` inconsistent with the actual brace nesting and tripping `assert(!Scopes.empty())` at the top of `parseBrace`'s loop on the next iteration. Bail out of `parseConditional` on an unbalanced `}` so the closing brace propagates up to the enclosing `parseBrace`, which pops the matching frame through its normal path. This mirrors the existing defensive check in `parseAngle` (TokenAnnotator.cpp:247). Fixes #199017 --- clang/lib/Format/TokenAnnotator.cpp | 5 +++++ clang/unittests/Format/FormatTest.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 43e4f6796b6dd..c3a65fd9eedb5 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1297,6 +1297,11 @@ class AnnotatingParser { next(); return true; } + // Avoid consuming an unbalanced `}` here: it would pop a Scopes frame + // owned by an enclosing parseBrace and trip its `!Scopes.empty()` + // assertion. See Issue #199017. + if (CurrentToken->is(tok::r_brace)) + return false; if (!consumeToken()) return false; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 83e2c5b38ceaf..41b5605ef1b9e 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14383,6 +14383,8 @@ TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { "};"); verifyNoCrash("decltype( {\n" " {"); + // Issue #199017 + verifyNoCrash("{{ < ? } a} b"); } TEST_F(FormatTest, IncorrectUnbalancedBracesInMacrosWithUnicode) { >From 5004f7091171238c9cb35c1c4920f49574e29942 Mon Sep 17 00:00:00 2001 From: mygitljf <[email protected]> Date: Sat, 23 May 2026 12:03:54 +0000 Subject: [PATCH 2/2] modify comments and move the position of verifyNoCrash --- clang/lib/Format/TokenAnnotator.cpp | 6 +++--- clang/unittests/Format/FormatTest.cpp | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c3a65fd9eedb5..00b3fc0ad7eaa 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1297,9 +1297,9 @@ class AnnotatingParser { next(); return true; } - // Avoid consuming an unbalanced `}` here: it would pop a Scopes frame - // owned by an enclosing parseBrace and trip its `!Scopes.empty()` - // assertion. See Issue #199017. + // A `}` here would be consumed by consumeToken's r_brace branch + // and pop a Scopes frame owned by the enclosing parseBrace, leaving + // the Scopes stack out of sync with the actual brace nesting. if (CurrentToken->is(tok::r_brace)) return false; if (!consumeToken()) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 41b5605ef1b9e..11d649af53359 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14383,8 +14383,6 @@ TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { "};"); verifyNoCrash("decltype( {\n" " {"); - // Issue #199017 - verifyNoCrash("{{ < ? } a} b"); } TEST_F(FormatTest, IncorrectUnbalancedBracesInMacrosWithUnicode) { @@ -22510,6 +22508,7 @@ TEST_F(FormatTest, DoNotCrashOnInvalidInput) { verifyNoCrash(" tst %o5 ! are we doing the gray case?\n" "LY52: ! [internal]"); verifyNoCrash("operator foo *;"); + verifyNoCrash("{{ < ? } a} b"); } TEST_F(FormatTest, FormatsTableGenCode) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
