// This test fails on VxWorks in kernel mode because it depends on the
// library version of "::operator new[]" calling the "::operator new"
// defined in this module.  This doesn't work because the library version
// of "::operator new[]" is built into the kernel itself; library relocations
// are resolved when the kernel is linked.
// { dg-do run { xfail { powerpc-ibm-aix* || vxworks_kernel } } }
// { dg-options "-flat_namespace" { target *-*-darwin[67]* } }
// Test __cxa_vec routines
// Copyright (C) 2000, 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 7 Apr 2000 <nathan@nathan@codesourcery.com>

#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
#include <cxxabi.h>
#include <stdio.h>
#include <new>
#include <stdlib.h>
#include <setjmp.h>

static int ctor_count = 0;
static int dtor_count = 0;
static bool dtor_repeat = false;

// Allocate enough padding to hold an array cookie.
#ifdef __ARM_EABI__
#define padding 8
#else
#define padding (sizeof (std::size_t))
#endif

// our pseudo ctors and dtors
static abi::__cxa_cdtor_return_type ctor (void *x)
{
  if (!ctor_count)
    throw 1;
  ctor_count--;
#ifdef __ARM_EABI__
  return x;
#endif
}

static abi::__cxa_cdtor_return_type dtor (void *x)
{
  if (!dtor_count)
    {
      if (!dtor_repeat)
        dtor_count--;
      throw 1;
    }
  dtor_count--;
#ifdef __ARM_EABI__
  return x;
#endif
}

// track new and delete
static int blocks = 0;
void *operator new[] (std::size_t size) throw (std::bad_alloc)
{
  void *ptr = malloc (size);
  
  if (!ptr)
    throw std::bad_alloc ();
  blocks++;
  return ptr;
}

void operator delete[] (void *ptr) throw ()
{
  if (ptr)
    {
      free (ptr);
      blocks--;
    }
}
static jmp_buf jump;

// allocate and delete an array with no problems
void test0 ()
{
  static bool started = false;
  
  if (!started)
    {
      started = true;
      std::set_terminate (test0);
      
      ctor_count = dtor_count = 5;
      dtor_repeat = false;
      blocks = 0;
      
      try
        {
          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
          abi::__cxa_vec_delete (ary, 1, padding, dtor);
          if (ctor_count || dtor_count || blocks)
            longjmp (jump, 1);
        }
      catch (...)
        {
          longjmp (jump, 2);
        }
    }
  else
    {
      longjmp (jump, 3);
    }
  return;
}

// allocate and delete an array with exception on ctor
void test1 ()
{
  static bool started = false;
  
  if (!started)
    {
      started = true;
      std::set_terminate (test1);
      
      ctor_count = dtor_count = 5;
      dtor_repeat = false;
      blocks = 0;
      
      ctor_count = 4;
      try
        {
          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
          longjmp (jump, 1);
        }
      catch (...)
        {
          // we expect to get here
          if (ctor_count || dtor_count != 1 || blocks)
            longjmp (jump, 2);
        }
    }
  else
    {
      longjmp (jump, 3);
    }
  return;
}

// allocate and delete an array with exception on dtor
void test2 ()
{
  static bool started = false;
  
  if (!started)
    {
      started = true;
      std::set_terminate (test2);
      ctor_count = dtor_count = 5;
      dtor_repeat = false;
      blocks = 0;
      
      dtor_count = 3;
      try
        {
          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
          abi::__cxa_vec_delete (ary, 1, padding, dtor);
          longjmp (jump, 1);
        }
      catch (...)
        {
          // we expect to get here
          if (ctor_count || dtor_count != -2u || blocks)
            longjmp (jump, 2);
        }
    }
  else
    {
      longjmp (jump, 3);
    }
  return;
}

// allocate an array with double exception on dtor
void test3 ()
{
  static bool started = false;
  
  if (!started)
    {
      started = true;
      std::set_terminate (test3);
      
      ctor_count = dtor_count = 5;
      dtor_repeat = false;
      blocks = 0;
  
      dtor_count = 3;
      dtor_repeat = true;
      try
        {
          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
          abi::__cxa_vec_delete (ary, 1, padding, dtor);
          longjmp (jump, 1);
        }
      catch (...)
        {
          // we do not expect to get here
          longjmp (jump, 2);
        }
    }
  else
    {
      // we expect to get here (via terminate)
      if (ctor_count || dtor_count || blocks != 1)
        longjmp (jump, 3);
      longjmp (jump, -1);
    }
  return;
}

// allocate an array with exception on ctor and exception in cleanup
void test4 ()
{
  static bool started = false;
  
  if (!started)
    {
      started = true;
      std::set_terminate (test4);
      
      ctor_count = dtor_count = 5;
      dtor_repeat = false;
      blocks = 0;
  
      ctor_count = 3;
      dtor_count = 2;
      try
        {
          void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor);
          longjmp (jump, 1);
        }
      catch (...)
        {
          // we do not expect to get here
          longjmp (jump, 2);
        }
    }
  else
    {
      // we expect to get here (via terminate)
      if (ctor_count || dtor_count != -1u || blocks != 1)
        longjmp (jump, 3);
      longjmp (jump, -1);
    }
  return;
}

static void (*tests[])() =
{
  test0,
  test1,
  test2,
  test3,
  test4,
  NULL
};

int main ()
{
  int ix;
  int n;
  int errors = 0;
  
  for (ix = 0; tests[ix]; ix++)
    {
      if (n = setjmp (jump))
        {
          if (n > 0)
            {
              printf ("test %d failed %d\n", ix, n);
              errors++;
            }
        }
      else
        tests[ix] ();
    }
  return errors;
}

#else
int main ()
{
  return 0;
}
#endif
