123 lines
1.8 KiB
C
123 lines
1.8 KiB
C
// { dg-do run }
|
|
//Lifetime of temporaries:
|
|
//egcs 2.92 performs cleanup for temporaries inside new expressions
|
|
//after the new is complete, not at the end of the full expression.
|
|
|
|
#include <new>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
|
|
bool new_throws;
|
|
bool ctor_throws;
|
|
|
|
int new_done;
|
|
int ctor_done;
|
|
int func_done;
|
|
int dtor_done;
|
|
int delete_done;
|
|
|
|
int count;
|
|
|
|
void init()
|
|
{
|
|
new_throws = ctor_throws = false;
|
|
new_done = ctor_done = func_done = dtor_done = delete_done = count = 0;
|
|
}
|
|
|
|
struct line_error{
|
|
int line;
|
|
line_error(int i):line(i){}
|
|
};
|
|
|
|
#define CHECK(cond) if(!(cond))throw line_error(__LINE__);
|
|
|
|
struct A{
|
|
A(int){
|
|
ctor_done = ++count;
|
|
if(ctor_throws)
|
|
throw 1;
|
|
}
|
|
A(const A&){
|
|
CHECK(false); //no copy constructors in this code
|
|
}
|
|
~A(){
|
|
dtor_done = ++count;
|
|
}
|
|
A* addr(){return this;}
|
|
};
|
|
|
|
struct B{
|
|
B(A*){}
|
|
void* operator new(size_t s){
|
|
new_done = ++count;
|
|
if(new_throws)
|
|
throw 1;
|
|
return malloc(s);
|
|
}
|
|
void operator delete(void *){
|
|
delete_done = ++count;
|
|
}
|
|
};
|
|
|
|
void func(B* )
|
|
{
|
|
func_done = ++count;
|
|
}
|
|
|
|
void test1()
|
|
{
|
|
init();
|
|
try{
|
|
func(new B(A(10).addr()));
|
|
}catch(int){
|
|
}
|
|
CHECK(ctor_done==1);
|
|
CHECK(new_done==2);
|
|
CHECK(func_done==3);
|
|
CHECK(dtor_done==4);
|
|
CHECK(delete_done==0);
|
|
}
|
|
|
|
void test2()
|
|
{
|
|
init();
|
|
new_throws = true;
|
|
try{
|
|
func(new B(A(10).addr()));
|
|
}catch(int){
|
|
}
|
|
CHECK(ctor_done==1);
|
|
CHECK(new_done==2);
|
|
CHECK(func_done==0);
|
|
CHECK(dtor_done==3);
|
|
CHECK(delete_done==0);
|
|
}
|
|
|
|
void test3()
|
|
{
|
|
init();
|
|
ctor_throws = true;
|
|
try{
|
|
func(new B(A(10).addr()));
|
|
}catch(int){
|
|
}
|
|
CHECK(new_done==0);
|
|
CHECK(ctor_done==1);
|
|
CHECK(func_done==0);
|
|
CHECK(dtor_done==0);
|
|
CHECK(delete_done==0);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
try{
|
|
test1();
|
|
test2();
|
|
test3();
|
|
}catch(line_error e){
|
|
printf("Got error in line %d\n",e.line);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|