https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117615
Bug ID: 117615
Summary: constexpr failure static_cast of Derived virtual
Pointer to Member
Product: gcc
Version: 14.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: acox at reliablecontrols dot com
Target Milestone: ---
Casting a virtual member function from the derived class fails to compile with
an error message complaining about a reinterpret_cast from a number to the
function signature. The number seems to be an offset, if you add a virtual
destructor to the Base class before the line doit is defined on the number
increases to 17.
https://godbolt.org/z/xPennWh15
<source>: In function 'int main()':
<source>:36:37: in 'constexpr' expansion of 'help(&Derived::doit)'
<source>:28:7: error: 'reinterpret_cast<void (Base::*)(int) const>(1)' is not a
constant expression
28 | : mFn(static_cast<fn_t>(fn))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 1
It compiles under the following changes
- if the member functions are made non-virtual
- if constexpr is removed from h
- if h is constructed with &Base::doit
Code from the godbolt link is included below as well.
```
#include <iostream>
#define BREAK_IT
struct Base {
#ifdef BREAK_IT
virtual
#endif
void doit(int v) const { std::cout << "doit base " << v; }
virtual ~Base() = default;
};
struct Derived : Base {
#ifdef BREAK_IT
virtual
#endif
void doit(int v) const { std::cout << "doit derived " << v; }
};
struct help
{
using fn_t = void (Base::*)(int) const;
fn_t mFn;
constexpr help(auto && fn)
: mFn(static_cast<fn_t>(fn))
{
}
};
int main()
{
constexpr help h (&Derived::doit);
Derived x;
(x.*h.mFn)(12);
}
```