aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/init/array16.C
blob: fa4c1b6508819053943c9a5196d5333ff79f66c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// { dg-do run }

// Copyright (C) 2004 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 8 Dec 2004 <nathan@codesourcery.com>

// PR 16681 too much memory used
// Origin:  Matt LaFary <lafary@activmedia.com>


struct elt 
{
  static int count;
  static elt*ptr;
  static int abort;
  char c;
  
  elt ();
  ~elt ();
  
};

int elt::count;
elt *elt::ptr;
int elt::abort;

elt::elt ()
  :c ()
{
  if (count >= 0)
    {
      if (!ptr)
	ptr = this;
      if (count == 100)
	throw 2;
      if (this != ptr)
	abort = 1;
      count++;
      ptr++;
    }
}

elt::~elt ()
{
  if (count >= 0)
    {
      ptr--;
      count--;
      if (ptr != this)
	abort = 2;
    }
}

struct foo {
  elt buffer[4111222];
  foo() ;
  bool check () const;
};

foo::foo ()
  : buffer()
{}

bool foo::check () const
{
  for (unsigned ix = sizeof (buffer)/ sizeof (buffer[0]); ix--;)
    if (buffer[ix].c)
      return false;
  return true;
}

void *operator new (__SIZE_TYPE__ size, void *p)
{
  return p;
}

char heap[5000000];

int main ()
{
  for (unsigned ix = sizeof (heap); ix--;)
    heap[ix] = ix;

  try
    {
      foo *f = new (heap) foo ();
      return 1;
    }
  catch (...)
    {
      if (elt::count)
	return 2;
      if (elt::abort)
	return elt::abort + 3;
    }

  for (unsigned ix = sizeof (heap); ix--;)
    heap[ix] = ix;

  elt::count = -1;
  foo *f = new (heap) foo ();
  if (!f->check ())
    return 3;
  return 0;
}