https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115769
--- Comment #11 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>: https://gcc.gnu.org/g:6db9d4e954bff3dfd926c7c9b71e41e47b7089c8 commit r15-7128-g6db9d4e954bff3dfd926c7c9b71e41e47b7089c8 Author: Jakub Jelinek <ja...@redhat.com> Date: Wed Jan 22 19:36:36 2025 +0100 c++: Implement for static locals CWG 2867 - Order of initialization for structured bindings [PR115769] On Wed, Aug 14, 2024 at 10:06:24AM +0200, Jakub Jelinek wrote: > Though, now that I think about it again, perhaps what we could do instead > is just make sure the _ZGVZ3barvEDC1x1y1z1wE initialization doesn't have > a CLEANUP_POINT_EXPR in it and wrap both the _ZGVZ3barvEDC1x1y1z1wE > and cp_finish_decomp created stuff into a single CLEANUP_POINT_EXPR. > That way, perhaps _ZGVZ3barvEDC1x1y1z1wE could be initialized by one thread > and _ZGVZ3barvE1x by a different, but the temporaries from _ZGVZ3barvEDC1x1y1z1wE > initialization would be only destructed after the _ZGVZ3barvE1w guard > was released by the thread which initialized _ZGVZ3barvEDC1x1y1z1wE. Here is the I believe ABI compatible version, which uses the separate guard variables, so different structured binding variables can be initialized in different threads, but the thread that did the artificial base initialization will keep temporaries live at least until the last guard variable is released (i.e. when even that variable has been initialized). 2025-01-22 Jakub Jelinek <ja...@redhat.com> PR c++/115769 * decl.cc: Partially implement CWG 2867 - Order of initialization for structured bindings. (cp_finish_decl): If need_decomp_init, for function scope structure binding bases, temporarily clear stmts_are_full_exprs_p before calling expand_static_init, after it call cp_finish_decomp and wrap code emitted by both into maybe_cleanup_point_expr_void and ensure cp_finish_decomp isn't called again. * g++.dg/DRs/dr2867-3.C: New test. * g++.dg/DRs/dr2867-4.C: New test.