Gentle ping for this patch.

v2 addresses the non-zero-offset base case Jason pointed out and adds
coverage for both zero- and non-zero-offset bases.

Bootstrapped and regression-tested on x86_64-pc-linux-gnu.

Is this OK for trunk?

Thanks,
Odysseas

________________________________
From: Odysseas Georgoudis <[email protected]>
Sent: 26 July 2026 22:15
To: [email protected] <[email protected]>
Cc: Jason Merrill <[email protected]>
Subject: [PATCH v2] c++: Adjust constexpr covariant call results [PR126324]

Hi Jason,

Thanks for catching the non-zero-offset case.
In v2, the result-thunk path now preserves null pointers,
evaluates the call only once, and adjusts the result to
the thunk’s static return type.

The test covers both zero- and non-zero-offset bases.

Thanks,
Odysseas

________________________________
From: Jason Merrill <[email protected]>
Sent: 26 July 2026 16:41
To: Odysseas Georgoudis <[email protected]>; [email protected] 
<[email protected]>
Subject: Re: [PATCH] c++: Adjust constexpr covariant call results [PR126324]

On 7/24/26 6:48 PM, Odysseas Georgoudis wrote:
> This patch adjusts successful scalar virtual-call results to the static
> call type after caching the underlying function result.  The cache
> therefore retains the final overrider's declared result type for direct
> calls.
> +  /* A virtual call with a covariant return type can evaluate the final
> +     overrider directly, whose result has its declared type rather than
> +     the static type of the call.  Adjust after caching so a direct call
> +     can reuse the result with its original type.  */
> +  if (!*non_constant_p
> +      && !*overflow_p
> +      && !*jump_target
> +      && DECL_VIRTUAL_P (fun)
> +      && result != void_node
> +      && scalarish_type_p (TREE_TYPE (t))
> +      && !same_type_ignoring_top_level_qualifiers_p
> +        (TREE_TYPE (result), TREE_TYPE (t)))
> +    result = adjust_temp_type (TREE_TYPE (t), result);

What if the base is at a non-zero offset from the derived type?
If I change your testcase to add another base, i.e.

struct B
{
   virtual constexpr B *clone(bool null)
   {
     return null ? nullptr : this;
   }
};

struct C
{
   virtual void dummy () { }
};

struct D : C, B
{
   constexpr D *clone(bool null) override
   {
     return null ? nullptr : this;
   }
};

then we still hit the same ICE.

Jason

Reply via email to