On 8/27/25 5:22 AM, Jakub Jelinek wrote:
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
Sounds good.
, or the original expansion stmt
body check, or something else?
Jakub