1 // { dg-do run  }
2 //Lifetime of temporaries:
3 //egcs 2.92 performs cleanup for temporaries inside new expressions
4 //after the new is complete, not at the end of the full expression.
5 
6 #include <new>
7 #include <cstdlib>
8 #include <cstdio>
9 
10 bool new_throws;
11 bool ctor_throws;
12 
13 int new_done;
14 int ctor_done;
15 int func_done;
16 int dtor_done;
17 int delete_done;
18 
19 int count;
20 
init()21 void init()
22 {
23   new_throws = ctor_throws = false;
24   new_done = ctor_done = func_done = dtor_done = delete_done = count = 0;
25 }
26 
27 struct line_error{
28   int line;
line_errorline_error29   line_error(int i):line(i){}
30 };
31 
32 #define CHECK(cond)  if(!(cond))throw line_error(__LINE__);
33 
34 struct A{
AA35   A(int){
36     ctor_done = ++count;
37     if(ctor_throws)
38       throw 1;
39   }
AA40   A(const A&){
41     CHECK(false); //no copy constructors in this code
42   }
~AA43   ~A(){
44     dtor_done = ++count;
45   }
addrA46   A* addr(){return this;}
47 };
48 
49 struct B{
BB50   B(A*){}
newB51   void* operator new(size_t s){
52     new_done = ++count;
53     if(new_throws)
54       throw 1;
55     return malloc(s);
56   }
deleteB57   void operator delete(void *){
58     delete_done = ++count;
59   }
60 };
61 
func(B *)62 void func(B* )
63 {
64   func_done = ++count;
65 }
66 
test1()67 void test1()
68 {
69   init();
70   try{
71     func(new B(A(10).addr()));
72   }catch(int){
73   }
74   CHECK(ctor_done==1);
75   CHECK(new_done==2);
76   CHECK(func_done==3);
77   CHECK(dtor_done==4);
78   CHECK(delete_done==0);
79 }
80 
test2()81 void test2()
82 {
83   init();
84   new_throws = true;
85   try{
86     func(new B(A(10).addr()));
87   }catch(int){
88   }
89   CHECK(ctor_done==1);
90   CHECK(new_done==2);
91   CHECK(func_done==0);
92   CHECK(dtor_done==3);
93   CHECK(delete_done==0);
94 }
95 
test3()96 void test3()
97 {
98   init();
99   ctor_throws = true;
100   try{
101     func(new B(A(10).addr()));
102   }catch(int){
103   }
104   CHECK(new_done==0);
105   CHECK(ctor_done==1);
106   CHECK(func_done==0);
107   CHECK(dtor_done==0);
108   CHECK(delete_done==0);
109 }
110 
main()111 int main()
112 {
113   try{
114     test1();
115     test2();
116     test3();
117   }catch(line_error e){
118     printf("Got error in line %d\n",e.line);
119     return 1;
120   }
121   return 0;
122 }
123