]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Don't prune constant capture proxies only used in array dimensions [PR114292]
authorSimon Martin <simon@nasilyan.com>
Wed, 22 Jan 2025 15:19:47 +0000 (16:19 +0100)
committerSimon Martin <simon@nasilyan.com>
Mon, 27 Jan 2025 19:29:33 +0000 (20:29 +0100)
commitceabea405ffdc851736e240111be9b297ad86c53
tree8e0c08df075d0bf9fda55b9b55d4568f58b00ead
parentf7dc4fd62ce4d9287988892b1e94bbdd0ca1c8fa
c++: Don't prune constant capture proxies only used in array dimensions [PR114292]

We currently ICE upon the following valid (under -Wno-vla) code

=== cut here ===
void f(int c) {
  constexpr int r = 4;
  [&](auto) { int t[r * c]; }(0);
}
=== cut here ===

When parsing the lambda body, and more specifically the multiplication,
we mark the lambda as LAMBDA_EXPR_CAPTURE_OPTIMIZED, which indicates to
prune_lambda_captures that it might be possible to optimize out some
captures.

The problem is that prune_lambda_captures then misses the use of the r
capture (because neither walk_tree_1 nor cp_walk_subtrees walks the
dimensions of array types - here "r * c"), hence believes the capture
can be pruned... and we trip on an assert when instantiating the lambda.

This patch changes cp_walk_subtrees so that (1) when walking a
DECL_EXPR, it also walks the DECL's type, and (2) when walking an
INTEGER_TYPE, it also walks its TYPE_{MIN,MAX}_VALUE. Note that #2 makes
a <case INTEGER_TYPE> redundant in for_each_template_parm_r, and removes
it.

PR c++/114292

gcc/cp/ChangeLog:

* pt.cc (for_each_template_parm_r) <INTEGER_TYPE>: Remove case
now handled by cp_walk_subtrees.
* tree.cc (cp_walk_subtrees): Walk the type of DECL_EXPR
declarations, as well as the TYPE_{MIN,MAX}_VALUE of
INTEGER_TYPEs.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/lambda-ice4.C: New test.
gcc/cp/pt.cc
gcc/cp/tree.cc
gcc/testsuite/g++.dg/cpp1y/lambda-ice4.C [new file with mode: 0644]