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()21void 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 *)62void func(B* ) 63 { 64 func_done = ++count; 65 } 66 test1()67void 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()81void 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()96void 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()111int 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