Hi,

In r16-8662-g2cdd7831e31601, a new test was added that experience the same kind 
of issue that was addressed in this patch.

The following snippet allows the new test to work the same way as for the other 
2 tests:

diff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_array11.C 
b/gcc/testsuite/g++.dg/reflect/reflect_constant_array11.C
index 044a2a0d2a6..b3e01f911ec 100644
--- a/gcc/testsuite/g++.dg/reflect/reflect_constant_array11.C
+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_array11.C
@@ -11,7 +11,7 @@ using namespace std::meta;
 struct A { int a, b; mutable int c; };
 constexpr A aa[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
 constexpr auto a = reflect_constant_array (aa);
-// { dg-error "'reflect_constant_array' argument with 'std::ranges::range_value_t<const A 
\\\[2\\\]>' \\\{aka 'A'\\\} which is not a structural type" "" { target *-*-* } .-1 }
+// { dg-error "'reflect_constant_array' argument with 'std::ranges::range_value_t<const A 
\\\[2\\\]>' \\\{aka '(A|std::iter_value_t<const A\\\*>)'\\\} which is not a structural type" 
"" { target *-*-* } .-1 }
 struct B { constexpr B (int x, int y) : a (x), b (y) {} constexpr ~B () {} B 
(const B &) = delete; int a, b; };
 constexpr B b[2][2] = { { { 1, 2 }, { 2, 3 } }, { { 3, 4 }, { 4, 5 } } };
 constexpr auto c = reflect_constant_array (b);


Is this a feasible route to go or is there some work to be done in the compiler 
to avoid the 2 different error messages?


Kind regards,
Torbjörn

On 2026-04-03 23:37, Jason Merrill wrote:
On 3/25/26 7:00 AM, Jakub Jelinek wrote:
Hi!

These two tests behave differently when using in-tree testing vs.
out-of-tree testing.
In the former case, libstdc++-v3/scripts/testsuite_flags uses
-nostdinc++ -I.../libstdc++-v3/include/x86_64-pc-linux-gnu etc.,
so the libstdc++ headers aren't considered system headers, while
with out-of-tree testing they are.
And the aka printing uses user_facing_original_type_p which depends on
   /* Look through any typedef in "user" code.  */
   if (!DECL_IN_SYSTEM_HEADER (decl) && !DECL_IS_UNDECLARED_BUILTIN (decl))
     return true;
and so behaves differently (and arguably in this case the non-system headers
output is nicer).

It definitely is.  I think this demonstrates that strip_typedefs needs to look 
further through a chain of typedefs to see if the actual underlying type is 
user-facing rather than get hung up on an intermediate typedef.

Anyway, the following patch adjusts the tests so that they accept both
forms.

Tested on x86_64-linux in-tree and Torbjorn has tested it in arm-none-eabi
out-of-tree testing.  Ok for trunk?

2026-03-25  Jakub Jelinek  <[email protected]>

    PR testsuite/124621
    * g++.dg/reflect/reflect_constant_array2.C: Allow different aka
    argument in diagnostics for in-tree vs. out-of-tree testing.
    * g++.dg/reflect/reflect_constant_string2.C: Likewise.

--- gcc/testsuite/g++.dg/reflect/reflect_constant_array2.C.jj    2026-01-15 
16:33:47.014097840 +0100
+++ gcc/testsuite/g++.dg/reflect/reflect_constant_array2.C    2026-03-25 
11:27:34.568796335 +0100
@@ -10,8 +10,8 @@ using namespace std::meta;
  struct A { int a, b; mutable int c; };
  constexpr auto a = reflect_constant_array (std::vector <A> { A { 1, 2, 3 } });
-// { dg-error "'reflect_constant_array' argument with 'std::ranges::range_value_t<std::vector<A> 
>' \\\{aka 'A'\\\} which is not a structural type" "" { target *-*-* } .-1 }
+// { dg-error "'reflect_constant_array' argument with 'std::ranges::range_value_t<std::vector<A> >' \\\{aka 
'(A|std::iter_value_t<__gnu_cxx::__normal_iterator<A\\\*, std::vector<A> > >)'\\\} which is not a structural 
type" "" { target *-*-* } .-1 }
  struct B { constexpr B (int x, int y) : a (x), b (y) {} constexpr ~B () {} B 
(const B &) = delete; int a, b; };
  constexpr B b[2] = { { 1, 2 }, { 2, 3 } };
  constexpr auto c = reflect_constant_array (b);
-// { dg-error "'reflect_constant_array' argument with 'std::ranges::range_value_t<const B 
\\\[2\\\]>' \\\{aka 'B'\\\} which is not copy constructible" "" { target *-*-* } .-1 }
+// { dg-error "'reflect_constant_array' argument with 'std::ranges::range_value_t<const B 
\\\[2\\\]>' \\\{aka '(B|std::iter_value_t<const B\\\*>)'\\\} which is not copy constructible" 
"" { target *-*-* } .-1 }
--- gcc/testsuite/g++.dg/reflect/reflect_constant_string2.C.jj    2026-01-15 
16:33:47.015097823 +0100
+++ gcc/testsuite/g++.dg/reflect/reflect_constant_string2.C    2026-03-25 
11:28:21.181009946 +0100
@@ -11,4 +11,4 @@ using namespace std::meta;
  struct V { int a, b, c; };
  constexpr auto a = reflect_constant_string (std::vector <int> { 42, 43, 44 });    // { dg-error 
"'reflect_constant_string' called with 'std::ranges::range_value_t<std::vector<int> >' 
\\\{aka 'int'\\\} rather than 'char', 'wchar_t', 'char8_t', 'char16_t' or 'char32_t'" }
  constexpr auto b = reflect_constant_string (std::vector <float> {});        // { dg-error 
"'reflect_constant_string' called with 'std::ranges::range_value_t<std::vector<float> >' 
\\\{aka 'float'\\\} rather than 'char', 'wchar_t', 'char8_t', 'char16_t' or 'char32_t'" }
-constexpr auto c = reflect_constant_string (std::vector <V> { V { 1, 2, 3 } });    // { dg-error 
"'reflect_constant_string' called with 'std::ranges::range_value_t<std::vector<V> >' 
\\\{aka 'V'\\\} rather than 'char', 'wchar_t', 'char8_t', 'char16_t' or 'char32_t'" }
+constexpr auto c = reflect_constant_string (std::vector <V> { V { 1, 2, 3 } });    // { dg-error 
"'reflect_constant_string' called with 'std::ranges::range_value_t<std::vector<V> >' \\\{aka 
'(V|std::iter_value_t<__gnu_cxx::__normal_iterator<V\\\*, std::vector<V> > >)'\\\} rather than 'char', 
'wchar_t', 'char8_t', 'char16_t' or 'char32_t'" }

    Jakub



Reply via email to