Author: Corentin Jabot Date: 2023-05-02T21:22:03+02:00 New Revision: 2528f1c84588f4a549c12dd1435cbba4a502a077
URL: https://github.com/llvm/llvm-project/commit/2528f1c84588f4a549c12dd1435cbba4a502a077 DIFF: https://github.com/llvm/llvm-project/commit/2528f1c84588f4a549c12dd1435cbba4a502a077.diff LOG: [Clang] Correctly expand pack in binary subscript expression. When constructing an array expression where the index expression was a pack expansion, we would construct an ArraySubscriptExpr instead of an CreateOverloadedArraySubscriptExpr, and pack expansion would not occur - leading a crash during code gen or a failure during constant evaluation Reviewed By: erichkeane, shafik Differential Revision: https://reviews.llvm.org/D149637 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/cxx2b-overloaded-operator.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d90a2b53eb616..8d0a9c96a9579 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -386,6 +386,7 @@ Bug Fixes to C++ Support - Fix overly aggressive lifetime checks for parenthesized aggregate initialization. (`#61567 <https://github.com/llvm/llvm-project/issues/61567>`_) +- Fix a crash when expanding a pack as the index of a subscript expression. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4edaf6970a2d7..8789e4c3cb25f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4924,7 +4924,8 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, // Build an unanalyzed expression if either operand is type-dependent. if (getLangOpts().CPlusPlus && ArgExprs.size() == 1 && (base->isTypeDependent() || - Expr::hasAnyTypeDependentArguments(ArgExprs))) { + Expr::hasAnyTypeDependentArguments(ArgExprs)) && + !isa<PackExpansionExpr>(ArgExprs[0])) { return new (Context) ArraySubscriptExpr( base, ArgExprs.front(), getDependentArraySubscriptType(base, ArgExprs.front(), getASTContext()), @@ -4958,7 +4959,8 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, // to overload resolution and so should not take this path. if (getLangOpts().CPlusPlus && !base->getType()->isObjCObjectPointerType() && ((base->getType()->isRecordType() || - (ArgExprs.size() != 1 || ArgExprs[0]->getType()->isRecordType())))) { + (ArgExprs.size() != 1 || isa<PackExpansionExpr>(ArgExprs[0]) || + ArgExprs[0]->getType()->isRecordType())))) { return CreateOverloadedArraySubscriptExpr(lbLoc, rbLoc, base, ArgExprs); } diff --git a/clang/test/SemaCXX/cxx2b-overloaded-operator.cpp b/clang/test/SemaCXX/cxx2b-overloaded-operator.cpp index f9a83c813dcf0..47218e1f2dab5 100644 --- a/clang/test/SemaCXX/cxx2b-overloaded-operator.cpp +++ b/clang/test/SemaCXX/cxx2b-overloaded-operator.cpp @@ -73,3 +73,47 @@ struct T2 { static_assert(T2{}[] == 1); static_assert(T2{}[1] == 2); static_assert(T2{}[1, 1] == 3); + +namespace test_packs { + +struct foo_t { +template<typename... Ts> +constexpr int operator[](Ts... idx) { + return (0 + ... + idx); +} +}; + +template<int... Is> +constexpr int cxx_subscript() { + foo_t foo; + return foo[Is...]; +} + +template<int... Is> +int cxx_subscript_unexpanded() { + foo_t foo; + return foo[Is]; // expected-error {{expression contains unexpanded parameter pack 'Is'}} +} + +template<int... Is> +constexpr int c_array() { + int arr[] = {1, 2, 3}; + return arr[Is...]; // expected-error 2{{type 'int[3]' does not provide a subscript operator}} +} + +template<int... Is> +int c_array_unexpanded() { + int arr[] = {1, 2, 3}; + return arr[Is]; // expected-error {{expression contains unexpanded parameter pack 'Is'}} +} + +void test() { + static_assert(cxx_subscript<1, 2, 3>() == 6); + static_assert(c_array<1>() == 2); + + c_array<>(); // expected-note {{in instantiation}} + c_array<1>(); + c_array<1, 2>(); // expected-note {{in instantiation}} +} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits