https://github.com/mygitljf created 
https://github.com/llvm/llvm-project/pull/199103

## Summary
`clang-format` aborts on triple-bracket input like `[[[a]]` with
`Assertion 'Left.isNot(tok::l_square)' failed.` This patch fixes the
crash by rejecting the C++ attribute classification when the candidate
`[[` is itself preceded by another `[`.

## Problem
`isCppAttribute` only inspects the tokens *following* `[[`. For
malformed input `[[[a]]` it returns `true` on the **middle** `[` (its
`Next`/`Next->Next` look like a valid `[[ident...]]` sequence), so that
token gets `TT_AttributeLSquare` while the outer `[` stays as a raw
`tok::l_square`. This breaks the invariant guarded by
`assert(Left.isNot(tok::l_square))` in `canBreakBefore`
(`TokenAnotator.cpp:6660`) and aborts the process.

## Solution
Add one defensive check to `isCppAttribute` that mirrors the existing
ObjC-array-literal exclusion: bail out when `Tok.Previous` is another
`[`. Legal C++ never has `[[[` in any context, so this is a strict
refinement with no behavioural impact on well-formed code.

## Testing
- `[[[a]]`, `[[[a]]]`, `[[ [a] ]]` no longer crash; output is preserved
  as-is.
- `[[nodiscard]] int foo();` and other legal C++11/17 attributes format
  identically to before.
- Regression cases added to `FormatTest.DoNotCrashOnInvalidInput`.
- All 1264 `FormatTests` gtest pass.
- All 33 `clang/test/Format/` lit tests pass.
- `ninja check-clang-format` passes end-to-end.

>From 70d1648e9d5a973acd5e710f485764be63d80038 Mon Sep 17 00:00:00 2001
From: mygitljf <[email protected]>
Date: Thu, 21 May 2026 19:53:27 +0000
Subject: [PATCH] [clang-format] Fix a crash on triple-bracket input like
 `[[[a]]`

`isCppAttribute` only checks the tokens following `[[`, so for malformed
input `[[[a]]` it returns true on the *middle* `[`: that token's
`Next`/`Next->Next` look like a valid `[[ident...]]` sequence. The middle
`[` is then annotated as `TT_AttributeLSquare` while the outer `[` stays
as a raw `tok::l_square`, which violates the invariant guarded by
`assert(Left.isNot(tok::l_square))` in `canBreakBefore` and aborts the
process.

Reject the C++ attribute classification when the candidate `[[` is
itself preceded by another `[`. Legal C++ never has `[[[` in any
context, so this is a strict refinement that mirrors the existing
defensive check that excludes ObjC `@[...]` array literals.

Fixes #199010
---
 clang/lib/Format/TokenAnnotator.cpp   | 6 ++++++
 clang/unittests/Format/FormatTest.cpp | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 43e4f6796b6dd..63b4f65418a93 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -90,6 +90,12 @@ static bool isCppAttribute(bool IsCpp, const FormatToken 
&Tok) {
   // The first square bracket is part of an ObjC array literal
   if (Tok.Previous && Tok.Previous->is(tok::at))
     return false;
+  // A C++ attribute specifier '[[...]]' never appears directly inside another
+  // '['. Treating malformed input like '[[[a]]' as one would mis-annotate the
+  // inner '[' as TT_AttributeLSquare while leaving the outer '[' as a raw
+  // tok::l_square, tripping an assertion in canBreakBefore.
+  if (Tok.Previous && Tok.Previous->is(tok::l_square))
+    return false;
   const FormatToken *AttrTok = Tok.Next->Next;
   if (!AttrTok)
     return false;
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 83e2c5b38ceaf..6f01492ddce82 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -22508,6 +22508,9 @@ TEST_F(FormatTest, DoNotCrashOnInvalidInput) {
   verifyNoCrash("        tst     %o5     ! are we doing the gray case?\n"
                 "LY52:                   ! [internal]");
   verifyNoCrash("operator foo *;");
+  verifyNoCrash("[[[a]]");
+  verifyNoCrash("[[[a]]]");
+  verifyNoCrash("[[ [a] ]]");
 }
 
 TEST_F(FormatTest, FormatsTableGenCode) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to