[clang] [clang] Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"` failed (PR #219270)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 27 22:04:13 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/219270.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+4) 
- (modified) clang/lib/Parse/ParseDecl.cpp (+5) 
- (added) clang/test/Parser/GH218144.cpp (+30) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 332e0bfdb3a8b..aaad27bd47408 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -536,6 +536,10 @@ features cannot lower the translation-unit ABI level;
   parameter that follows a parameter pack (e.g.
   `template <typename... T> S::S(T..., int = 10) {}`).  (#GH216211)
 
+- Fixed an assertion failure when a parenthesized structured binding declarator
+  was followed by a function declarator and body (e.g. ``([a, b])() {}``).
+  (#GH218144, #GH193687)
+
 #### Bug Fixes to AST Handling
 
 - Fixed a non-deterministic ordering of unused local typedefs that made
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 at -1 2 {{a type specifier is required for all declarations}}
+// expected-error at -2 {{structured binding declaration cannot be declared with parentheses}}
+// expected-error at -3 {{expected expression}}
+// expected-error at -4 {{expected ';' after top level declarator}}
+
+([d])(){d}
+// expected-error at -1 {{a type specifier is required for all declarations}}
+// expected-error at -2 {{structured binding declaration cannot be declared with parentheses}}
+// expected-error at -3 {{expected expression}}
+// expected-error at -4 {{expected ';' after top level declarator}}
+
+auto ([a])() {}
+// expected-error at -1 {{structured binding declaration cannot be declared with parentheses}}
+// expected-error at -2 {{expected expression}}
+// expected-error at -3 {{expected ';' after top level declarator}}
+
+auto (([x, y, z]))() {}
+// expected-error at -1 {{structured binding declaration cannot be declared with parentheses}}
+// expected-error at -2 {{expected expression}}
+// expected-error at -3 {{expected ';' after top level declarator}}
+
+struct S {
+  ([m, n])() {}
+  // expected-error at -1 {{structured binding declaration not permitted in this context}}
+  // expected-error at -2 {{expected ';' at end of declaration list}}
+};

``````````

</details>


https://github.com/llvm/llvm-project/pull/219270


More information about the cfe-commits mailing list