https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125423
Bug ID: 125423
Summary: [17 Regression] ICE in tsubst_expr, at cp/pt.cc with
C++26 reflection (missing TREE_BINFO handling during
lambda tsubst)
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: berningchen at gmail dot com
Target Milestone: ---
Created attachment 64532
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64532&action=edit
Preprocessed source
=== GCC Version & Environment ===
- GCC Version: 17.0.0 (Experimental P2996 branch, trunk snapshot 20260522)
- Target: x86_64-linux-gnu
- Options: -std=c++26 -freflection
=== Minimal Reproducible Example ===
#include <meta>
struct Base
{
};
struct Derived : Base
{
};
template <typename Tp, Tp v> struct get_type
{
inline constexpr static auto info = ^^void;
};
template <std::meta::info base> struct get_type<std::meta::info, base>
{
inline constexpr static auto info = std::meta::type_of(base);
};
template <std::meta::info currField> struct ReflectionSubPanel
{
static constexpr auto _ranges = []()
{
constexpr auto b = std::meta::bases_of(^^Derived,
std::meta::access_context::unchecked())[0];
return get_type<decltype(b), b>::info;
}();
};
int main() { ReflectionSubPanel<^^Derived> panel; }
<source>: In instantiation of 'constexpr const auto
ReflectionSubPanel<^^Derived>::_ranges':
<source>:22:27: required from 'struct ReflectionSubPanel<^^Derived>'
22 | static constexpr auto _ranges = []()
| ^~~~~~~
<source>:29:44: required from here
29 | int main() { ReflectionSubPanel<^^Derived> panel; }
| ^~~~~
<source>:24:47: internal compiler error: in tsubst_expr, at cp/pt.cc:23403
24 | constexpr auto b = std::meta::bases_of(^^Derived,
std::meta::access_context::unchecked())[0];
|
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x29e12e8 diagnostics::context::diagnostic_impl(rich_location*,
diagnostics::metadata const*, diagnostics::option_id, char const*,
__va_list_tag (*) [1], diagnostics::kind)
???:0
0x29d5f2b internal_error(char const*, ...)
???:0
0xb2fe3e fancy_abort(char const*, int, char const*)
???:0
0xdac66d tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*)
???:0
0xde722d instantiate_decl(tree_node*, bool, bool)
???:0
0xc41bf7 cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int,
cp_decomp*)
???:0
0xc52e5e finish_static_data_member_decl(tree_node*, tree_node*, bool,
tree_node*, int)
???:0
0xdef3b0 instantiate_class_template(tree_node*)
???:0
0xc0e2dd start_decl_1(tree_node*, bool)
???:0
0xc3326d start_decl(cp_declarator const*, cp_decl_specifier_seq*, int,
tree_node*, tree_node*, tree_node**)
???:0
0xd82dd3 c_parse_file()
???:0
0xf11ce9 c_common_parse_file()
???:0
/cefs/61/615d2debb21166bafb7bf798_gcc-trunk-20260522/bin/../libexec/gcc/x86_64-linux-gnu/17.0.0/cc1plus
-quiet -imultiarch x86_64-linux-gnu -iprefix
/cefs/61/615d2debb21166bafb7bf798_gcc-trunk-20260522/bin/../lib/gcc/x86_64-linux-gnu/17.0.0/
-D_GNU_SOURCE <source> -quiet -dumpdir /app/output.s- -dumpbase example.cpp
-dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -std=c++26
-fdiagnostics-color=always -fno-verbose-asm -freflection -freport-bug -o
/tmp/ccCCKYbj.s
"
case REFLECT_EXPR:
{
tree h = REFLECT_EXPR_HANDLE (t);
reflect_kind kind = REFLECT_EXPR_KIND (t);
if (TYPE_P (h) || TREE_CODE (h) == NAMESPACE_DECL)
h = tsubst (h, args, complain, in_decl);
else if (kind == REFLECT_ANNOTATION)
/* annotations_of should be called on reflections of already
instantiated entities and so no need to tsubst the annotation
attribute and we rely on pointer equality of that. */
;
else if (TREE_CODE (h) == SCOPE_REF)
h = tsubst_qualified_id (h, args, complain, in_decl,
/*done=*/true, /*address_p=*/false,
/*reflecting_p=*/true);
else
{
/* [expr.reflect] The id-expression of a reflect-expression is
an unevaluated operand. */
cp_unevaluated u;
h = RECUR (h);
}
" in "tree tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree
in_decl)" in cp/pt.cc
When the TREE_CODE of h is binfo, it will enter the recursion "tree tsubst_expr
(tree t, tree args, tsubst_flags_t complain, tree in_decl)". This can be
handled normally for field declarations, but for binfo, due to the lack of
processing for this type of tree, it will directly reach the default case in
the switch, resulting in an error.