Bug 92402 - parsing error in lambda trail return type with decltype, statement expressions and structured bindings
Summary: parsing error in lambda trail return type with decltype, statement expression...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, ice-on-valid-code, stmt-expr
Depends on:
Blocks: 772 lambdas
  Show dependency treegraph
 
Reported: 2019-11-06 20:46 UTC by jonas simple
Modified: 2025-12-08 07:05 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-07-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jonas simple 2019-11-06 20:46:42 UTC
The following code:

int a[1];

void  f() {
    decltype(({auto&& [x] = a; 0;})) b;
    (void)[]() -> decltype(({auto&& [x] = a; 0;})) { return 0; };
}

when compiled with gcc 9.2 and --std=c++17

outputs:

<source>: In function 'void f()':

<source>:5:39: internal compiler error: in cp_parser_decomposition_declaration, at cp/parser.c:13786

    5 |     (void)[]() -> decltype(({auto&& [x] = a; 0;})) { return 0; };
      |                                       ^

Please submit a full bug report, with preprocessed source if appropriate.
Comment 1 Will Wray 2019-11-21 21:18:51 UTC
Here's a motivating use case; https://godbolt.org/z/Tt-QmN
This allows to effectively SFINAE on structured binding - a 'missing link'.
Works in Clang since 5.0.

GDB debugging gcc latest trunk build. The parse error occurs here

gcc/cp/parser.c:13869

 cp_parser_decomposition_declaration

      else if (decl != error_mark_node && DECL_CHAIN (decl2) != prev)
	{
	  /* Ensure we've diagnosed redeclaration if we aren't creating
	     a new VAR_DECL.  */
	  gcc_assert (errorcount);  /*** HERE  ***/
	  decl = error_mark_node;
	}

Haven't worked out exactly what is being checked there.

So I tried commenting out that entire else-if block to see what happens.
It then proceeds to mangling and crashes out in contains_struct_check.
Backtrace looks like this:

#0  contains_struct_check gcc/cp/mangle.c "write_closure_type_name" gcc/tree.h:3386
#1  write_closure_type_name gcc/cp/mangle.c:1641 in write_unqualified_name 
#3  write_prefix gcc/cp/mangle.c:1164 in mangle_decomp  at gcc/cp/mangle.c:4050
#5  cp_maybe_mangle_decomp gcc/cp/decl.c:8024
#6  cp_parser_decomposition_declaration
Comment 2 Martin Liška 2020-01-30 10:09:00 UTC
Confirmed.
Comment 3 Marek Polacek 2020-01-30 19:02:27 UTC
Even shorter:

int a[1];
void f() {
  []() -> decltype(({auto&& [x] = a; 0;})) { return 0; };
}

clang++ compiles it.
Comment 4 Marek Polacek 2020-01-30 19:07:24 UTC
Not a regression though, so I'll leave it for GCC 11.