// RUN: %clang_cc1 -std=c++23 %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s // RUN: %clang_cc1 -std=c++23 %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s struct Functor { static int operator[](int x, int y) { return x + y; } }; Functor GetAFunctor() { return {}; } void call_static_subscript_operator() { Functor f; f[101, 102]; f.operator[](201, 202); Functor{}[301, 302]; Functor::operator[](401, 402); GetAFunctor()[501, 502]; } // 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: {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 401, i32 noundef 402) // CHECK: {{.*}}call {{.*}}GetAFunctor{{.*}}() // CHECK-NEXT: {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 501, i32 noundef 502) // 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 noundef i32 {{.*}}DepFunctor{{.*}}(float noundef 1.000000e+00) // CHECK: {{.*}} = call noundef i32 {{.*}}DepFunctor{{.*}}(i1 noundef zeroext true) // CHECK: ret void // CHECK-NEXT: }