Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/SynTree/Statement.cc	(revision f5ef08c683a703ed1fb36572de445bead8f72152)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Statement.cc -- 
+// Statement.cc --
 //
 // Author           : Richard C. Bilson
@@ -36,13 +36,23 @@
 ExprStmt::ExprStmt( std::list<Label> _labels, Expression *_expr ) : Statement( _labels ), expr( _expr ) {}
 
-ExprStmt::~ExprStmt() {}
+ExprStmt::ExprStmt( const ExprStmt &other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
+
+ExprStmt::~ExprStmt() {
+	delete expr;
+}
 
 void ExprStmt::print( std::ostream &os, int indent ) const {
 	os << string( indent, ' ' ) << "Expression Statement:" << endl;
 	expr->print( os, indent + 2 );
-} 
+}
 
 
 AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, ConstantExpr *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
+
+AsmStmt::AsmStmt( const AsmStmt & other ) : Statement( other ), voltile( other.voltile ), instruction( maybeClone( other.instruction ) ), gotolabels( other.gotolabels ) {
+  cloneAll( other.output, output );
+  cloneAll( other.input, input );
+  cloneAll( other.clobber, clobber );
+}
 
 AsmStmt::~AsmStmt() {
@@ -60,5 +70,5 @@
 		os << endl << std::string( indent, ' ' ) << "output: " << endl;
 		printAll( output, os, indent + 2 );
-	} // if 
+	} // if
 	if ( ! input.empty() ) {
 		os << std::string( indent, ' ' ) << "input: " << endl << std::string( indent, ' ' );
@@ -69,5 +79,5 @@
 		printAll( clobber, os, indent + 2 );
 	} // if
-} 
+}
 
 
@@ -93,4 +103,6 @@
 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr, bool throwP ) : Statement( labels ), expr( _expr ), isThrow( throwP ) {}
 
+ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ), isThrow( other.isThrow ) {}
+
 ReturnStmt::~ReturnStmt() {
 	delete expr;
@@ -106,4 +118,7 @@
 	Statement( _labels ), condition( _condition ), thenPart( _thenPart ), elsePart( _elsePart ) {}
 
+IfStmt::IfStmt( const IfStmt & other ) :
+	Statement( other ), condition( maybeClone( other.condition ) ), thenPart( maybeClone( other.thenPart ) ), elsePart( maybeClone( other.elsePart ) ) {}
+
 IfStmt::~IfStmt() {}
 
@@ -123,4 +138,9 @@
 SwitchStmt::SwitchStmt( std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches ):
 	Statement( _labels ), condition( _condition ), branches( _branches ) {
+}
+
+SwitchStmt::SwitchStmt( const SwitchStmt & other ):
+	Statement( other ), condition( maybeClone( other.condition ) ) {
+	cloneAll( other.branches, branches );
 }
 
@@ -145,8 +165,13 @@
 }
 
-CaseStmt::CaseStmt( std::list<Label> _labels, Expression *_condition, std::list<Statement *> &_statements, bool deflt ) throw ( SemanticError ) : 
+CaseStmt::CaseStmt( std::list<Label> _labels, Expression *_condition, std::list<Statement *> &_statements, bool deflt ) throw ( SemanticError ) :
 	Statement( _labels ), condition( _condition ), stmts( _statements ), _isDefault( deflt ) {
 	if ( isDefault() && condition != 0 )
 		throw SemanticError("default with conditions");
+}
+
+CaseStmt::CaseStmt( const CaseStmt & other ) :
+	Statement( other ), condition( maybeClone(other.condition ) ), _isDefault( other._isDefault ) {
+	cloneAll( other.stmts, stmts );
 }
 
@@ -181,4 +206,9 @@
 }
 
+ChooseStmt::ChooseStmt( const ChooseStmt & other ):
+	Statement( other ), condition( maybeClone( other.condition ) ) {
+		cloneAll( other.branches, branches );
+}
+
 ChooseStmt::~ChooseStmt() {
 	delete condition;
@@ -208,4 +238,8 @@
 }
 
+WhileStmt::WhileStmt( const WhileStmt & other ):
+	Statement( other ), condition( maybeClone( other.condition ) ), body( maybeClone( other.body ) ), isDoWhile( other.isDoWhile ) {
+}
+
 WhileStmt::~WhileStmt() {
 	delete body;
@@ -223,4 +257,10 @@
 ForStmt::ForStmt( std::list<Label> labels, std::list<Statement *> initialization_, Expression *condition_, Expression *increment_, Statement *body_ ):
 	Statement( labels ), initialization( initialization_ ), condition( condition_ ), increment( increment_ ), body( body_ ) {
+}
+
+ForStmt::ForStmt( const ForStmt & other ):
+	Statement( other ), condition( maybeClone( other.condition ) ), increment( maybeClone( other.increment ) ), body( maybeClone( other.body ) ) {
+		cloneAll( other.initialization, initialization );
+
 }
 
@@ -241,18 +281,18 @@
 	os << string( indent, ' ' ) << "For Statement" << endl ;
 
-	os << string( indent + 2, ' ' ) << "initialization: \n"; 
+	os << string( indent + 2, ' ' ) << "initialization: \n";
 	for ( std::list<Statement *>::const_iterator it = initialization.begin(); it != initialization.end(); ++it ) {
 		(*it)->print( os, indent + 4 );
 	}
 
-	os << "\n" << string( indent + 2, ' ' ) << "condition: \n"; 
+	os << "\n" << string( indent + 2, ' ' ) << "condition: \n";
 	if ( condition != 0 )
 		condition->print( os, indent + 4 );
 
-	os << "\n" << string( indent + 2, ' ' ) << "increment: \n"; 
+	os << "\n" << string( indent + 2, ' ' ) << "increment: \n";
 	if ( increment != 0 )
 		increment->print( os, indent + 4 );
 
-	os << "\n" << string( indent + 2, ' ' ) << "statement block: \n"; 
+	os << "\n" << string( indent + 2, ' ' ) << "statement block: \n";
 	if ( body != 0 )
 		body->print( os, indent + 4 );
@@ -265,8 +305,6 @@
 }
 
-TryStmt::TryStmt( const TryStmt &other ) : Statement( other.labels ) {
-	block = other.block;
-	std::copy( other.handlers.begin(), other.handlers.end(), back_inserter( handlers ) );
-	finallyBlock = other.finallyBlock;
+TryStmt::TryStmt( const TryStmt &other ) : Statement( other ), block( maybeClone( other.block ) ), finallyBlock( maybeClone( other.finallyBlock ) ) {
+	cloneAll( other.handlers, handlers );
 }
 
@@ -294,4 +332,8 @@
 CatchStmt::CatchStmt( std::list<Label> labels, Declaration *_decl, Statement *_body, bool isCatchRest ) :
 	Statement( labels ), decl ( _decl ), body( _body ), catchRest ( isCatchRest ) {
+}
+
+CatchStmt::CatchStmt( const CatchStmt & other ) :
+	Statement( other ), decl ( maybeClone( other.decl ) ), body( maybeClone( other.body ) ), catchRest ( other.catchRest ) {
 }
 
@@ -319,4 +361,7 @@
 }
 
+FinallyStmt::FinallyStmt( const FinallyStmt & other ) : Statement( other ), block( maybeClone( other.block ) ) {
+}
+
 FinallyStmt::~FinallyStmt() {
 	delete block;
@@ -331,5 +376,4 @@
 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}
 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}
-NullStmt::~NullStmt() {}
 
 void NullStmt::print( std::ostream &os, int indent ) const {
