--- gcc/cp/cp-tree.h.jj	2026-04-03 20:46:22.845328260 +0200
+++ gcc/cp/cp-tree.h	2026-04-06 09:59:23.095379300 +0200
@@ -8028,10 +8028,10 @@ extern tree clone_attrs				(tree);
 extern bool maybe_clone_body			(tree);
 
 /* In parser.cc */
-extern tree cp_build_range_for_decls (location_t, tree, tree *, bool);
+extern tree cp_build_range_for_decls (location_t, tree, tree *, tree);
 extern tree cp_convert_range_for (tree, tree, tree, cp_decomp *, bool,
 				  tree, bool);
-extern tree build_range_temp (tree, bool = false);
+extern tree build_range_temp (tree, tree = NULL_TREE);
 extern tree cp_perform_range_for_lookup	(tree, tree *, tree *,
 					 tsubst_flags_t = tf_warning_or_error);
 extern void cp_convert_omp_range_for (tree &, tree &, tree &,
--- gcc/cp/parser.cc.jj	2026-04-04 11:32:27.440454554 +0200
+++ gcc/cp/parser.cc	2026-04-06 09:59:23.100379216 +0200
@@ -15854,16 +15854,17 @@ cp_parser_range_for (cp_parser *parser,
    builds up the range temporary.  */
 
 tree
-build_range_temp (tree range_expr, bool expansion_stmt_p /* = false */)
+build_range_temp (tree range_expr, tree expansion_stmt_decl /* = NULL_TREE */)
 {
   tree range_type, auto_node;
 
-  if (expansion_stmt_p)
+  if (expansion_stmt_decl)
     {
       /* Build const decltype(auto) __range = range_expr;
 	 - range_expr provided by the caller already is (range_expr).  */
-      auto_node = make_decltype_auto ();
-      range_type = cp_build_qualified_type (auto_node, TYPE_QUAL_CONST);
+      range_type = auto_node = make_decltype_auto ();
+      if (DECL_DECLARED_CONSTEXPR_P (expansion_stmt_decl))
+	range_type = cp_build_qualified_type (auto_node, TYPE_QUAL_CONST);
     }
   else
     {
@@ -16007,11 +16008,13 @@ warn_for_range_copy (tree decl, tree exp
 
 /* Helper function for cp_convert_range_for and finish_expansion_stmt.
    Build the __range, __begin and __end declarations.  Return the
-   __begin VAR_DECL, set *END_P to the __end VAR_DECL.  */
+   __begin VAR_DECL, set *END_P to the __end VAR_DECL.  If
+   EXPANSION_STMT_DECL, don't create __end and instead store
+   begin_expr to END_P[0] and end_expr to END_P[1].  */
 
 tree
 cp_build_range_for_decls (location_t loc, tree range_expr, tree *end_p,
-			  bool expansion_stmt_p)
+			  tree expansion_stmt_decl)
 {
   tree iter_type, begin_expr, end_expr;
 
@@ -16023,30 +16026,34 @@ cp_build_range_for_decls (location_t loc
     {
       tree range_temp;
 
-      if (!expansion_stmt_p
+      if (!expansion_stmt_decl
 	  && VAR_P (range_expr)
 	  && array_of_runtime_bound_p (TREE_TYPE (range_expr)))
 	/* Can't bind a reference to an array of runtime bound.  */
 	range_temp = range_expr;
       else
 	{
-	  if (expansion_stmt_p)
+	  if (expansion_stmt_decl)
 	    {
 	      /* Build constexpr decltype(auto) __for_range = (range_expr);  */
 	      location_t range_loc = cp_expr_loc_or_loc (range_expr, loc);
 	      range_expr
 		= finish_parenthesized_expr (cp_expr (range_expr, range_loc));
-	      range_temp = build_range_temp (range_expr, true);
+	      range_temp = build_range_temp (range_expr, expansion_stmt_decl);
 
 	      /* When P2686R4 is fully implemented, these 3 sets of TREE_STATIC
 		 (on range_temp, begin and end) should be removed as per
-		 CWG3044.  */
-	      TREE_STATIC (range_temp) = 1;
-	      TREE_PUBLIC (range_temp) = 0;
-	      DECL_COMMON (range_temp) = 0;
-	      DECL_INTERFACE_KNOWN (range_temp) = 1;
-	      DECL_DECLARED_CONSTEXPR_P (range_temp) = 1;
-	      TREE_READONLY (range_temp) = 1;
+		 CWG3044.  If expansion_stmt_decl is not constexpr, we don't
+		 need the static though.  */
+	      if (DECL_DECLARED_CONSTEXPR_P (expansion_stmt_decl))
+		{
+		  TREE_STATIC (range_temp) = 1;
+		  TREE_PUBLIC (range_temp) = 0;
+		  DECL_COMMON (range_temp) = 0;
+		  DECL_INTERFACE_KNOWN (range_temp) = 1;
+		  DECL_DECLARED_CONSTEXPR_P (range_temp) = 1;
+		  TREE_READONLY (range_temp) = 1;
+		}
 	    }
 	  else
 	    /* Build auto &&__for_range = range_expr;  */
@@ -16063,12 +16070,14 @@ cp_build_range_for_decls (location_t loc
     }
 
   /* The new for initialization statement.  */
-  if (expansion_stmt_p && !TYPE_REF_P (iter_type))
+  if (expansion_stmt_decl
+      && DECL_DECLARED_CONSTEXPR_P (expansion_stmt_decl)
+      && !TYPE_REF_P (iter_type))
     iter_type = cp_build_qualified_type (iter_type, TYPE_QUAL_CONST);
   tree begin = build_decl (loc, VAR_DECL, for_begin__identifier, iter_type);
   TREE_USED (begin) = 1;
   DECL_ARTIFICIAL (begin) = 1;
-  if (expansion_stmt_p)
+  if (expansion_stmt_decl && DECL_DECLARED_CONSTEXPR_P (expansion_stmt_decl))
     {
       TREE_STATIC (begin) = 1;
       DECL_DECLARED_CONSTEXPR_P (begin) = 1;
@@ -16079,21 +16088,18 @@ cp_build_range_for_decls (location_t loc
 		  /*is_constant_init*/false, NULL_TREE,
 		  LOOKUP_ONLYCONVERTING);
 
-  if (cxx_dialect >= cxx17)
+  if (expansion_stmt_decl)
     {
-      iter_type = cv_unqualified (TREE_TYPE (end_expr));
-      if (expansion_stmt_p && !TYPE_REF_P (iter_type))
-	iter_type = cp_build_qualified_type (iter_type, TYPE_QUAL_CONST);
+      end_p[0] = begin_expr;
+      end_p[1] = end_expr;
+      return begin;
     }
+
+  if (cxx_dialect >= cxx17)
+    iter_type = cv_unqualified (TREE_TYPE (end_expr));
   tree end = build_decl (loc, VAR_DECL, for_end__identifier, iter_type);
   TREE_USED (end) = 1;
   DECL_ARTIFICIAL (end) = 1;
-  if (expansion_stmt_p)
-    {
-      TREE_STATIC (end) = 1;
-      DECL_DECLARED_CONSTEXPR_P (end) = 1;
-      TREE_READONLY (end) = 1;
-    }
   pushdecl (end);
   cp_finish_decl (end, end_expr,
 		  /*is_constant_init*/false, NULL_TREE,
@@ -16149,7 +16155,7 @@ cp_convert_range_for (tree statement, tr
   if (range_decl == error_mark_node)
     range_expr = error_mark_node;
   tree begin
-    = cp_build_range_for_decls (input_location, range_expr, &end, false);
+    = cp_build_range_for_decls (input_location, range_expr, &end, NULL_TREE);
 
   finish_init_stmt (statement);
 
--- gcc/cp/pt.cc.jj	2026-04-04 11:07:32.000119351 +0200
+++ gcc/cp/pt.cc	2026-04-06 10:59:16.537372085 +0200
@@ -33329,34 +33329,46 @@ finish_expansion_stmt (tree expansion_st
   if (kind == esk_iterating)
     {
       /* Iterating expansion statements.  */
-      tree end;
-      begin = cp_build_range_for_decls (loc, expansion_init, &end, true);
-      if (!error_operand_p (begin) && !error_operand_p (end))
+      tree exprs[2];
+      begin = cp_build_range_for_decls (loc, expansion_init, exprs, range_decl);
+      if (!error_operand_p (begin)
+	  && !error_operand_p (exprs[0])
+	  && !error_operand_p (exprs[1]))
 	{
 	  /* In the standard this is all evaluated inside of a consteval
 	     lambda.  So, force in_immediate_context () around this.  */
 	  in_consteval_if_p_temp_override icip;
 	  in_consteval_if_p = true;
-	  tree i
-	    = build_target_expr_with_type (begin,
-					   cv_unqualified (TREE_TYPE (begin)),
-					   tf_warning_or_error);
+	  tree b = exprs[0], e = exprs[1];
+	  if (TREE_CODE (b) == TARGET_EXPR)
+	    b = TARGET_EXPR_INITIAL (b);
+	  if (TREE_CODE (e) == TARGET_EXPR)
+	    e = TARGET_EXPR_INITIAL (e);
+	  b = force_target_expr (cv_unqualified (TREE_TYPE (b)), b,
+				 tf_warning_or_error);
+	  e = force_target_expr (cv_unqualified (TREE_TYPE (e)), e,
+				 tf_warning_or_error);
 	  tree w = build_stmt (loc, WHILE_STMT, NULL_TREE, NULL_TREE,
 			       NULL_TREE, NULL_TREE, NULL_TREE);
 	  tree r = get_target_expr (build_zero_cst (ptrdiff_type_node));
-	  tree iinc = build_x_unary_op (loc, PREINCREMENT_EXPR,
-					TARGET_EXPR_SLOT (i), NULL_TREE,
+	  tree binc = build_x_unary_op (loc, PREINCREMENT_EXPR,
+					TARGET_EXPR_SLOT (b), NULL_TREE,
 					tf_warning_or_error);
 	  tree rinc = build2 (PREINCREMENT_EXPR, ptrdiff_type_node,
 			      TARGET_EXPR_SLOT (r),
 			      build_int_cst (ptrdiff_type_node, 1));
-	  WHILE_BODY (w) = build_compound_expr (loc, iinc, rinc);
-	  WHILE_COND (w) = build_x_binary_op (loc, NE_EXPR, i, ERROR_MARK,
-					      end, ERROR_MARK, NULL_TREE, NULL,
+	  WHILE_BODY (w) = build_compound_expr (loc, binc, rinc);
+	  WHILE_COND (w) = build_x_binary_op (loc, NE_EXPR, b, ERROR_MARK,
+					      e, ERROR_MARK, NULL_TREE, NULL,
 					      tf_warning_or_error);
-	  tree e = build_compound_expr (loc, r, i);
-	  e = build_compound_expr (loc, e, w);
-	  e = build_compound_expr (loc, e, TARGET_EXPR_SLOT (r));
+	  {
+	    warning_sentinel wur (warn_unused_result);
+	    e = build_compound_expr (loc, b, e);
+	    e = build_compound_expr (loc, r, e);
+	    e = build_compound_expr (loc, e, w);
+	    e = build_compound_expr (loc, e, TARGET_EXPR_SLOT (r));
+	  }
+	  e = fold_build_cleanup_point_expr (TREE_TYPE (e), e);
 	  e = cxx_constant_value (e);
 	  if (tree_fits_uhwi_p (e))
 	    n = tree_to_uhwi (e);
@@ -33481,13 +33493,18 @@ finish_expansion_stmt (tree expansion_st
 				 tf_warning_or_error);
 	  auto_node = make_auto ();
 	  iter_type = do_auto_deduction (auto_node, iter_init, auto_node);
-	  if (!TYPE_REF_P (iter_type))
+	  if (DECL_DECLARED_CONSTEXPR_P (range_decl)
+	      && !TYPE_REF_P (iter_type))
 	    iter_type = cp_build_qualified_type (iter_type, TYPE_QUAL_CONST);
 	  iter = build_decl (loc, VAR_DECL, NULL_TREE, iter_type);
 	  TREE_USED (iter) = 1;
 	  DECL_ARTIFICIAL (iter) = 1;
-	  TREE_STATIC (iter) = 1;
-	  DECL_DECLARED_CONSTEXPR_P (iter) = 1;
+	  if (DECL_DECLARED_CONSTEXPR_P (range_decl))
+	    {
+	      TREE_STATIC (iter) = 1;
+	      DECL_DECLARED_CONSTEXPR_P (iter) = 1;
+	      TREE_READONLY (iter) = 1;
+	    }
 	  pushdecl (iter);
 	  cp_finish_decl (iter, iter_init, /*is_constant_init*/false,
 			  NULL_TREE, LOOKUP_ONLYCONVERTING);
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt11.C.jj	2026-03-27 10:17:15.653305952 +0100
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt11.C	2026-04-06 11:10:33.407077674 +0200
@@ -9,7 +9,7 @@ struct T { using type = T; int s; };
 T d = { 8 };
 struct U {
   constexpr const S *begin () const { return &c[0]; }
-  constexpr const S *end () const { return &c[s]; }
+  constexpr const S *end () const { return &c[s]; }	// { dg-error "is not usable in a constant expression" "" { target c++11_down } }
   int s;
 };
 struct V { int a; long b; double c; };
@@ -29,7 +29,7 @@ foo ()
   template for (auto g : u)		// { dg-warning "'template for' only available with" "" { target c++23_down } }
     {
       decltype(g)::type h = g;
-    }
+    }					// { dg-message "was not declared 'constexpr'" "" { target c++11_down } }
   V v = { 9, 10L, 11.0 };
   template for (auto g : v)		// { dg-warning "'template for' only available with" "" { target c++23_down } }
     {
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt13.C.jj	2026-03-27 10:17:15.653305952 +0100
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt13.C	2026-04-07 08:21:54.478390430 +0200
@@ -1,5 +1,6 @@
 // C++26 P1306R5 - Expansion statements
-// { dg-do run { target c++11 } }
+// { dg-do run { target c++14 } }
+// { dg-do compile { target c++11_only } }
 // { dg-options "" }
 
 namespace std {
@@ -11,7 +12,7 @@ struct S { int s; };
 constexpr S c[] = { { 3 }, { 4 }, { 5 }, { 6 }, { 7 } };
 struct U {
   constexpr const S *begin () const { return &c[0]; }
-  constexpr const S *end () const { return &c[s]; }
+  constexpr const S *end () const { return &c[s]; }	// { dg-error "is not usable in a constant expression" "" { target c++11_down } }
   int s;
 };
 constexpr U u1 = { 3 }, u2 = { 0 };
@@ -45,7 +46,7 @@ foo ()
   template for (auto h = 2; constexpr auto g : u1)	// { dg-warning "'template for' only available with" "" { target c++23_down } }
     r += g.s + h;
   template for (long long h = ++r; auto g : u2)		// { dg-warning "'template for' only available with" "" { target c++23_down } }
-    __builtin_abort ();
+    __builtin_abort ();					// { dg-message "was not declared 'constexpr'" "" { target c++11_down } }
   return r;
 }
 
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt16.C.jj	2026-03-27 10:17:15.653305952 +0100
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt16.C	2026-04-06 11:18:26.642182557 +0200
@@ -49,12 +49,11 @@ foo ()
   template for (constexpr auto g : d)	// { dg-warning "'template for' only available with" "" { target c++23_down } }
     ;					// { dg-error "'d' is not a constant expression" "" { target c++14 } .-1 }
 					// { dg-error "call to non-'constexpr' function 'const A\\\* C::begin\\\(\\\) const'" "" { target c++11_down } .-1 }
-					// { dg-error "call to non-'constexpr' function 'const A\\\* C::end\\\(\\\) const'" "" { target c++11_down } .-2 }
-					// { dg-error "the type 'const C' of 'constexpr' variable '__for_range ' is not literal" "" { target c++11_down } .-3 }
+					// { dg-error "the type 'const C' of 'constexpr' variable '__for_range ' is not literal" "" { target c++11_down } .-2 }
   constexpr D e = { 3 };
   template for (constexpr auto g : e)	// { dg-warning "'template for' only available with" "" { target c++23_down } }
     ;					// { dg-error "'e' is not a constant expression" "" { target c++14 } .-1 }
-					// { dg-error "call to non-'constexpr' function 'const A\\\* D::end\\\(\\\) const'" "" { target *-*-* } .-1 }
+					// { dg-error "call to non-'constexpr' function 'const A\\\* D::end\\\(\\\) const'" "" { target c++11_down } .-1 }
   constexpr E f = { 3 };
   template for (constexpr auto g : f)	// { dg-warning "'template for' only available with" "" { target c++23_down } }
     ;					// { dg-error "'f' is not a constant expression" "" { target c++14 } .-1 }
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt19.C.jj	2026-03-27 10:17:15.653305952 +0100
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt19.C	2026-04-07 08:22:10.880110548 +0200
@@ -1,5 +1,6 @@
 // C++26 P1306R5 - Expansion statements
-// { dg-do run { target c++11 } }
+// { dg-do run { target c++14 } }
+// { dg-do compile { target c++11_only } }
 // { dg-options "" }
 
 namespace std {
@@ -18,7 +19,7 @@ template<int I> struct std::tuple_elemen
 constexpr V c[] = { { 3, 4 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 } };
 struct U {
   constexpr const V *begin () const { return &c[0]; }
-  constexpr const V *end () const { return &c[s]; }
+  constexpr const V *end () const { return &c[s]; }	// { dg-error "is not usable in a constant expression" "" { target c++11_down } }
   int s;
 };
 constexpr U u1 = { 3 }, u2 = { 0 };
@@ -51,6 +52,7 @@ foo ()
   template for (long long h = ++r; auto [...i, j] : u2)	// { dg-warning "'template for' only available with" "" { target c++23_down } }
     __builtin_abort ();					// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
 							// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } .-2 }
+							// { dg-message "was not declared 'constexpr'" "" { target c++11_down } .-3 }
   return r;
 }
 
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt25.C.jj	2026-04-01 19:09:34.867401760 +0200
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt25.C	2026-04-06 09:59:23.103559220 +0200
@@ -22,6 +22,8 @@ namespace N
 void
 foo ()
 {
-  template for (auto i : N::B {})				// { dg-warning "'template for' only available with" "" { target c++23_down } }
+  template for (constexpr auto i : N::B {})			// { dg-warning "'template for' only available with" "" { target c++23_down } }
     ;								// { dg-error "no match for 'operator-' in '__for_begin  - __for_begin ' \\\(operand types are 'const A' and 'const A'\\\)" "" { target *-*-* } .-1 }
+  template for (auto i : N::B {})				// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    ;								// { dg-error "no match for 'operator-' in '__for_begin  - __for_begin ' \\\(operand types are 'A' and 'A'\\\)" "" { target *-*-* } .-1 }
 }
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt30.C.jj	2026-03-27 10:17:15.654305935 +0100
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt30.C	2026-04-06 11:12:43.266911186 +0200
@@ -30,7 +30,7 @@ foo ()
   for (auto i : N::S {})		// { dg-error "call of overloaded 'begin\\\(N::S\\\&\\\)' is ambiguous" }
     ;
   template for (auto i : N::S {})
-    ;					// { dg-error "call of overloaded 'begin\\\(const N::S\\\&\\\)' is ambiguous" }
+    ;					// { dg-error "call of overloaded 'begin\\\(N::S\\\&\\\)' is ambiguous" }
   template for (auto i : V {})
     ;					// { dg-error "cannot be used as a function" }
   template for (auto i : O::B {})
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt35.C.jj	2026-04-06 11:37:50.160784900 +0200
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt35.C	2026-04-06 11:53:22.034260816 +0200
@@ -0,0 +1,60 @@
+// CWG3140 - Allowing expansion over non-constant std::array
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+struct A
+{
+  int x;
+  constexpr explicit A (int v) : x(v) {}
+  constexpr A &operator ++ () { ++x; return *this; }
+  constexpr int operator * () const { return x; }
+  constexpr bool operator != (const A &o) const { return x != o.x; }
+  constexpr A operator + (int o) const { A r (x + o); return r; }
+  constexpr int operator - (const A &o) const { return x - o.x; }
+};
+
+namespace N
+{
+  struct B { constexpr B (int n) : b (n) {} int b; };
+  constexpr A begin (const B &) { return A (0); }
+  constexpr A end (const B &x) { return A (x.b); }	// { dg-error "is not usable in a constant expression" }
+  struct C { };
+  constexpr A begin (const C &) { return A (0); }
+  constexpr A end (const C &x) { return A (6); }
+}
+
+int
+foo ()
+{
+  int r = 0;
+  template for (constexpr auto m : N::B (3))	// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    r += m;
+  return r;
+}
+
+int
+bar ()
+{
+  int r = 0;
+  template for (auto m : N::B (3))		// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    r += m;					// { dg-message "was not declared 'constexpr'" }
+  return r;
+}
+
+int
+baz ()
+{
+  int r = 0;
+  template for (constexpr auto m : N::C ())	// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    r += m;
+  return r;
+}
+
+int
+qux ()
+{
+  int r = 0;
+  template for (auto m : N::C ())		// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    r += m;
+  return r;
+}
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt36.C.jj	2026-04-06 11:37:57.111669031 +0200
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt36.C	2026-04-06 11:55:13.017411979 +0200
@@ -0,0 +1,21 @@
+// CWG3140 - Allowing expansion over non-constant std::array
+// { dg-do run { target c++17 } }
+// { dg-options "" }
+
+#include <array>
+
+std::array <int, 5>
+foo ()
+{
+  return { 1, 2, 3, 4, 5 };
+}
+
+int
+main ()
+{
+  int r = 0;
+  template for (auto n : foo ())	// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    r += n;
+  if (r != 15)
+    __builtin_abort ();
+}
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt37.C.jj	2026-04-06 11:39:45.982855213 +0200
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt37.C	2026-04-06 12:00:39.720970271 +0200
@@ -0,0 +1,19 @@
+// CWG3140 - Allowing expansion over non-constant std::array
+// { dg-do compile { target c++17 } }
+// { dg-options "" }
+
+#include <array>
+
+std::array <int, 5>
+foo ()
+{
+  return { 1, 2, 3, 4, 5 };
+}
+
+void
+bar ()
+{
+  int r = 0;
+  template for (constexpr auto n : foo ())	// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    r += n;					// { dg-error " call to non-'constexpr' function" "" { target *-*-* } .-1 }
+}
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt38.C.jj	2026-04-06 11:40:59.562629467 +0200
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt38.C	2026-04-06 11:59:16.769351934 +0200
@@ -0,0 +1,36 @@
+// CWG3140 - Allowing expansion over non-constant std::array
+// { dg-do run { target c++17 } }
+// { dg-options "" }
+// { dg-additional-options "-frange-for-ext-temps" { target c++20_down } }
+
+#include <array>
+
+struct A {
+  A () { a++; }
+  A (const A &) { a++; }
+  ~A () { a--; }
+  static int a;
+};
+int A::a = 0;
+
+std::array <int, 5>
+foo (A, A, A)
+{
+  return { 1, 2, 3, 4, 5 };
+}
+
+int
+main ()
+{
+  int r = 0;
+  if (A::a != 0)
+    __builtin_abort ();
+  template for (auto n : foo (A (), A (), A ()))	// { dg-warning "'template for' only available with" "" { target c++23_down } }
+    {
+      if (A::a != 3)
+	__builtin_abort ();
+      r += n;
+    }
+  if (r != 15 || A::a != 0)
+    __builtin_abort ();
+}
