https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107079
--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> --- Very interesting. We're in store_init_value, initializing x with &TARGET_EXPR <D.2768, {.x=(const struct X *) &<PLACEHOLDER_EXPR struct X>}> but we must lifetime-extend via extend_ref_init_temps and we get _ZGR1x_.x = (const struct X *) &<PLACEHOLDER_EXPR struct X> >>>;, (const struct X &) &_ZGR1x_; Since x was declared constexpr, we do cxx_constant_init (not quiet) and we hit the code added in r269003: + bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) == MODIFY_EXPR; + if (preeval) + { + /* Evaluate the value to be stored without knowing what object it will be + stored in, so that any side-effects happen first. */ + if (!SCALAR_TYPE_P (type)) + new_ctx.ctor = new_ctx.object = NULL_TREE; + init = cxx_eval_constant_expression (&new_ctx, init, false, + non_constant_p, overflow_p); while evaluating the INIT_EXPR _ZGR1x_.x = (const struct X *) &<PLACEHOLDER_EXPR struct X> >>>. But we have no ctx.ctor or ctx.object here so lookup_placeholder won't find anything and we ICE on 7861 /* A placeholder without a referent. We can get here when 7862 checking whether NSDMIs are noexcept, or in massage_init_elt; 7863 just say it's non-constant for now. */ 7864 gcc_assert (ctx->quiet); Somehow we should manage that the PLACEHOLDER_EXPR is replaced with _ZGR1x_ I guess.