On 11/22/25 1:53 PM, Jakub Jelinek wrote:
Hi!
This PR complains that [[maybe_unused]] attribute is ignored on
the range-for-declaration of expansion-statement.
We copy DECL_ATTRIBUTES and apply late attributes, but early attributes
don't have their handlers called again, so some extra flags need to be
copied as well.
This copies TREE_USED and DECL_READ_P flags.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
2025-11-22 Jakub Jelinek <[email protected]>
PR c++/122788
* pt.cc (finish_expansion_stmt): Or in TREE_USED and DECL_READ_P
flags from range_decl to decl or from corresponding structured binding
to this_decl.
* g++.dg/cpp26/expansion-stmt27.C: New test.
--- gcc/cp/pt.cc.jj 2025-11-20 08:19:24.741372896 +0100
+++ gcc/cp/pt.cc 2025-11-21 10:07:06.664153996 +0100
@@ -32900,6 +32900,8 @@ finish_expansion_stmt (tree expansion_st
type = tsubst (type, args, complain | tf_tst_ok, in_decl);
tree decl = build_decl (loc, VAR_DECL, DECL_NAME (range_decl), type);
DECL_ATTRIBUTES (decl) = DECL_ATTRIBUTES (range_decl);
+ TREE_USED (decl) |= TREE_USED (range_decl);
+ DECL_READ_P (decl) |= DECL_READ_P (range_decl);
if (args)
apply_late_template_attributes (&decl, DECL_ATTRIBUTES (decl),
/*flags=*/0, args, complain,
@@ -32958,6 +32960,8 @@ finish_expansion_stmt (tree expansion_st
DECL_ARTIFICIAL (this_decl) = 1;
DECL_ATTRIBUTES (this_decl)
= DECL_ATTRIBUTES (TREE_VEC_ELT (v, i + 1));
+ TREE_USED (this_decl) |= TREE_USED (TREE_VEC_ELT (v, i + 1));
+ DECL_READ_P (this_decl) |= DECL_READ_P (TREE_VEC_ELT (v, i + 1));
if (DECL_PACK_P (TREE_VEC_ELT (v, i + 1)))
{
tree dtype = cxx_make_type (DECLTYPE_TYPE);
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt27.C.jj 2025-11-21
09:53:51.311857261 +0100
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt27.C 2025-11-21
10:04:23.130656298 +0100
@@ -0,0 +1,17 @@
+// PR c++/122788
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wunused" }
+
+void
+foo ()
+{
+ template for ([[maybe_unused]] auto i : { 42 }) // { dg-warning "'template
for' only available with" "" { target c++23_down } }
+ ; // { dg-bogus "unused variable
'i'" "" { target *-*-* } .-1 }
+ template for ([[maybe_unused]] auto j : { 1, 2, 3 }) // { dg-warning "'template
for' only available with" "" { target c++23_down } }
+ { // { dg-bogus "unused variable
'j'" "" { target *-*-* } .-1 }
+#if __cpp_if_constexpr >= 201606
+ if constexpr (false)
+ (void) j;
+#endif
+ }
+}
Jakub