c++: Mark reflected vars/parameters as read [PR124790]

Message ID adSuBGjcn7Tw_K9A@tucnak
State New
Headers
Series c++: Mark reflected vars/parameters as read [PR124790] |

Commit Message

Jakub Jelinek April 7, 2026, 7:11 a.m. UTC
  Hi!

This PR complains about spurious -Wunused-but-set-* warnings when using
reflections.  E.g. there is no warning for variable just set and used in
sizeof (var), but there is one when using size_of (^^var).  If we reflect
some variable or parameter, we can do all kinds of things with it, so
setting preventing these warnings is IMHO desirable.

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

2026-04-07  Jakub Jelinek  <jakub@redhat.com>

	PR c++/124790
	* reflect.cc (get_reflection): When reflecting VAR_DECL or PARM_DECL,
	call mark_exp_read on it.

	* g++.dg/reflect/pr124790.C: New test.


	Jakub
  

Comments

Jason Merrill April 7, 2026, 3:27 p.m. UTC | #1
On 4/7/26 3:11 AM, Jakub Jelinek wrote:
> Hi!
> 
> This PR complains about spurious -Wunused-but-set-* warnings when using
> reflections.  E.g. there is no warning for variable just set and used in
> sizeof (var), but there is one when using size_of (^^var).  If we reflect
> some variable or parameter, we can do all kinds of things with it, so
> setting preventing these warnings is IMHO desirable.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2026-04-07  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/124790
> 	* reflect.cc (get_reflection): When reflecting VAR_DECL or PARM_DECL,
> 	call mark_exp_read on it.
> 
> 	* g++.dg/reflect/pr124790.C: New test.
> 
> --- gcc/cp/reflect.cc.jj	2026-04-05 18:05:56.686310097 +0200
> +++ gcc/cp/reflect.cc	2026-04-06 17:05:30.470028343 +0200
> @@ -219,6 +219,10 @@ get_reflection (location_t loc, tree t,
>   	 instantiate it now to find out its type.  */
>         if (!mark_used (t))
>   	return error_mark_node;
> +      /* Avoid -Wunused-but-set* warnings when a variable or parameter
> +	 is just set and reflected.  */
> +      if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
> +	mark_exp_read (t);
>       }
>   
>     /* For injected-class-name, use the main variant so that comparing
> --- gcc/testsuite/g++.dg/reflect/pr124790.C.jj	2026-04-06 17:32:52.637755896 +0200
> +++ gcc/testsuite/g++.dg/reflect/pr124790.C	2026-04-06 17:32:34.652054385 +0200
> @@ -0,0 +1,38 @@
> +// PR c++/124790
> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection -Wunused-but-set-variable -Wunused-but-set-parameter" }
> +
> +consteval auto
> +foo ()
> +{
> +  int a = 42;		// { dg-bogus "variable 'a' set but not used" }
> +  return ^^a;
> +}
> +
> +consteval auto
> +bar ()
> +{
> +  int a = 42;		// { dg-bogus "variable 'a' set but not used" }
> +  a = 7;
> +  a = 9;
> +  return ^^a;
> +}
> +
> +consteval auto
> +baz (int a)		// { dg-bogus "parameter 'a' set but not used" }
> +{
> +  return ^^a;
> +}
> +
> +consteval auto
> +qux (int a)		// { dg-bogus "parameter 'a' set but not used" }
> +{
> +  a = 7;
> +  a = 9;
> +  return ^^a;
> +}
> +
> +constexpr auto a = foo ();
> +constexpr auto b = bar ();
> +constexpr auto c = baz (42);
> +constexpr auto d = qux (42);
> 
> 	Jakub
>
  

Patch

--- gcc/cp/reflect.cc.jj	2026-04-05 18:05:56.686310097 +0200
+++ gcc/cp/reflect.cc	2026-04-06 17:05:30.470028343 +0200
@@ -219,6 +219,10 @@  get_reflection (location_t loc, tree t,
 	 instantiate it now to find out its type.  */
       if (!mark_used (t))
 	return error_mark_node;
+      /* Avoid -Wunused-but-set* warnings when a variable or parameter
+	 is just set and reflected.  */
+      if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
+	mark_exp_read (t);
     }
 
   /* For injected-class-name, use the main variant so that comparing
--- gcc/testsuite/g++.dg/reflect/pr124790.C.jj	2026-04-06 17:32:52.637755896 +0200
+++ gcc/testsuite/g++.dg/reflect/pr124790.C	2026-04-06 17:32:34.652054385 +0200
@@ -0,0 +1,38 @@ 
+// PR c++/124790
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection -Wunused-but-set-variable -Wunused-but-set-parameter" }
+
+consteval auto
+foo ()
+{
+  int a = 42;		// { dg-bogus "variable 'a' set but not used" }
+  return ^^a;
+}
+
+consteval auto
+bar ()
+{
+  int a = 42;		// { dg-bogus "variable 'a' set but not used" }
+  a = 7;
+  a = 9;
+  return ^^a;
+}
+
+consteval auto
+baz (int a)		// { dg-bogus "parameter 'a' set but not used" }
+{
+  return ^^a;
+}
+
+consteval auto
+qux (int a)		// { dg-bogus "parameter 'a' set but not used" }
+{
+  a = 7;
+  a = 9;
+  return ^^a;
+}
+
+constexpr auto a = foo ();
+constexpr auto b = bar ();
+constexpr auto c = baz (42);
+constexpr auto d = qux (42);