1*c1512250SCorentin Jabot // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx2b -std=c++2b %s
2*c1512250SCorentin Jabot // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s
3*c1512250SCorentin Jabot 
4*c1512250SCorentin Jabot //cxx2b-no-diagnostics
5*c1512250SCorentin Jabot 
6*c1512250SCorentin Jabot struct S {
operator []S7*c1512250SCorentin Jabot   constexpr int operator[](int i) {
8*c1512250SCorentin Jabot     return i;
9*c1512250SCorentin Jabot   }
operator []S10*c1512250SCorentin Jabot   constexpr int operator[](int a, int b) { // cxx20-error {{overloaded 'operator[]' cannot have more than one parameter before C++2b}}
11*c1512250SCorentin Jabot     return a + b;
12*c1512250SCorentin Jabot   }
operator []S13*c1512250SCorentin Jabot   constexpr int operator[]() { // cxx20-error {{overloaded 'operator[]' cannot have no parameter before C++2b}}
14*c1512250SCorentin Jabot     return 42;
15*c1512250SCorentin Jabot   }
16*c1512250SCorentin Jabot };
17*c1512250SCorentin Jabot 
18*c1512250SCorentin Jabot struct Defaults {
operator []Defaults19*c1512250SCorentin Jabot   constexpr int operator[](int i = 0) { // cxx20-error {{overloaded 'operator[]' cannot have a defaulted parameter before C++2b}}
20*c1512250SCorentin Jabot     return 0;
21*c1512250SCorentin Jabot   }
operator []Defaults22*c1512250SCorentin Jabot   constexpr int operator[](int a, int b, int c = 0) { // cxx20-error {{overloaded 'operator[]' cannot have a defaulted parameter before C++2b}}\
23*c1512250SCorentin Jabot                                                          // cxx20-error {{cannot have more than one parameter before C++2b}}
24*c1512250SCorentin Jabot     return 0;
25*c1512250SCorentin Jabot   }
26*c1512250SCorentin Jabot };
27*c1512250SCorentin Jabot 
28*c1512250SCorentin Jabot template <typename... T>
29*c1512250SCorentin Jabot struct T1 {
30*c1512250SCorentin Jabot   constexpr auto operator[](T &&...arg); // cxx20-error {{overloaded 'operator[]' cannot have no parameter before C++2b}} \
31*c1512250SCorentin Jabot                                            // cxx20-error {{overloaded 'operator[]' cannot have more than one parameter before C++2b}}
32*c1512250SCorentin Jabot };
33*c1512250SCorentin Jabot 
34*c1512250SCorentin Jabot T1<> t10;         // cxx20-note {{requested here}}
35*c1512250SCorentin Jabot T1<int, int> t12; // cxx20-note {{requested here}}
36*c1512250SCorentin Jabot T1<int> t11;
37*c1512250SCorentin Jabot 
38*c1512250SCorentin Jabot struct Variadic {
operator []Variadic39*c1512250SCorentin Jabot   constexpr int operator[](auto &&...arg) { return 0; }
40*c1512250SCorentin Jabot };
41*c1512250SCorentin Jabot 
f()42*c1512250SCorentin Jabot void f() {
43*c1512250SCorentin Jabot   S s;
44*c1512250SCorentin Jabot   (void)s[0];
45*c1512250SCorentin Jabot   (void)s[1, 2]; // cxx20-warning {{left operand of comma operator has no effect}}\
46*c1512250SCorentin Jabot                    // cxx20-warning {{top-level comma expression in array subscript is deprecated in C++20 and unsupported in C++2b}}
47*c1512250SCorentin Jabot   (void)S{}[];   // cxx20-error {{expected expression}}
48*c1512250SCorentin Jabot 
49*c1512250SCorentin Jabot   (void)Defaults{}[1];
50*c1512250SCorentin Jabot   (void)Defaults{}[];     // cxx20-error {{expected expression}}
51*c1512250SCorentin Jabot   (void)Defaults{}[1, 2]; // cxx20-warning {{left operand of comma operator has no effect}}\
52*c1512250SCorentin Jabot                             // cxx20-warning {{top-level comma expression in array subscript is deprecated in C++20 and unsupported in C++2b}}
53*c1512250SCorentin Jabot 
54*c1512250SCorentin Jabot   Variadic{}[]; // cxx20-error {{expected expression}}
55*c1512250SCorentin Jabot   Variadic{}[1];
56*c1512250SCorentin Jabot   Variadic{}[1, 2]; // cxx20-warning {{left operand of comma operator has no effect}}\
57*c1512250SCorentin Jabot                        // cxx20-warning {{top-level comma expression in array subscript is deprecated in C++20 and unsupported in C++2b}}
58*c1512250SCorentin Jabot }
59