Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 931dd1264212048e4fe4b09741eb0442ebabcb99)
+++ src/ResolvExpr/Unify.cc	(revision 33e6a2cc471e9cc9c8faee7dd84043aaecd223f9)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Unify.cc -- 
+// Unify.cc --
 //
 // Author           : Richard C. Bilson
@@ -38,5 +38,5 @@
 		WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
 		operator bool() { return widenFirst && widenSecond; }
-  
+
 		bool widenFirst : 1, widenSecond : 1;
 	};
@@ -45,5 +45,5 @@
 	  public:
 		Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
-  
+
 		bool get_result() const { return result; }
 	  private:
@@ -79,5 +79,5 @@
 	bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
 	bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
-  
+
 	bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		TypeEnvironment newEnv;
@@ -137,5 +137,5 @@
 		  case TypeDecl::Dtype:
 			return ! isFtype( type, indexer );
-  
+
 		  case TypeDecl::Ftype:
 			return isFtype( type, indexer );
@@ -196,5 +196,5 @@
 		bool widen1 = false, widen2 = false;
 		Type *type1 = 0, *type2 = 0;
-  
+
 		if ( env.lookup( var1->get_name(), class1 ) ) {
 			hasClass1 = true;
@@ -217,5 +217,5 @@
 			widen2 = widenMode.widenSecond && class2.allowWidening;
 		} // if
-  
+
 		if ( type1 && type2 ) {
 //    std::cout << "has type1 && type2" << std::endl;
@@ -436,7 +436,5 @@
 		// to unify, array types must both be VLA or both not VLA
 		// and must both have a dimension expression or not have a dimension
-		if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() 
-				&& ((arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0)
-					|| (arrayType->get_dimension() == 0 && otherArray->get_dimension() == 0))) {
+		if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
 
 			// not positive this is correct in all cases, but it's needed for typedefs
@@ -449,12 +447,15 @@
 				ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
 				ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( otherArray->get_dimension() );
-				assert(ce1 && ce2);
-
-				Constant * c1 = ce1->get_constant();
-				Constant * c2 = ce2->get_constant();
-
-				if ( c1->get_value() != c2->get_value() ) {
-					// does not unify if the dimension is different
-					return;
+				// see C11 Reference Manual 6.7.6.2.6
+				// two array types with size specifiers that are integer constant expressions are
+				// compatible if both size specifiers have the same constant value
+				if ( ce1 && ce2 ) {
+					Constant * c1 = ce1->get_constant();
+					Constant * c2 = ce2->get_constant();
+
+					if ( c1->get_value() != c2->get_value() ) {
+						// does not unify if the dimension is different
+						return;
+					}
 				}
 			}
@@ -485,5 +486,5 @@
 
 			if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
-	
+
 				if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 931dd1264212048e4fe4b09741eb0442ebabcb99)
+++ src/SynTree/Expression.cc	(revision 33e6a2cc471e9cc9c8faee7dd84043aaecd223f9)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Expression.cc -- 
+// Expression.cc --
 //
 // Author           : Richard C. Bilson
@@ -422,4 +422,7 @@
 }
 
+AsmExpr::AsmExpr( const AsmExpr & other ) : inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
+
+
 void AsmExpr::print( std::ostream &os, int indent ) const {
 	os << "Asm Expression: " << std::endl;
@@ -429,4 +432,8 @@
 }
 
+UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {}
+
+UntypedValofExpr::~UntypedValofExpr() { delete body; }
+
 void UntypedValofExpr::print( std::ostream &os, int indent ) const {
 	os << std::string( indent, ' ' ) << "Valof Expression: " << std::endl;
@@ -434,4 +441,6 @@
 		get_body()->print( os, indent + 2 );
 }
+
+
 
 std::ostream & operator<<( std::ostream & out, Expression * expr ) {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 931dd1264212048e4fe4b09741eb0442ebabcb99)
+++ src/SynTree/Expression.h	(revision 33e6a2cc471e9cc9c8faee7dd84043aaecd223f9)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Expression.h -- 
+// Expression.h --
 //
 // Author           : Richard C. Bilson
@@ -155,8 +155,9 @@
 };
 
+// xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack
 class LabelAddressExpr : public Expression {
   public:
 	LabelAddressExpr( Expression *arg );
-	LabelAddressExpr( const AddressExpr &other );
+	LabelAddressExpr( const LabelAddressExpr &other );
 	virtual ~LabelAddressExpr();
 
@@ -251,5 +252,5 @@
 };
 
-/// ConstantExpr represents an expression that simply refers to the value of a constant 
+/// ConstantExpr represents an expression that simply refers to the value of a constant
 class ConstantExpr : public Expression {
   public:
@@ -515,4 +516,5 @@
   public:
 	AsmExpr( Expression *inout, ConstantExpr *constraint, Expression *operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
+	AsmExpr( const AsmExpr & other );
 	virtual ~AsmExpr() { delete inout; delete constraint; delete operand; };
 
@@ -541,5 +543,6 @@
   public:
 	UntypedValofExpr( Statement *_body, Expression *_aname = 0 ) : Expression( _aname ), body ( _body ) {}
-	virtual ~UntypedValofExpr() {}
+	UntypedValofExpr( const UntypedValofExpr & other );
+	virtual ~UntypedValofExpr();
 
 	Expression *get_value();
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 931dd1264212048e4fe4b09741eb0442ebabcb99)
+++ src/SynTree/Statement.cc	(revision 33e6a2cc471e9cc9c8faee7dd84043aaecd223f9)
@@ -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 {
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 931dd1264212048e4fe4b09741eb0442ebabcb99)
+++ src/SynTree/Statement.h	(revision 33e6a2cc471e9cc9c8faee7dd84043aaecd223f9)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Statement.h -- 
+// Statement.h --
 //
 // Author           : Richard C. Bilson
@@ -57,4 +57,5 @@
   public:
 	ExprStmt( std::list<Label> labels, Expression *expr );
+	ExprStmt( const ExprStmt &other );
 	virtual ~ExprStmt();
 
@@ -73,4 +74,5 @@
   public:
 	AsmStmt( std::list<Label> labels, bool voltile, ConstantExpr *instruction, std::list<Expression *> input, std::list<Expression *> output, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
+	AsmStmt( const AsmStmt &other );
 	virtual ~AsmStmt();
 
@@ -103,4 +105,5 @@
   public:
 	IfStmt( std::list<Label> labels, Expression *condition, Statement *thenPart, Statement *elsePart );
+	IfStmt( const IfStmt &other );
 	virtual ~IfStmt();
 
@@ -111,5 +114,5 @@
 	Statement *get_elsePart() { return elsePart; }
 	void set_elsePart( Statement *newValue ) { elsePart = newValue; }
-	
+
 	virtual IfStmt *clone() const { return new IfStmt( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -125,4 +128,5 @@
   public:
 	SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &branches );
+	SwitchStmt( const SwitchStmt &other );
 	virtual ~SwitchStmt();
 
@@ -146,4 +150,5 @@
   public:
 	ChooseStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &branches );
+	ChooseStmt( const ChooseStmt &other );
 	virtual ~ChooseStmt();
 
@@ -177,6 +182,7 @@
 class CaseStmt : public Statement {
   public:
-	CaseStmt( std::list<Label> labels, Expression *conditions, 
+	CaseStmt( std::list<Label> labels, Expression *conditions,
 	      std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
+	CaseStmt( const CaseStmt &other );
 	virtual ~CaseStmt();
 
@@ -192,5 +198,5 @@
 	std::list<Statement *> &get_statements() { return stmts; }
 	void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
-	
+
 	virtual void accept( Visitor &v ) { v.visit( this ); }
 	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
@@ -208,4 +214,5 @@
 	WhileStmt( std::list<Label> labels, Expression *condition,
 	       Statement *body, bool isDoWhile = false );
+	WhileStmt( const WhileStmt &other );
 	virtual ~WhileStmt();
 
@@ -216,5 +223,5 @@
 	bool get_isDoWhile() { return isDoWhile; }
 	void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
-	
+
 	virtual WhileStmt *clone() const { return new WhileStmt( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -231,4 +238,5 @@
 	ForStmt( std::list<Label> labels, std::list<Statement *> initialization,
 	     Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
+	ForStmt( const ForStmt &other );
 	virtual ~ForStmt();
 
@@ -241,5 +249,5 @@
 	Statement *get_body() { return body; }
 	void set_body( Statement *newValue ) { body = newValue; }
-	
+
 	virtual ForStmt *clone() const { return new ForStmt( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -259,10 +267,9 @@
 	BranchStmt( std::list<Label> labels, Label target, Type ) throw (SemanticError);
 	BranchStmt( std::list<Label> labels, Expression *computedTarget, Type ) throw (SemanticError);
-	virtual ~BranchStmt() {}
 
 	Label get_originalTarget() { return originalTarget; }
 	Label get_target() { return target; }
 	void set_target( Label newValue ) { target = newValue; }
-	
+
 	Expression *get_computedTarget() { return computedTarget; }
 	void set_target( Expression * newValue ) { computedTarget = newValue; }
@@ -286,9 +293,10 @@
   public:
 	ReturnStmt( std::list<Label> labels, Expression *expr, bool throwP = false );
+	ReturnStmt( const ReturnStmt &other );
 	virtual ~ReturnStmt();
 
 	Expression *get_expr() { return expr; }
 	void set_expr( Expression *newValue ) { expr = newValue; }
-	
+
 	virtual ReturnStmt *clone() const { return new ReturnStmt( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -305,5 +313,4 @@
 	NullStmt();
 	NullStmt( std::list<Label> labels );
-	virtual ~NullStmt();
 
 	virtual NullStmt *clone() const { return new NullStmt( *this ); }
@@ -311,9 +318,9 @@
 	virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
 	virtual void print( std::ostream &os, int indent = 0 ) const;
-	
-  private:
-};
-
-class TryStmt : public Statement { 
+
+  private:
+};
+
+class TryStmt : public Statement {
   public:
 	TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &handlers, FinallyStmt *finallyBlock = 0 );
@@ -332,14 +339,15 @@
 	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
 	virtual void print( std::ostream &os, int indent = 0 ) const;
-	
+
   private:
 	CompoundStmt *block;
 	std::list<Statement *> handlers;
 	FinallyStmt *finallyBlock;
-}; 
+};
 
 class CatchStmt : public Statement {
   public:
 	CatchStmt( std::list<Label> labels, Declaration *decl, Statement *body, bool isCatchRest = false );
+	CatchStmt( const CatchStmt &other );
 	virtual ~CatchStmt();
 
@@ -349,10 +357,10 @@
 	Statement *get_body() { return body; }
 	void set_body( Statement *newValue ) { body = newValue; }
-	
+
 	virtual CatchStmt *clone() const { return new CatchStmt( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
 	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
 	virtual void print( std::ostream &os, int indent = 0 ) const;
-	
+
   private:
 	Declaration *decl;
@@ -361,12 +369,13 @@
 };
 
-class FinallyStmt : public Statement { 
+class FinallyStmt : public Statement {
   public:
 	FinallyStmt( std::list<Label> labels, CompoundStmt *block );
+	FinallyStmt( const FinallyStmt &other );
 	virtual ~FinallyStmt();
 
 	CompoundStmt *get_block() const { return block; }
 	void set_block( CompoundStmt *newValue ) { block = newValue; }
-	
+
 	virtual FinallyStmt *clone() const { return new FinallyStmt( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -375,5 +384,5 @@
   private:
 	CompoundStmt *block;
-}; 
+};
 
 
