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);
}