{
expr = build_op_subscript (loc, array_expr, index_exp_list,
&overload, complain & tf_decltype);
- if (expr == error_mark_node)
+ if (expr == error_mark_node
+ /* Don't do the backward compatibility fallback in a SFINAE
+ context. */
+ && (complain & tf_error))
{
tree idx = build_x_compound_expr_from_vec (*index_exp_list, NULL,
tf_none);
if (index_exp == NULL_TREE)
{
+ if (!(complain & tf_error))
+ /* Don't do the backward compatibility fallback in a SFINAE
+ context. */
+ return error_mark_node;
+
if ((*index_exp_list)->is_empty ())
{
error_at (loc, "built-in subscript operator without expression "
swapped = true, array_expr = p2, index_exp = i1;
else
{
- error_at (loc, "invalid types %<%T[%T]%> for array subscript",
- type, TREE_TYPE (index_exp));
+ if (complain & tf_error)
+ error_at (loc, "invalid types %<%T[%T]%> for array subscript",
+ type, TREE_TYPE (index_exp));
return error_mark_node;
}
--- /dev/null
+// PR c++/111493
+// { dg-do compile { target c++23 } }
+
+template<class T, class... Ts>
+concept CartesianIndexable = requires(T t, Ts... ts) { t[ts...]; };
+
+static_assert(!CartesianIndexable<int>);
+static_assert(!CartesianIndexable<int, int>);
+static_assert(!CartesianIndexable<int, int, int>);
+
+static_assert(!CartesianIndexable<int*>);
+static_assert(CartesianIndexable<int*, int>);
+static_assert(!CartesianIndexable<int*, int, int>);
+static_assert(!CartesianIndexable<int*, int*>);
+
+template<class... Ts>
+struct A {
+ void operator[](Ts...);
+};
+
+static_assert(!CartesianIndexable<A<>, int>);
+static_assert(CartesianIndexable<A<int>, int>);
+static_assert(!CartesianIndexable<A<int>>);
+static_assert(!CartesianIndexable<A<int>, int, int>);
+static_assert(CartesianIndexable<A<int, int>, int, int>);