Hi Jason,

On 3 Dec 2024, at 22:37, Jason Merrill wrote:

> On 12/3/24 12:25 PM, Simon Martin wrote:
>> We currently reject the following valid code:
>>
>> === cut here ===
>> struct Base {
>>      virtual void doit (int v) const {}
>> };
>> struct Derived : Base {
>>      void doit (int v) const {}
>> };
>> using fn_t = void (Base::*)(int) const;
>> struct Helper {
>>      fn_t mFn;
>>      constexpr Helper (auto && fn) : mFn(static_cast<fn_t>(fn)) {}
>> };
>> void foo () {
>>      constexpr Helper h (&Derived::doit);
>> }
>> === cut here ===
>>
>> The problem is that since r6-4014-gdcdbc004d531b4, &Derived::doit is
>> represented with an expression with type pointer to method and using 
>> an
>> INTEGER_CST (here 1), and that cxx_eval_constant_expression rejects 
>> any
>> such expression with a non-null INTEGER_CST.
>>
>> This patch uses the same strategy as r12-4491-gf45610a45236e9 (fix 
>> for
>> PR c++/102786), and simply lets such expressions go through.
>>
>> Successfully tested on x86_64-pc-linux-gnu.
>>
>>      PR c++/117615
>>
>> gcc/cp/ChangeLog:
>>
>>      * constexpr.cc (cxx_eval_constant_expression): Don't reject
>>      INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE.
>>
>> gcc/testsuite/ChangeLog:
>>
>>      * g++.dg/cpp2a/constexpr-virtual22.C: New test.
>>
>> ---
>>   gcc/cp/constexpr.cc                           | 27 
>> ++++++++++++-------
>>   .../g++.dg/cpp2a/constexpr-virtual22.C        | 22 +++++++++++++++
>>   2 files changed, 40 insertions(+), 9 deletions(-)
>>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-virtual22.C
>>
>> diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
>> index 5a87fa485c6..d9636bad683 100644
>> --- a/gcc/cp/constexpr.cc
>> +++ b/gcc/cp/constexpr.cc
>> @@ -8277,15 +8277,24 @@ cxx_eval_constant_expression (const 
>> constexpr_ctx *ctx, tree t,
>>            }
>>          else
>>            {
>> -            /* This detects for example:
>> -                 reinterpret_cast<void*>(sizeof 0)
>> -            */
>> -            if (!ctx->quiet)
>> -              error_at (loc, "%<reinterpret_cast<%T>(%E)%> is not "
>> -                        "a constant expression",
>> -                        type, op);
>> -            *non_constant_p = true;
>> -            return t;
>> +            if (TYPE_PTR_P (type)
>> +                && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
>> +              /* INTEGER_CST with pointer-to-method type is only used
>> +                 for a virtual method in a pointer to member function.
>> +                 Don't reject those.  */
>> +              ;
>
> This could be "else if" added before the existing else so it doesn't 
> need to be reindented.  OK with that change.
Thanks, merged as r15-5920-g72a2380a306a1c with the suggested change.

Since this is a reject-valid, also OK for active branches?

Simon

Reply via email to