https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127109
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The error is on the D.2758 temporary, TARGET_EXPR_SLOT of DECL_DECOMP_BASE.
This is created in cp_finish_decomp:
if (cond && !error_operand_p (cond))
{
/* Wrap that value into a TARGET_EXPR, emit it right
away and save for later uses in the cp_parse_condition
or its instantiation. */
cond = get_internal_target_expr (cond);
add_stmt (cond);
DECL_DECOMP_BASE (decl) = cond;
}
There is no CLEANUP_POINT_EXPR wrapping right this TARGET_EXPR (good), but
there is one added in cp_finish_decl:
decomp_init = maybe_cleanup_point_expr_void (sl);
That is supposed to destruct any temporaries from the whole structured binding
construction, as per https://wg21.link/cwg2867.
The problem is that (at least for constexpr evaluation) it destructs also this
TARGET_EXPR_SLOT (which is bool, so it doesn't have destructor).
Guess we'd need to arrange for the TARGET_EXPR to be evaluated already before
that CLEANUP_POINT_EXPR (but in that case it can't have the A::operator bool
(&D.2722) initializer, but would need to be initialized say to just false and
at the point of the current add_stmt (cond) there would need to be assignment
of the A::operator bool (&D.2722) to the TARGET_EXPR.
Right now we have:
<<cleanup_point <<< Unknown tree: expr_stmt
D.2722.a = v >>>;
<<< Unknown tree: expr_stmt
D.2722.b = v * 2 >>>;
<<< Unknown tree: expr_stmt
D.2722.c = v != 0 >>>;
D.2757 = 1;
TARGET_EXPR <D.2758, A::operator bool (&D.2722)>;
const type & a;
<<cleanup_point <<< Unknown tree: expr_stmt
(void) (a = (const type &) (const int *) A::get<0> ((struct A *)
NON_LVALUE_EXPR <(struct A &) &D.2722>)) >>>>>;
const type & b;
<<cleanup_point <<< Unknown tree: expr_stmt
(void) (b = (const type &) (const int *) A::get<1> ((struct A *)
NON_LVALUE_EXPR <(struct A &) &D.2722>)) >>>>>;>>;
and use D.2758 in code after this.