Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -2675,13 +2675,11 @@ /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildArraySubscriptExpr(Expr *LHS, - SourceLocation LBracketLoc, - Expr *RHS, - SourceLocation RBracketLoc) { + ExprResult RebuildArraySubscriptExpr(Expr *LHS, SourceLocation LBracketLoc, + MultiExprArg Args, + SourceLocation RBracketLoc) { return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS, - LBracketLoc, RHS, - RBracketLoc); + LBracketLoc, Args, RBracketLoc); } /// Build a new matrix subscript expression. @@ -8584,8 +8582,10 @@ IdxRes.get() == E->getIdx()) return E; - return getDerived().RebuildArraySubscriptExpr( - BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc()); + Expr *IdxExpr = IdxRes.get(); + return getDerived().RebuildArraySubscriptExpr(BaseRes.get(), SourceLocation(), + MultiExprArg(IdxExpr), + E->getRBracketLoc()); } template @@ -11053,19 +11053,21 @@ if (LHS.isInvalid()) return ExprError(); - ExprResult RHS = getDerived().TransformExpr(E->getRHS()); - if (RHS.isInvalid()) + /// During Template instantiation, parameter packs maybe be expanded so even + /// if we have a single LHS in ArraySubscriptExpr we may have multiple or none + /// after pack expansion. + bool ArgChanged = false; + SmallVector Args; + auto RHS = E->getRHS(); + if (getDerived().TransformExprs(&RHS, 1, true, Args, &ArgChanged)) return ExprError(); - - if (!getDerived().AlwaysRebuild() && - LHS.get() == E->getLHS() && - RHS.get() == E->getRHS()) + if (!getDerived().AlwaysRebuild() && LHS.get() == E->getLHS() && !ArgChanged) return E; return getDerived().RebuildArraySubscriptExpr( - LHS.get(), - /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc()); + LHS.get(), /*FIXME:*/ E->getLHS()->getBeginLoc(), Args, + E->getRBracketLoc()); } template Index: clang/test/SemaCXX/cxx2b-overloaded-operator.cpp =================================================================== --- clang/test/SemaCXX/cxx2b-overloaded-operator.cpp +++ clang/test/SemaCXX/cxx2b-overloaded-operator.cpp @@ -73,3 +73,36 @@ static_assert(T2{}[] == 1); static_assert(T2{}[1] == 2); static_assert(T2{}[1, 1] == 3); + +struct A0 { + int operator[](int, int) { return 0; } +}; +A0 a; +template int f(n... i) { + return a[i...]; +} +int variadic() { + f(0, 1); +} + +template struct A1 { + template auto operator[](n... indices) {// expected-note {{'operator[]' declared here}} + return (*this)[indices...]; // expected-error {{function 'operator[]' with deduced return type cannot be used before it is defined}} + } +}; +int variadic1() { + A1<0> a; + if (a[0, 1]) {}// expected-note {{in instantiation of function template specialization 'A1<0>::operator[]' requested here}} +} + +template +int variadic20(n... i) { + int arr[5] = {}; + return arr[i...];// expected-error 2 {{type 'int[5]' does not provide a subscript operator}} +} + +void variadic2() { + variadic20();// expected-note {{in instantiation of function template specialization 'variadic20<>' requested here}} + variadic20(0); + variadic20(1, 2);// expected-note {{in instantiation of function template specialization 'variadic20' requested here}} +}