diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -648,7 +648,7 @@ ^^^^^^^^^^^^^^^^^^^^^ - Support label at end of compound statement (`P2324 `_). -- Implemented `P1169R4: static operator() `_. +- Implemented `P1169R4: static operator() `_ and `P2589R1: static operator[] `_. - Implemented "char8_t Compatibility and Portability Fix" (`P2513R3 `_). This Change was applied to C++20 as a Defect Report. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/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, 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; def err_operator_overload_static : Error< "overloaded %0 cannot be a static member function">; diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/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 diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -15993,10 +15993,10 @@ // function allowed to be static is the call operator function. if (CXXMethodDecl *MethodDecl = dyn_cast(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) diff --git a/clang/test/CXX/over/over.oper/p7.cpp b/clang/test/CXX/over/over.oper/p7.cpp --- a/clang/test/CXX/over/over.oper/p7.cpp +++ b/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}} }; diff --git a/clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp b/clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp new file mode 100644 --- /dev/null +++ b/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 +struct DepFunctor { + static int operator[](T t) { + return int(t); + } +}; + +void test_dep_functors() { + int x = DepFunctor{}[1.0f]; + int y = DepFunctor{}[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: } diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp --- a/clang/test/Lexer/cxx-features.cpp +++ b/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 diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -1518,7 +1518,7 @@ static operator[] P2589R1 - No + 16 Permitting static constexpr variables in constexpr functions (DR)