royjacobson updated this revision to Diff 476975.
royjacobson added a comment.

1. Update warnings according to Corentin's comment
2. Somehow I missed the CodeGen was completely broken. Made a few necessary 
follow up changes in SemaOverload and ran the tests this time...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138387/new/

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/lib/Sema/SemaOverload.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 {{declaring overloaded 'operator()' as 'static' is a C++2b extension}}
+  // cxx11-warning@-2 {{declaring overloaded 'operator[]' as 'static' is a C++2b extension}}
+  // precxx2b-warning@-4 {{incompatible with C++ standards before C++2b}}
+  // precxx2b-warning@-4 {{incompatible with C++ standards before C++2b}}
 };
 
 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/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -14425,12 +14425,17 @@
         // Convert the arguments.
         CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
         SmallVector<Expr *, 2> MethodArgs;
-        ExprResult Arg0 = PerformObjectArgumentInitialization(
-            Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method);
-        if (Arg0.isInvalid())
-          return ExprError();
 
-        MethodArgs.push_back(Arg0.get());
+        // Handle 'this' parameter if the selected function is not static.
+        if (Method->isInstance()) {
+          ExprResult Arg0 = PerformObjectArgumentInitialization(
+              Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method);
+          if (Arg0.isInvalid())
+            return ExprError();
+
+          MethodArgs.push_back(Arg0.get());
+        }
+
         bool IsError = PrepareArgumentsForCallToObjectOfClassType(
             *this, MethodArgs, Method, ArgExpr, LLoc);
         if (IsError)
@@ -14450,9 +14455,16 @@
         ExprValueKind VK = Expr::getValueKindForType(ResultTy);
         ResultTy = ResultTy.getNonLValueExprType(Context);
 
-        CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
-            Context, OO_Subscript, FnExpr.get(), MethodArgs, ResultTy, VK, RLoc,
-            CurFPFeatureOverrides());
+        CallExpr *TheCall;
+        if (Method->isInstance())
+          TheCall = CXXOperatorCallExpr::Create(
+              Context, OO_Subscript, FnExpr.get(), MethodArgs, ResultTy, VK,
+              RLoc, CurFPFeatureOverrides());
+        else
+          TheCall =
+              CallExpr::Create(Context, FnExpr.get(), MethodArgs, ResultTy, VK,
+                               RLoc, CurFPFeatureOverrides());
+
         if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
           return ExprError();
 
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -15993,10 +15993,11 @@
   //       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))
+             (LangOpts.CPlusPlus2b
+                  ? diag::warn_cxx20_compat_operator_overload_static
+                  : diag::ext_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
@@ -9108,10 +9108,10 @@
   "or enumeration type">;
 
 def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
+def warn_cxx20_compat_operator_overload_static : Warning<
+  "declaring overloaded %0 as 'static' is incompatible with C++ standards "
+  "before C++2b">, InGroup<CXXPre2bCompat>, DefaultIgnore;
 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<
   "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