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