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()20void 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 *)61void func(B* ) 62 { 63 func_done = ++count; 64 } 65 test1()66void 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()80void 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()95void 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()110int 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