[Bug c++/126918] New: constexpr exceptions and nullptr vs. pointer-to-member

"jakub at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.