Home | History | Annotate | Download | only in jni
      1 // { dg-do run  }
      2 // Origin: Mark Mitchell <mark (at) codesourcery.com>
      3 
      4 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
      5 
      6 #include <cstdlib>
      7 #include <new>
      8 
      9 void* p;
     10 
     11 void* operator new[](size_t s) throw (std::bad_alloc)
     12 {
     13   // Record the base of the last array allocated.
     14   p = malloc (s);
     15   return p;
     16 }
     17 
     18 template <typename T>
     19 void check_no_cookie (int i)
     20 {
     21   void* a = new T[7];
     22   if (p != a)
     23     exit (i);
     24 }
     25 
     26 template <typename T>
     27 void check_no_placement_cookie (int i)
     28 {
     29   p = malloc (13 * sizeof (T));
     30   void* a = new (p) T[13];
     31   if (p != a)
     32     exit (i);
     33 }
     34 
     35 template <typename T>
     36 void check_cookie (int i)
     37 {
     38   void* a = new T[11];
     39   size_t x;
     40 
     41   // Compute the cookie location manually.
     42 #if defined(__ARM_EABI__) || defined(__le32__)
     43   x = 8;
     44 #else
     45   x = __alignof__ (T);
     46   if (x < sizeof (size_t))
     47     x = sizeof (size_t);
     48 #endif
     49   if ((char *) a - x != (char *) p)
     50     exit (i);
     51 
     52   // Check the cookie value.
     53   size_t *sp = ((size_t *) a) - 1;
     54   if (*sp != 11)
     55     exit (i);
     56 
     57 #if defined(__ARM_EABI__) || defined(__le32__)
     58   sp = ((size_t *) a) - 2;
     59   if (*sp != sizeof (T))
     60     exit (i);
     61 #endif
     62 }
     63 
     64 template <typename T>
     65 void check_placement_cookie (int i)
     66 {
     67   p = malloc (sizeof (T) * 11 + 100);
     68   void* a = new (p) T[11];
     69   size_t x;
     70 
     71   // Compute the cookie location manually.
     72 #if defined(__ARM_EABI__) || defined(__le32__)
     73   x = 8;
     74 #else
     75   x = __alignof__ (T);
     76   if (x < sizeof (size_t))
     77     x = sizeof (size_t);
     78 #endif
     79   if ((char *) a - x != (char *) p)
     80     exit (i);
     81 
     82   // Check the cookie value.
     83   size_t *sp = ((size_t *) a) - 1;
     84   if (*sp != 11)
     85     exit (i);
     86 
     87 #if defined(__ARM_EABI__) || defined(__le32__)
     88   sp = ((size_t *) a) - 2;
     89   if (*sp != sizeof (T))
     90     exit (i);
     91 #endif
     92 }
     93 
     94 struct X {};
     95 
     96 template <typename T>
     97 struct Y { int i; virtual void f () {} };
     98 
     99 // A class with a non-trivial destructor -- it needs a cookie.
    100 struct Z { ~Z () {} };
    101 // Likewise, but this class needs a bigger cookie so that the array
    102 // elements are correctly aligned.
    103 struct Z2 { ~Z2 () {} long double d; };
    104 
    105 struct W1 { void operator delete[] (void *, size_t) {} };
    106 struct W2 { void operator delete[] (void *) {}
    107             void operator delete[] (void *, size_t) {} };
    108 struct W3 { void operator delete[] (void *, size_t) {}
    109             void operator delete[] (void *) {} };
    110 struct W4 : public W1 {};
    111 
    112 struct V { void *operator new[] (size_t s, void *p)
    113              { return p; }
    114            ~V () {}
    115          };
    116 
    117 int main ()
    118 {
    119   // There should be no cookies for types with trivial destructors.
    120   check_no_cookie<int> (1);
    121   check_no_cookie<X> (2);
    122   check_no_cookie<Y<double> > (3);
    123 
    124   // There should be no cookies for allocations using global placement
    125   // new.
    126   check_no_placement_cookie<int> (4);
    127   check_no_placement_cookie<X> (5);
    128   check_no_placement_cookie<Z> (6);
    129 
    130   // There should be a cookie when using a non-trivial destructor.
    131   check_cookie<Z> (7);
    132   check_cookie<Z2> (8);
    133 
    134   // There should be a cookie when using the two-argument array delete
    135   // operator.
    136   check_cookie<W1> (9);
    137   check_cookie<W4> (10);
    138   // But not when the one-argument version is also available.
    139   check_no_cookie<W2> (11);
    140   check_no_cookie<W3> (12);
    141 
    142   // There should be a cookie when using a non-global placement new.
    143   check_placement_cookie<V> (13);
    144 }
    145 
    146 #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
    147 
    148 int main ()
    149 {
    150 }
    151 
    152 #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
    153