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
