https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124243
Bug ID: 124243
Summary: [reflection] internal compiler error: in
tsubst_splice_expr, at cp/pt.cc:16816
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: mpolacek at gcc dot gnu.org
Target Milestone: ---
This tracks the TODO in serialize2.C.
```
#include <meta>
#include <cstdlib>
namespace impl {
template <auto... vals>
struct replicator_type {
template <typename F>
constexpr void operator >> (F body) const
{ (body.template operator()<vals>(), ...); }
};
template <auto... vals>
replicator_type <vals...> replicator = {};
}
template <typename R>
consteval auto
expand (R range)
{
std::vector <std::meta::info> args;
for (auto r : range)
args.push_back (std::meta::reflect_constant (r));
return substitute (^^impl::replicator, args);
}
struct Person {
std::string name;
int age;
};
template <typename S>
constexpr std::string
serialize (S s)
{
std::string result = " ";
#if 01
// TODO, this ICEs in tsubst_expr.
impl::replicator <^^S::age, ^^S::name> >> [&] <auto m> {
#else
impl::replicator <^^Person::age, ^^Person::name> >> [&] <auto m> {
#endif
result += identifier_of (m);
result += "=";
if constexpr (type_of (m) == ^^int)
result += std::string (s.[: m :] / 10, 'X');
else
result += s.[: m :];
result += " ";
};
return result;
}
constexpr Person john { "John", 42 };
static_assert (serialize (john) == " age=XXXX name=John ");
int
main ()
{
Person jack { "Jack", 53 };
std::string s = serialize (jack);
if (s != " age=XXXXX name=Jack ")
std::abort ();
}
```
results in:
serialize2.C:58:26: in ‘constexpr’ expansion of
‘serialize<Person>(Person(john))’
58 | static_assert (serialize (john) == " age=XXXX name=John ");
| ~~~~~~~~~~^~~~~~
serialize2.C:47:5: error: uncaught exception of type ‘std::meta::exception’;
‘what()’: ‘reflection does not have a type’
47 | if constexpr (type_of (m) == ^^int)
| ^~
serialize2.C:48:35: internal compiler error: in tsubst_splice_expr, at
cp/pt.cc:16816
48 | result += std::string (s.[: m :] / 10, 'X');
| ~~~^~~~
0x3197e46 internal_error(char const*, ...)
/home/mpolacek/src/gcc/gcc/diagnostic-global-context.cc:787
0x31a6751 fancy_abort(char const*, int, char const*)
/home/mpolacek/src/gcc/gcc/diagnostics/context.cc:1812
0x7f8bb1 tsubst_splice_expr
/home/mpolacek/src/gcc/gcc/cp/pt.cc:16816
0x81f4a4 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:23137
0x7fd5c7 tsubst_name
/home/mpolacek/src/gcc/gcc/cp/pt.cc:17811
0x81a591 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:22407
0x81503b tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:21536
0x7f7ca4 tsubst_tree_list(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:16695
0x81a3e6 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:22384
0x814633 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:21398
0x812d02 tsubst_call_args
/home/mpolacek/src/gcc/gcc/cp/pt.cc:21125
0x817e95 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:22016
0x813dc2 tsubst_expr(tree_node*, tree_node*, int, tree_node*)
/home/mpolacek/src/gcc/gcc/cp/pt.cc:21310
0x810695 tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:20639
0x8068fb tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:19430
0x80a16f tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:19833
0x809e4e tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:19802
0x806770 tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:19412
0x80a16f tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:19833
0x806770 tsubst_stmt
/home/mpolacek/src/gcc/gcc/cp/pt.cc:19412