royjacobson created this revision.
royjacobson added reviewers: cor3ntin, erichkeane.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

After accepted in Kona, update the code to accept static operator[]
as well.

No big code changes, just accept this in SemaDeclCXX and update
feature macros + tests accordingly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D138387

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/over/over.oper/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1518,7 +1518,7 @@
     <tr>
       <td>static <code>operator[]</code></td>
       <td><a href="https://wg21.link/P2589R1";>P2589R1</a></td>
-      <td class="none" align="center">No</td>
+      <td class="unreleased" align="center">16</td>
     </tr>
     <tr>
       <td>Permitting static constexpr variables in constexpr functions (DR)</td>
Index: clang/test/Lexer/cxx-features.cpp
===================================================================
--- clang/test/Lexer/cxx-features.cpp
+++ clang/test/Lexer/cxx-features.cpp
@@ -43,7 +43,7 @@
 #error "wrong value for __cpp_if_consteval"
 #endif
 
-#if check(multidimensional_subscript, 0, 0, 0, 0, 0, 202110)
+#if check(multidimensional_subscript, 0, 0, 0, 0, 0, 202211)
 #error "wrong value for __cpp_multidimensional_subscript"
 #endif
 
Index: clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
+
+struct Functor {
+  static int operator[](int x, int y) {
+    return x + y;
+  }
+};
+
+void call_static_subscript_operator[] {
+  Functor f;
+  f[101, 102];
+  f.operator[](201, 202);
+  Functor{}[301, 302];
+}
+
+// CHECK:      define {{.*}}call_static_subscript_operator{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:        {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 301, i32 noundef 302)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+struct FunctorConsteval {
+  consteval static int operator[](int x, int y) {
+      return x + y;
+  }
+};
+
+struct FunctorConstexpr {
+  constexpr static int operator[](int x, int y) {
+      return x + y;
+  }
+};
+
+void test_consteval_constexpr() {
+  int x = 0;
+  int y = FunctorConstexpr{}[x, 2];
+  constexpr int z1 = FunctorConsteval{}[2, 2];
+  constexpr int z2 = FunctorConstexpr{}[2, 2];
+  
+  static_assert(z1 == 4);
+  static_assert(z2 == 4);
+}
+
+template <class T>
+struct DepFunctor {
+  static int operator[](T t) {
+    return int(t);
+  }
+};
+
+void test_dep_functors() {
+  int x = DepFunctor<float>{}[1.0f];
+  int y = DepFunctor<bool>{}[true];
+}
+
+// CHECK:      define {{.*}}test_dep_functors{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:        %call = call noundef i32 {{.*}}DepFunctor{{.*}}(float noundef 1.000000e+00)
+// CHECK:        %call1 = call noundef i32 {{.*}}DepFunctor{{.*}}(i1 noundef zeroext true)
+// CHECK:        ret void
+// CHECK-NEXT: }
Index: clang/test/CXX/over/over.oper/p7.cpp
===================================================================
--- clang/test/CXX/over/over.oper/p7.cpp
+++ clang/test/CXX/over/over.oper/p7.cpp
@@ -5,14 +5,19 @@
 
 struct Functor {
   static int operator()(int a, int b);
-  // cxx11-warning@-1 {{is a C++2b extension}}
-  // precxx2b-warning@-2 {{declaring overloaded 'operator()' as 'static' is a C++2b extension}}
+  static int operator[](int a1);
+  // cxx11-warning@-2 {{is a C++2b extension}}
+  // cxx11-warning@-2 {{is a C++2b extension}}
+  // precxx2b-warning@-4 {{declaring overloaded 'operator()' as 'static' is a C++2b extension}}
+  // precxx2b-warning@-4 {{declaring overloaded 'operator[]' as 'static' is a C++2b extension}}
 };
 
 struct InvalidParsing1 {
   extern int operator()(int a, int b);  // expected-error {{storage class specified}}
+  extern int operator[](int a1);  // expected-error {{storage class specified}}
 };
 
 struct InvalidParsing2 {
   extern static int operator()(int a, int b);  // expected-error {{storage class specified}} // expected-error {{cannot combine with previous 'extern' declaration specifier}}
+  extern static int operator[](int a);  // expected-error {{storage class specified}} // expected-error {{cannot combine with previous 'extern' declaration specifier}}
 };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -15993,10 +15993,10 @@
   //       function allowed to be static is the call operator function.
   if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(FnDecl)) {
     if (MethodDecl->isStatic()) {
-      if (Op == OO_Call)
+      if (Op == OO_Call || Op == OO_Subscript)
         Diag(FnDecl->getLocation(),
              (LangOpts.CPlusPlus2b ? diag::ext_operator_overload_static
-                                   : diag::err_call_operator_overload_static))
+                                   : diag::err_future_operator_overload_static))
             << FnDecl;
       else
         return Diag(FnDecl->getLocation(), diag::err_operator_overload_static)
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -695,7 +695,7 @@
     Builder.defineMacro("__cpp_implicit_move", "202011L");
     Builder.defineMacro("__cpp_size_t_suffix", "202011L");
     Builder.defineMacro("__cpp_if_consteval", "202106L");
-    Builder.defineMacro("__cpp_multidimensional_subscript", "202110L");
+    Builder.defineMacro("__cpp_multidimensional_subscript", "202211L");
   }
 
   // We provide those C++2b features as extensions in earlier language modes, so
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9111,7 +9111,7 @@
 def ext_operator_overload_static : ExtWarn<
   "declaring overloaded %0 as 'static' is a C++2b extension">,
   InGroup<CXXPre2bCompat>, DefaultIgnore;
-def err_call_operator_overload_static : ExtWarn<
+def err_future_operator_overload_static : ExtWarn<
   "declaring overloaded %0 as 'static' is a C++2b extension">, InGroup<CXX2b>;
 def err_operator_overload_static : Error<
   "overloaded %0 cannot be a static member function">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -648,7 +648,7 @@
 ^^^^^^^^^^^^^^^^^^^^^
 
 - Support label at end of compound statement (`P2324 <https://wg21.link/p2324r2>`_).
-- Implemented `P1169R4: static operator() <https://wg21.link/P1169R4>`_.
+- Implemented `P1169R4: static operator() <https://wg21.link/P1169R4>`_ and `P2589R1: static operator[] <https://wg21.link/P2589R1>`_.
 - Implemented "char8_t Compatibility and Portability Fix" (`P2513R3 <https://wg21.link/P2513R3>`_).
   This Change was applied to C++20 as a Defect Report.
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to