https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126918
Bug ID: 126918
Summary: constexpr exceptions and nullptr vs. pointer-to-member
Product: gcc
Version: 16.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
// { dg-do compile { target c++26 } }
struct S { int m, n; int foo (int x) { return x + 42; } };
constexpr int S::*
foo (bool x)
{
if (x)
return nullptr;
try
{
throw nullptr;
}
catch (int S::*p)
{
return p;
}
return &S::m;
}
constexpr int S::*&
bar (bool x)
{
static int S::*sm = &S::m;
if (x)
return sm;
try
{
throw nullptr;
}
catch (int S::*&p)
{
return p;
}
return sm;
}
constexpr const int S::*
baz (bool x)
{
if (x)
return nullptr;
try
{
throw &S::m;
}
catch (const int S::*p)
{
return p;
}
return nullptr;
}
constexpr const int S::*&
qux (bool x)
{
static const int S::*np = nullptr;
if (x)
return np;
try
{
throw &S::m;
}
catch (const int S::*&p)
{
return p;
}
return np;
}
using F = int (S::*) (int);
constexpr F
corge (bool x)
{
if (x)
return nullptr;
try
{
throw nullptr;
}
catch (F p)
{
return p;
}
return &S::foo;
}
constexpr F &
garply (bool x)
{
static F f = &S::foo;
if (x)
return f;
try
{
throw nullptr;
}
catch (F &p)
{
return p;
}
return f;
}
#if __cpp_constexpr_exceptions >= 202411L
static_assert (foo (false) == nullptr);
static_assert (bar (false) == nullptr);
static_assert (baz (false) == &S::m);
static_assert (qux (false) == &S::m);
static_assert (corge (false) == nullptr);
static_assert (garply (false) == nullptr);
#endif
int
main ()
{
if (foo (false) != nullptr
|| bar (false) != nullptr
|| baz (false) != &S::m
|| qux (false) != &S::m
|| corge (false) != nullptr
|| garply (false) != nullptr)
__builtin_abort ();
}
should succeed but fails (if the baz/qux uses in static_assert/main are
commented out) or ICEs.