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&lt;FunctionDecl&gt;` 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@-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}}
+};

``````````

</details>


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

Reply via email to