On 5/7/26 4:17 PM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16.2?
OK.
-- >8 -- Here we crash in strip_typedefs_expr because we recurse on a REFLECT_EXPR with TREE_BINFO as its operand, which is not a code this function handles. It seems to me that we don't need to recurse for REFLECT_EXPRs at all. Alternatively, we could just handle TREE_BINFO. PR c++/125206 gcc/cp/ChangeLog: * tree.cc (strip_typedefs_expr) <case REFLECT_EXPR>: Always return instead of recursing. gcc/testsuite/ChangeLog: * g++.dg/reflect/bases_of4.C: New test. --- gcc/cp/tree.cc | 7 ++-- gcc/testsuite/g++.dg/reflect/bases_of4.C | 45 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/reflect/bases_of4.C diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index c510a5bf2d0..2e96d65eecd 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -2155,12 +2155,9 @@ strip_typedefs_expr (tree t, bool *remove_attributes, unsigned int flags)case LAMBDA_EXPR:case STMT_EXPR: - return t; - + /* ^^alias represents the alias itself, not the underlying type. */ case REFLECT_EXPR: - /* ^^alias represents the alias itself, not the underlying type. */ - if (TYPE_P (REFLECT_EXPR_HANDLE (t))) - return t; + return t;default:break; diff --git a/gcc/testsuite/g++.dg/reflect/bases_of4.C b/gcc/testsuite/g++.dg/reflect/bases_of4.C new file mode 100644 index 00000000000..843f0e53c4e --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/bases_of4.C @@ -0,0 +1,45 @@ +// PR c++/125206 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +#include <meta> +#include <type_traits> + +template<auto...> struct mp_list_v +{ +}; + +template<class...> struct mp_list +{ +}; + +template<auto V> using mp_value = std::integral_constant<decltype(V), V>; + +template<class L, template<class...> class B> struct mp_rename_impl; + +template<template<class...> class L, class... T, template<class...> class B> struct mp_rename_impl<L<T...>, B> +{ + using type = B<T...>; +}; + +template<template<auto...> class L, auto... A, template<class...> class B> struct mp_rename_impl<L<A...>, B> +{ + using type = B<mp_value<A>...>; +}; + +template<class L, template<class...> class B> using mp_rename = typename mp_rename_impl<L, B>::type; + +class X1 +{ +}; + +class Z: public X1 +{ +}; + +int main() +{ + constexpr auto all = std::meta::access_context::unchecked(); + constexpr auto L1 = ^^mp_list_v< bases_of(^^Z, all)[0] >; + using L2 = mp_rename<typename [: L1 :], mp_list>; +} base-commit: 6bae0c37c95565171657a15ab4dcfd13a6898769
