c++: Fix up pedwarn for capturing structured bindings in lambdas [PR118719]

Message ID Z59Fn+5PYrFWDaR+@tucnak
State New
Headers
Series c++: Fix up pedwarn for capturing structured bindings in lambdas [PR118719] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Jakub Jelinek Feb. 2, 2025, 10:14 a.m. UTC
  Hi!

As mentioned in the PR, this pedwarni is desirable for the implicit or
explicit capturing of structured bindings in C++17, but in the case of
init-captures the initializer is just some expression and that can include
structured bindings.

So, the following patch limits the warning to non-explicit_init_p.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-02-02  Jakub Jelinek  <jakub@redhat.com>

	PR c++/118719
	* lambda.cc (add_capture): Only pedwarn about capturing structured
	binding if !explicit_init_p.

	* g++.dg/cpp1z/decomp63.C: New test.


	Jakub
  

Comments

Marek Polacek Feb. 3, 2025, 1:58 p.m. UTC | #1
On Sun, Feb 02, 2025 at 11:14:55AM +0100, Jakub Jelinek wrote:
> Hi!
> 
> As mentioned in the PR, this pedwarni is desirable for the implicit or
> explicit capturing of structured bindings in C++17, but in the case of
> init-captures the initializer is just some expression and that can include
> structured bindings.
> 
> So, the following patch limits the warning to non-explicit_init_p.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

LGTM, sorry for missing the !explicit_init_p check.
 
> 2025-02-02  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/118719
> 	* lambda.cc (add_capture): Only pedwarn about capturing structured
> 	binding if !explicit_init_p.
> 
> 	* g++.dg/cpp1z/decomp63.C: New test.
> 
> --- gcc/cp/lambda.cc.jj	2025-01-24 17:37:49.004457905 +0100
> +++ gcc/cp/lambda.cc	2025-01-31 23:47:08.907034696 +0100
> @@ -613,7 +613,7 @@ add_capture (tree lambda, tree id, tree
>  	    return error_mark_node;
>  	}
>  
> -      if (cxx_dialect < cxx20)
> +      if (cxx_dialect < cxx20 && !explicit_init_p)
>  	{
>  	  auto_diagnostic_group d;
>  	  tree stripped_init = tree_strip_any_location_wrapper (initializer);
> --- gcc/testsuite/g++.dg/cpp1z/decomp63.C.jj	2025-01-31 23:54:15.480699418 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp63.C	2025-01-31 23:53:02.998578507 +0100
> @@ -0,0 +1,18 @@
> +// PR c++/118719
> +// { dg-do compile { target c++11 } }
> +// { dg-options "" }
> +
> +int
> +main ()
> +{
> +  int a[] = { 42 };
> +  auto [x] = a;					// { dg-warning "structured bindings only available with" "" { target c++14_down } }
> +						// { dg-message "declared here" "" { target c++17_down } .-1 }
> +  [=] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [&] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [x] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [&x] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [x = x] () { int b = x; (void) b; };		// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
> +  [y = x] () { int b = y; (void) b; };		// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
> +  [y = x * 2] () { int b = y; (void) b; };	// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
> +}
> 
> 	Jakub
> 

Marek
  
Jason Merrill Feb. 3, 2025, 11:35 p.m. UTC | #2
On 2/2/25 5:14 AM, Jakub Jelinek wrote:
> Hi!
> 
> As mentioned in the PR, this pedwarni is desirable for the implicit or
> explicit capturing of structured bindings in C++17, but in the case of
> init-captures the initializer is just some expression and that can include
> structured bindings.
> 
> So, the following patch limits the warning to non-explicit_init_p.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2025-02-02  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/118719
> 	* lambda.cc (add_capture): Only pedwarn about capturing structured
> 	binding if !explicit_init_p.
> 
> 	* g++.dg/cpp1z/decomp63.C: New test.
> 
> --- gcc/cp/lambda.cc.jj	2025-01-24 17:37:49.004457905 +0100
> +++ gcc/cp/lambda.cc	2025-01-31 23:47:08.907034696 +0100
> @@ -613,7 +613,7 @@ add_capture (tree lambda, tree id, tree
>   	    return error_mark_node;
>   	}
>   
> -      if (cxx_dialect < cxx20)
> +      if (cxx_dialect < cxx20 && !explicit_init_p)
>   	{
>   	  auto_diagnostic_group d;
>   	  tree stripped_init = tree_strip_any_location_wrapper (initializer);
> --- gcc/testsuite/g++.dg/cpp1z/decomp63.C.jj	2025-01-31 23:54:15.480699418 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp63.C	2025-01-31 23:53:02.998578507 +0100
> @@ -0,0 +1,18 @@
> +// PR c++/118719
> +// { dg-do compile { target c++11 } }
> +// { dg-options "" }
> +
> +int
> +main ()
> +{
> +  int a[] = { 42 };
> +  auto [x] = a;					// { dg-warning "structured bindings only available with" "" { target c++14_down } }
> +						// { dg-message "declared here" "" { target c++17_down } .-1 }
> +  [=] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [&] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [x] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [&x] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
> +  [x = x] () { int b = x; (void) b; };		// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
> +  [y = x] () { int b = y; (void) b; };		// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
> +  [y = x * 2] () { int b = y; (void) b; };	// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
> +}
> 
> 	Jakub
>
  

Patch

--- gcc/cp/lambda.cc.jj	2025-01-24 17:37:49.004457905 +0100
+++ gcc/cp/lambda.cc	2025-01-31 23:47:08.907034696 +0100
@@ -613,7 +613,7 @@  add_capture (tree lambda, tree id, tree
 	    return error_mark_node;
 	}
 
-      if (cxx_dialect < cxx20)
+      if (cxx_dialect < cxx20 && !explicit_init_p)
 	{
 	  auto_diagnostic_group d;
 	  tree stripped_init = tree_strip_any_location_wrapper (initializer);
--- gcc/testsuite/g++.dg/cpp1z/decomp63.C.jj	2025-01-31 23:54:15.480699418 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp63.C	2025-01-31 23:53:02.998578507 +0100
@@ -0,0 +1,18 @@ 
+// PR c++/118719
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+int
+main ()
+{
+  int a[] = { 42 };
+  auto [x] = a;					// { dg-warning "structured bindings only available with" "" { target c++14_down } }
+						// { dg-message "declared here" "" { target c++17_down } .-1 }
+  [=] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
+  [&] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
+  [x] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
+  [&x] () { int b = x; (void) b; };		// { dg-warning "captured structured bindings are a C\\\+\\\+20 extension" "" { target c++17_down } }
+  [x = x] () { int b = x; (void) b; };		// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
+  [y = x] () { int b = y; (void) b; };		// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
+  [y = x * 2] () { int b = y; (void) b; };	// { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
+}