blob: 502c4f42ad098fbf56b36c14d7323b4d92a6a8f2 [file] [log] [blame]
// { 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;
}