diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-09-22 06:27:48 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-09-22 06:27:48 -0400 |
commit | 1fea14def849dd38b098b0e2d54e64801f9c1f43 (patch) | |
tree | 26422a99f7f61119899be23812fd97e30ad663db | |
parent | 6f902a42b0afe3f3145bcb864695fc290b5acc3e (diff) | |
download | gcc-1fea14def849dd38b098b0e2d54e64801f9c1f43.zip gcc-1fea14def849dd38b098b0e2d54e64801f9c1f43.tar.gz gcc-1fea14def849dd38b098b0e2d54e64801f9c1f43.tar.bz2 |
c++: missing SFINAE in grok_array_decl [PR111493]
We should guard both the diagnostic and backward compatibilty fallback
code with tf_error, so that in a SFINAE context we don't issue any
diagnostics and correctly treat ill-formed C++23 multidimensional
subscript operator expressions as such.
PR c++/111493
gcc/cp/ChangeLog:
* decl2.cc (grok_array_decl): Guard diagnostic and backward
compatibility fallback code paths with tf_error.
gcc/testsuite/ChangeLog:
* g++.dg/cpp23/subscript15.C: New test.
-rw-r--r-- | gcc/cp/decl2.cc | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp23/subscript15.C | 25 |
2 files changed, 37 insertions, 3 deletions
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 113b031..344e19e 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -459,7 +459,10 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp, { 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); @@ -510,6 +513,11 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp, 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 " @@ -561,8 +569,9 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp, 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; } diff --git a/gcc/testsuite/g++.dg/cpp23/subscript15.C b/gcc/testsuite/g++.dg/cpp23/subscript15.C new file mode 100644 index 0000000..fece96b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/subscript15.C @@ -0,0 +1,25 @@ +// 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>); |