https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107637
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Adjusted testcase so that it also verifies what is destructed first, S vs. T in the various cases and standards: // P2718R0 - Wording for P2644R1 Fix for Range-based for Loop // { dg-do run { target c++11 } } extern "C" void abort (); void check (bool); struct S { S () { ++s; } S (const S &) { ++s; } ~S () { check (true); --s; } static int s; }; int S::s; struct T { T (const S &, const S &) { ++t; } T (const T &) { ++t; } ~T () { check (false); --t; } static int t; }; int T::t; int a[4]; int c; void check (bool is_s) { if (c) { if (is_s) { if (T::t != (c == 1)) abort (); } else { if (S::s != (c == 1 ? 0 : 2)) abort (); } } } int * begin (const S &) { return &a[0]; } int * end (const S &) { return &a[4]; } int * begin (const T &) { return &a[0]; } int * end (const T &) { return &a[4]; } const S & foo (const S &x) { return x; } const T & foo (const T &x) { return x; } int main () { if (S::s != 0) abort (); for (auto x : S ()) { if (S::s != 1) abort (); } if (S::s != 0) abort (); for (auto x : foo (S ())) { if (S::s != (__cpp_range_based_for >= 202211L)) abort (); } if (S::s != 0) abort (); if (T::t != 0) abort (); c = 1 + (__cpp_range_based_for >= 202211L); for (auto x : T (S (), S ())) { if (S::s != 2 * (__cpp_range_based_for >= 202211L) || T::t != 1) abort (); } if (S::s != 0 || T::t != 0) abort (); c = 2; for (auto x : foo (T (S (), S ()))) { if (S::s != 2 * (__cpp_range_based_for >= 202211L) || T::t != (__cpp_range_based_for >= 202211L)) abort (); } if (S::s != 0 || T::t != 0) abort (); }