https://gcc.gnu.org/g:20e31f507a2dd6cbd40cc65a7c06d07bfaa2a5e1

commit r16-6-g20e31f507a2dd6cbd40cc65a7c06d07bfaa2a5e1
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Mar 24 12:59:39 2025 -0400

    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.

Diff:
---
 gcc/cp/semantics.cc                                    | 18 ++++++++++++++----
 gcc/testsuite/g++.dg/cpp26/pack-indexing2.C            |  6 +++---
 gcc/testsuite/g++.dg/ext/type_pack_element2.C          |  2 +-
 gcc/testsuite/g++.dg/ext/type_pack_element4.C          |  2 +-
 .../testsuite/20_util/tuple/element_access/get_neg.cc  |  2 +-
 5 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a10ef34383c2..7f23efd4a11e 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -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));
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
index fdc8320e2555..4a7e494ab043 100644
--- a/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
@@ -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; }
diff --git a/gcc/testsuite/g++.dg/ext/type_pack_element2.C 
b/gcc/testsuite/g++.dg/ext/type_pack_element2.C
index 1bf77534097f..1b076733d97d 100644
--- a/gcc/testsuite/g++.dg/ext/type_pack_element2.C
+++ b/gcc/testsuite/g++.dg/ext/type_pack_element2.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/ext/type_pack_element4.C 
b/gcc/testsuite/g++.dg/ext/type_pack_element4.C
index aa508c79090b..5a391947c7be 100644
--- a/gcc/testsuite/g++.dg/ext/type_pack_element4.C
+++ b/gcc/testsuite/g++.dg/ext/type_pack_element4.C
@@ -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) {
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc 
b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
index 48628a98884b..18d47d266ce8 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
@@ -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" }

Reply via email to