https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99790

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Even more reduced:

struct A;
struct B { void (*fn) (A *); };
template <typename T>
int foo (const T &);
struct A { int a; static constexpr B b{[] (A *n) { n->*&A::a = 2; }}; };
int a = foo (A::b);

The problem seems to be that the lambda is genericized from
finish_lambda_function -> finish_function before the A class is finalized, so
    case PTRMEM_CST:
      /* By the time we get here we're handing off to the back end, so we don't
         need or want to preserve PTRMEM_CST anymore.  */
      *stmt_p = cplus_expand_constant (stmt);
doesn't do anything.

If PTRMEM_CSTs are the only thing, one possible fix could be
--- gcc/cp/cp-gimplify.c.jj     2021-03-20 17:01:59.791040946 +0100
+++ gcc/cp/cp-gimplify.c        2021-03-29 14:27:37.532223156 +0200
@@ -660,6 +660,14 @@ cp_gimplify_expr (tree *expr_p, gimple_s
       ret = GS_UNHANDLED;
       break;

+    case PTRMEM_CST:
+      *expr_p = cplus_expand_constant (*expr_p);
+      if (TREE_CODE (*expr_p) == PTRMEM_CST)
+       ret = GS_ERROR;
+      else
+       ret = GS_OK;
+      break;
+
     case RETURN_EXPR:
       if (TREE_OPERAND (*expr_p, 0)
          && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
i.e. handle PTRMEM_CSTs not just during  genericization, but also during
gimplification where because we are unit at a time the classes should be better
complete already.

Reply via email to