Author: Akash Manna
Date: 2026-08-30T01:41:35+08:00
New Revision: e1a4ef535a07fbd41827f53708b71efc6ad20a68

URL: 
https://github.com/llvm/llvm-project/commit/e1a4ef535a07fbd41827f53708b71efc6ad20a68
DIFF: 
https://github.com/llvm/llvm-project/commit/e1a4ef535a07fbd41827f53708b71efc6ad20a68.diff

LOG: [clang][Parse] Stop parsing declarator chunks after a parenthesized 
structured binding (#219270)

Fixes #218144
Fixes #193687

`ParseDirectDeclarator` stops right after a structured binding like `[a,
b]`, since nothing can follow it — but that check only covers the
unparenthesized form. For `([a, b])`, the binding gets parsed inside
`ParseParenDeclarator`, and the outer `ParseDirectDeclarator` doesn't
notice — it carries on into its suffix loop and parses a trailing `()`
as a function declarator. `([a, b])() {}` then looks like a function
definition, so `ActOnStartOfFunctionDef` gets handed a
`DecompositionDecl` where it expects a `FunctionDecl`:
`cast<FunctionDecl>` asserts, or segfaults later without assertions —
that's #193687. (The `b;` in the report is noise; `([a])() {}` alone
crashes.)

This patch makes `ParseDirectDeclarator` stop as well when the
parenthesized declarator turns out to be a structured binding, so
nothing can follow a binding list, parenthesized or not. The declaration
then takes the normal variable path and hits the diagnostics we already
have — `structured binding declaration cannot be declared with
parentheses`, then `expected expression` for the empty `()` — same as
`[a, b]() {}` today. No Sema changes; the parser just stops building a
declarator that can't exist.

LLM tools were used for this contribution. I've reviewed, built, and
tested the change myself before pushing.

Added: 
    clang/test/Parser/GH218144.cpp

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/Parse/ParseDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 7f198050c92b8..bdbabf2cd98d0 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -503,6 +503,10 @@ features cannot lower the translation-unit ABI level;
   parsed where a nested-name-specifier could appear (e.g. ``int decltype = 
0;``).
   Clang now diagnoses the error instead of asserting. (#GH211207)
 
+- Fixed an assertion failure when a parenthesized structured binding declarator
+  was followed by a function declarator and body (e.g. ``([a, b])() {}``).
+  (#GH218144, #GH193687)
+
 - Fixed a crash when computing the implicit deletion of a defaulted comparison
   operator required an access check that ran while an enclosing declaration
   was still being parsed. (#GH210692)

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 2bbc76fc7c4df..11ba2b81baacc 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -6862,6 +6862,11 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
     // Example: 'char (*X)'   or 'int (*XX)(void)'
     ParseParenDeclarator(D);
 
+    // As above, a structured binding declarator cannot be followed by any
+    // declarator chunks.
+    if (D.isDecompositionDeclarator())
+      return;
+
     // If the declarator was parenthesized, we entered the declarator
     // scope when parsing the parenthesized declarator, then exited
     // the scope already. Re-enter the scope, if we need to.

diff  --git a/clang/test/Parser/GH218144.cpp b/clang/test/Parser/GH218144.cpp
new file mode 100644
index 0000000000000..d915047ad52ea
--- /dev/null
+++ b/clang/test/Parser/GH218144.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++26 -fsyntax-only -verify %s
+
+b;([c,ac])(){}
+// expected-error@-1 2 {{a type specifier is required for all declarations}}
+// expected-error@-2 {{structured binding declaration cannot be declared with 
parentheses}}
+// expected-error@-3 {{expected expression}}
+// expected-error@-4 {{expected ';' after top level declarator}}
+
+([d])(){d}
+// expected-error@-1 {{a type specifier is required for all declarations}}
+// expected-error@-2 {{structured binding declaration cannot be declared with 
parentheses}}
+// expected-error@-3 {{expected expression}}
+// expected-error@-4 {{expected ';' after top level declarator}}
+
+auto ([a])() {}
+// expected-error@-1 {{structured binding declaration cannot be declared with 
parentheses}}
+// expected-error@-2 {{expected expression}}
+// expected-error@-3 {{expected ';' after top level declarator}}
+
+auto (([x, y, z]))() {}
+// expected-error@-1 {{structured binding declaration cannot be declared with 
parentheses}}
+// expected-error@-2 {{expected expression}}
+// expected-error@-3 {{expected ';' after top level declarator}}
+
+struct S {
+  ([m, n])() {}
+  // expected-error@-1 {{structured binding declaration not permitted in this 
context}}
+  // expected-error@-2 {{expected ';' at end of declaration list}}
+};


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

Reply via email to