Author: Younan Zhang Date: 2024-05-01T11:52:14+08:00 New Revision: 410d6350eda322de213941b36adcdab13a0b557b
URL: https://github.com/llvm/llvm-project/commit/410d6350eda322de213941b36adcdab13a0b557b DIFF: https://github.com/llvm/llvm-project/commit/410d6350eda322de213941b36adcdab13a0b557b.diff LOG: [Sema] Avoid an undesired pack expansion while transforming PackIndexingType (#90195) A pack indexing type can appear in a larger pack expansion, e.g `Pack...[pack_of_indexes]...` so we need to temporarily disable substitution of pack elements. Besides, this patch also fixes an assertion failure in `PackIndexingExpr::classify`: dependent `PackIndexingExpr`s are always LValues and thus we don't need to consider their `IndexExpr`s. Fixes https://github.com/llvm/llvm-project/issues/88925 --------- Co-authored-by: cor3ntin <corentinja...@gmail.com> Added: Modified: clang/lib/AST/ExprClassification.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/cxx2c-pack-indexing.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 2bb8f9aeedc7e2..390000e3ed3835 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -216,8 +216,13 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { return ClassifyInternal(Ctx, cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement()); - case Expr::PackIndexingExprClass: + case Expr::PackIndexingExprClass: { + // A pack-index-expression always expands to an id-expression. + // Consider it as an LValue expression. + if (cast<PackIndexingExpr>(E)->isInstantiationDependent()) + return Cl::CL_LValue; return ClassifyInternal(Ctx, cast<PackIndexingExpr>(E)->getSelectedExpr()); + } // C, C++98 [expr.sub]p1: The result is an lvalue of type "T". // C++11 (DR1213): in the case of an array operand, the result is an lvalue diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ababb5d02b5fdb..dff7e9df636b96 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6657,6 +6657,10 @@ TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB, } } + // A pack indexing type can appear in a larger pack expansion, + // e.g. `Pack...[pack_of_indexes]...` + // so we need to temporarily disable substitution of pack elements + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc()); QualType Out = getDerived().RebuildPackIndexingType( diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp index 606715e6aacffd..a3e5a0931491b5 100644 --- a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp +++ b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp @@ -160,3 +160,37 @@ namespace GH88929 { using E = P...[0]; // expected-error {{unknown type name 'P'}} \ // expected-error {{expected ';' after alias declaration}} } + +namespace GH88925 { +template <typename...> struct S {}; + +template <auto...> struct W {}; + +template <int...> struct sequence {}; + +template <typename... args, int... indices> auto f(sequence<indices...>) { + return S<args...[indices]...>(); // #use +} + +template <auto... args, int... indices> auto g(sequence<indices...>) { + return W<args...[indices]...>(); // #nttp-use +} + +void h() { + static_assert(__is_same(decltype(f<int>(sequence<0, 0>())), S<int, int>)); + static_assert(__is_same(decltype(f<int, long>(sequence<0, 0>())), S<int, int>)); + static_assert(__is_same(decltype(f<int, long>(sequence<0, 1>())), S<int, long>)); + f<int, long>(sequence<3>()); + // expected-error@#use {{invalid index 3 for pack 'args' of size 2}}} + // expected-note-re@-2 {{function template specialization '{{.*}}' requested here}} + + struct foo {}; + struct bar {}; + struct baz {}; + + static_assert(__is_same(decltype(g<foo{}, bar{}, baz{}>(sequence<0, 2, 1>())), W<foo{}, baz{}, bar{}>)); + g<foo{}>(sequence<4>()); + // expected-error@#nttp-use {{invalid index 4 for pack args of size 1}} + // expected-note-re@-2 {{function template specialization '{{.*}}' requested here}} +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits