]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: allow variadic operator[] for C++23 [PR103460]
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Mar 2022 14:28:20 +0000 (15:28 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 10 Mar 2022 14:28:20 +0000 (15:28 +0100)
wg21.link/p2128 removed "with exactly one parameter" from over.sub
section.  grok_op_properties has for that the last 2 lines in:
    case OVL_OP_FLAG_BINARY:
      if (arity != 2)
        {
          if (operator_code == ARRAY_REF && cxx_dialect >= cxx23)
            break;
but unfortunately it isn't enough, we reject variadic operator[]
earlier.  The following patch accepts variadic operator[] for C++23
too.

2022-03-10  Jakub Jelinek  <jakub@redhat.com>

PR c++/103460
* decl.cc (grok_op_properties): Allow variadic operator[] for
C++23.

* g++.dg/cpp23/subscript7.C: New test.

gcc/cp/decl.cc
gcc/testsuite/g++.dg/cpp23/subscript7.C [new file with mode: 0644]

index 58210905ee989bac3c8f26869c3a2d567152bea7..37d52d8f804e590105544d531a932cbe35aaf2cc 100644 (file)
@@ -15214,6 +15214,9 @@ grok_op_properties (tree decl, bool complain)
       if (!arg)
        {
          /* Variadic.  */
+         if (operator_code == ARRAY_REF && cxx_dialect >= cxx23)
+           break;
+
          error_at (loc, "%qD must not have variable number of arguments",
                    decl);
          return false;
@@ -15289,7 +15292,8 @@ grok_op_properties (tree decl, bool complain)
     }
 
   /* There can be no default arguments.  */
-  for (tree arg = argtypes; arg != void_list_node; arg = TREE_CHAIN (arg))
+  for (tree arg = argtypes; arg && arg != void_list_node;
+       arg = TREE_CHAIN (arg))
     if (TREE_PURPOSE (arg))
       {
        TREE_PURPOSE (arg) = NULL_TREE;
diff --git a/gcc/testsuite/g++.dg/cpp23/subscript7.C b/gcc/testsuite/g++.dg/cpp23/subscript7.C
new file mode 100644 (file)
index 0000000..bb81197
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/103460
+// { dg-do compile }
+// { dg-options "-std=c++23" }
+
+struct S {
+  int &operator[] (int, ...);
+} s;
+struct T {
+  int &operator[] (auto...);
+} t;
+struct U {
+  int &operator[] (...);
+} u;
+
+int a = s[1] + s[2, 1] + s[3, 2, 1] + s[4, 3, 2, 1]
+       + t[0.0] + t[nullptr, s, 42]
+       + u[] + u[42] + u[1.5L, 1LL];