// CWG2867 - Order of initialization for structured bindings. // { dg-require-effective-target c++20 } // { dg-additional-options -fmodule-header } // { dg-module-cmi {} } // { dg-add-options tls } // { dg-require-effective-target tls_runtime } #define assert(X) do { if (!(X)) __builtin_abort(); } while (0) namespace std { template struct tuple_size; template struct tuple_element; } extern int a, c, d, i; struct A { A () { assert (c == 3); ++c; } ~A () { ++a; } template int &get () const { assert (c == 5 + I); ++c; return i; } }; template <> struct std::tuple_size { static const int value = 4; }; template struct std::tuple_element { using type = int; }; template <> struct std::tuple_size { static const int value = 4; }; template struct std::tuple_element { using type = int; }; struct B { B () { assert (c >= 1 && c <= 2); ++c; } ~B () { assert (c >= 9 && c <= 10); ++c; } }; struct C { constexpr C () {} constexpr C (const C &) {} template int &get () const { assert (d == 1 + I); ++d; return i; } }; template <> struct std::tuple_size { static const int value = 3; }; template struct std::tuple_element { using type = int; }; template <> struct std::tuple_size { static const int value = 3; }; template struct std::tuple_element { using type = int; }; inline A foo (const B &, const B &) { A a; assert (c == 4); ++c; return a; } constexpr C foo (const C &, const C &) { return C {}; } inline int bar (int &x, int y) { x = y; return y; } inline int baz (int &x, int y) { assert (x == y); return y; } struct E { ~E () { assert (a == 2); } }; namespace { thread_local E e; thread_local int c1 = bar (c, 1); thread_local const auto &[x, y, z, w] = foo (B {}, B {}); thread_local int c2 = baz (c, 11); thread_local int d1 = bar (d, 1); thread_local const auto &[s, t, u] = foo (C {}, C {}); thread_local int d2 = baz (d, 4); thread_local int c3 = bar (c, 1); thread_local auto [x2, y2, z2, w2] = foo (B {}, B {}); thread_local int c4 = baz (c, 11); thread_local int d3 = bar (d, 1); thread_local auto [s2, t2, u2] = foo (C {}, C {}); thread_local int d4 = baz (d, 4); }