On Tue, Aug 26, 2025 at 12:26:17AM +0200, Jakub Jelinek wrote: > Unfortunately that version (unlike the previous one) regresses: ... > UNRESOLVED: std/ranges/access/rend.cc -std=gnu++26 compilation failed to > produce executable > > Will try to investigate what's going on tomorrow^H^H^Htoday.
Took a while to reduce, -std=c++2{0,3,6}: template <typename T> struct remove_reference { using type = __remove_reference (T); }; template <typename> bool A; template <typename T> constexpr bool A<T &> = true; template <typename T> void foo (typename remove_reference <T>::type); template <typename T, typename U> concept B = requires (T x, U) { x; }; template <typename T, typename U> concept C = B<T, U>; template <typename T> concept D = A<T>; struct E {}; template <typename T> concept F = requires (T &x) { { 0 } -> C<decltype (E {} (foo<T> (x)))>; }; template <typename T> concept G = requires(T &x) { { x } -> C<decltype (E {} (foo<T> (x)))>; }; struct H { template <D T> void operator () (T &&) { if (F<T>) if (G<T>) ; } } h; struct I {}; void bar () { I r; h (r); } When current_function_decl is the H::operator (), the PARM_DECL x from concept F = requires (T &x) has NULL DECL_CONTEXT for which uses_template_parms returns false, so with: + /* Parameters of non-templates map to themselves (e.g. in + expansion statement body). */ + if (!uses_template_parms (DECL_CONTEXT (t))) + RETURN (t); + we return t rather than doing what we were before: /* This can happen for a parameter name used later in a function declaration (such as in a late-specified return type). Just make a dummy decl, since it's only used for its type. */ gcc_assert (cp_unevaluated_operand); r = tsubst_decl (t, args, complain); /* Give it the template pattern as its context; its true context hasn't been instantiated yet and this is good enough for mangling. */ DECL_CONTEXT (r) = DECL_CONTEXT (t); Now, in expansion stmt bodies we can have unevaluated operands, so doing if (cp_unevaluated_oeprand) { r = tsubst_decl (t, args, complain); DECL_CONTEXT (r) = DECL_CONTEXT (t); } else if (!uses_template_parms (DECL_CONTEXT (t))) RETURN (t); else gcc_unreachable (); would be wrong. Guess if (DECL_CONTEXT (t) && !uses_template_parms (DECL_CONTEXT (t))) RETURN (t); would fix these ICEs, shall I go with that, or the original expansion stmt body check, or something else? Jakub