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

Reply via email to