https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115769
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Better testcase: // CWG2867 - Order of initialization for structured bindings. // { dg-do run { target c++17 } } #define assert(X) do { if (!(X)) __builtin_abort(); } while (0) namespace std { template<typename T> struct tuple_size; template<int, typename> struct tuple_element; } int c; int i; struct A { A () { assert (c == 3); ++c; } ~A () { assert (c == 12); ++c; } template <int I> int &get () const { assert (c == 5 + I); ++c; return i; } }; template <> struct std::tuple_size <A> { static const int value = 4; }; template <int I> struct std::tuple_element <I, A> { using type = int; }; template <> struct std::tuple_size <const A> { static const int value = 4; }; template <int I> struct std::tuple_element <I, const A> { using type = int; }; struct B { B () { assert (c >= 1 && c <= 2); ++c; } ~B () { assert (c >= 9 && c <= 10); ++c; } }; A foo (const B &, const B &) { A a; assert (c == 4); ++c; return a; } int main () { { c = 1; const auto &[x, y, z, w] = foo (B {}, B {}); assert (c == 11); ++c; } assert (c == 13); }