c++: improve pack index diagnostics

While looking at pack-indexing16.C I thought it would be helpful to print
the problematic type/value.

gcc/cp/ChangeLog:

	* semantics.cc (finish_type_pack_element): Add more info
	to diagnostics.

libstdc++-v3/ChangeLog:

	* testsuite/20_util/tuple/element_access/get_neg.cc: Adjust
	diagnostic.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp26/pack-indexing2.C: Adjust diagnostics.
	* g++.dg/ext/type_pack_element2.C: Likewise.
	* g++.dg/ext/type_pack_element4.C: Likewise.
This commit is contained in:
Jason Merrill 2025-03-24 12:59:39 -04:00
parent eff4dc4233
commit 20e31f507a
5 changed files with 20 additions and 10 deletions

View file

@ -5088,22 +5088,32 @@ static tree
finish_type_pack_element (tree idx, tree types, tsubst_flags_t complain)
{
idx = maybe_constant_value (idx, NULL_TREE, mce_true);
if (TREE_CODE (idx) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (idx)))
if (!INTEGRAL_TYPE_P (TREE_TYPE (idx)))
{
if (complain & tf_error)
error ("pack index is not an integral constant");
error ("pack index has non-integral type %qT", TREE_TYPE (idx));
return error_mark_node;
}
if (TREE_CODE (idx) != INTEGER_CST)
{
if (complain & tf_error)
{
error ("pack index is not an integral constant");
cxx_constant_value (idx);
}
return error_mark_node;
}
if (tree_int_cst_sgn (idx) < 0)
{
if (complain & tf_error)
error ("pack index is negative");
error ("pack index %qE is negative", idx);
return error_mark_node;
}
if (wi::to_widest (idx) >= TREE_VEC_LENGTH (types))
{
if (complain & tf_error)
error ("pack index is out of range");
error ("pack index %qE is out of range for pack of length %qd",
idx, TREE_VEC_LENGTH (types));
return error_mark_node;
}
return TREE_VEC_ELT (types, tree_to_shwi (idx));

View file

@ -49,7 +49,7 @@ template<int N>
int
getT2 (auto... Ts)
{
return Ts...[N]; // { dg-error "pack index is negative" }
return Ts...[N]; // { dg-error "pack index '-1' is negative" }
}
template<auto N, typename... Ts>
@ -63,7 +63,7 @@ template<auto N, typename... Ts>
void
badtype2 ()
{
Ts...[N] t; // { dg-error "pack index is out of range" }
Ts...[N] t; // { dg-error "pack index '1' is out of range for pack of length '1'" }
}
template<auto N, typename... Ts>
@ -77,7 +77,7 @@ template<auto N, typename... Ts>
void
badtype4 ()
{
Ts...[N] t; // { dg-error "pack index is negative" }
Ts...[N] t; // { dg-error "pack index '-1' is negative" }
}
int nonconst () { return 42; }

View file

@ -2,7 +2,7 @@
int p;
using type = __type_pack_element<&p, int>; // { dg-error "not an integral constant" }
using type = __type_pack_element<&p, int>; // { dg-error "non-integral type" }
using type = __type_pack_element<1, int>; // { dg-error "out of range" }
using type = __type_pack_element<2, int, char>; // { dg-error "out of range" }
using type = __type_pack_element<-1, int>; // { dg-error "negative" }

View file

@ -3,7 +3,7 @@
template <typename... _Elements> class tuple{};
template <unsigned long __i, typename... _Elements>
__type_pack_element<__i, _Elements...> &get(tuple<_Elements...> &__t) noexcept; // { dg-error "index is out of range" }
__type_pack_element<__i, _Elements...> &get(tuple<_Elements...> &__t) noexcept; // { dg-error "out of range" }
tuple<int,int> data;
template <unsigned long Level>
unsigned take_impl(unsigned idx) {

View file

@ -61,4 +61,4 @@ test03()
// { dg-error "tuple index must be in range" "" { target *-*-* } 0 }
// { dg-prune-output "no type named 'type' in .*_Nth_type" }
// { dg-prune-output "pack index is out of range" }
// { dg-prune-output "pack index '.' is out of range" }