diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 201f1e6b6b96861dccb3b193c98f7d5f8191154d..2b195e999975cee7c5be03a11cef0ad367a23be8 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -474,11 +474,23 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
 					     &overload, complain);
 		}
 	      else
-		/* If it would be valid albeit deprecated expression in C++20,
-		   just pedwarn on it and treat it as if wrapped in ().  */
-		pedwarn (loc, OPT_Wcomma_subscript,
-			 "top-level comma expression in array subscript "
-			 "changed meaning in C++23");
+		{
+		  /* If it would be valid albeit deprecated expression in
+		     C++20, just pedwarn on it and treat it as if wrapped
+		     in ().  */
+		  pedwarn (loc, OPT_Wcomma_subscript,
+			   "top-level comma expression in array subscript "
+			   "changed meaning in C++23");
+		  if (processing_template_decl)
+		    {
+		      orig_index_exp
+			= build_x_compound_expr_from_vec (orig_index_exp_list,
+							  NULL, complain);
+		      if (orig_index_exp == error_mark_node)
+			expr = error_mark_node;
+		      release_tree_vector (orig_index_exp_list);
+		    }
+		}
 	    }
 	}
     }
@@ -519,6 +531,15 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
 	      return error_mark_node;
 	    }
 	  index_exp = idx;
+	  if (processing_template_decl)
+	    {
+	      orig_index_exp
+		= build_x_compound_expr_from_vec (orig_index_exp_list,
+						  NULL, complain);
+	      release_tree_vector (orig_index_exp_list);
+	      if (orig_index_exp == error_mark_node)
+		return error_mark_node;
+	    }
 	}
 
       if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
diff --git a/gcc/testsuite/g++.dg/cpp23/subscript14.C b/gcc/testsuite/g++.dg/cpp23/subscript14.C
new file mode 100644
index 0000000000000000000000000000000000000000..042799c6aba12da311e4c40f973ce1093ccd17b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/subscript14.C
@@ -0,0 +1,42 @@
+// PR c++/109319
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A { static int &operator[] (int x) { static int a[2]; return a[x]; } };	// { dg-warning "may be a static member function only with" "" { target c++20_down } }
+struct B { int &operator[] (int x) { static int b[2]; return b[x]; } };
+int c[2];
+
+template <typename T, typename U, typename V>
+int
+foo ()
+{
+  A a;
+  ++a[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  B b;			// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++b[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+			// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++c[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  T d;			// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++d[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  U e;			// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++e[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  extern V f[2];	// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++f[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  return 0;		// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+}
+
+int f[2];
+
+int
+main ()
+{
+  A a;
+  ++a[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  B b;			// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++b[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+			// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  ++c[0, 1];		// { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } }
+  foo <A, B, int> ();	// { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 }
+  if (a.operator[] (1) != 3 || b.operator[] (1) != 3 || c[1] != 2 || f[1] != 1)
+    __builtin_abort ();
+}