[PATCH] D149637: [Clang] Correctly expand pack in binary subscript expression.
Corentin Jabot via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue May 2 01:36:50 PDT 2023
cor3ntin created this revision.
Herald added a project: All.
cor3ntin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
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
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D149637
Files:
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/cxx2b-overloaded-operator.cpp
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,47 @@
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}}
+}
+
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4924,7 +4924,8 @@
// 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 @@
// 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);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149637.518650.patch
Type: text/x-patch
Size: 2517 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230502/4faecb8a/attachment.bin>
More information about the cfe-commits
mailing list