Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 67b11805a9c9b0a267280de939d17212697a3732)
+++ src/InitTweak/FixInit.cc	(revision 845cedcae61ca707834e349e69b07e41e766d7c0)
@@ -10,5 +10,5 @@
 // Created On       : Wed Jan 13 16:29:30 2016
 // Last Modified By : Rob Schluntz
-// Last Modified On : Thu Apr 14 17:29:21 2016
+// Last Modified On : Mon Apr 25 14:44:21 2016
 // Update Count     : 30
 //
@@ -18,4 +18,5 @@
 #include "RemoveInit.h"
 #include "ResolvExpr/Resolver.h"
+#include "ResolvExpr/typeops.h"
 #include "SynTree/Declaration.h"
 #include "SynTree/Type.h"
@@ -27,4 +28,7 @@
 #include "GenPoly/PolyMutator.h"
 
+bool ctordtorp = false;
+#define PRINT( text ) if ( ctordtorp ) { text }
+
 namespace InitTweak {
 	namespace {
@@ -115,17 +119,32 @@
 
 	Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
+		appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );
+		assert( appExpr );
+
 		if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
 			if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
 				// optimization: don't need to copy construct in order to call intrinsic functions
 				return appExpr;
-			} else if ( FunctionDecl * func = dynamic_cast< FunctionDecl * > ( function->get_var() ) ) {
-				// if (  )
-				// // optimization: don't need to copy construct in order to call a copy constructor
-				// return appExpr;
+			} else if ( FunctionDecl * funcDecl = dynamic_cast< FunctionDecl * > ( function->get_var() ) ) {
+				FunctionType * ftype = funcDecl->get_functionType();
+				if ( (funcDecl->get_name() == "?{}" || funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) {
+					Type * t1 = ftype->get_parameters().front()->get_type();
+					Type * t2 = ftype->get_parameters().back()->get_type();
+					PointerType * ptrType = dynamic_cast< PointerType * > ( t1 );
+					assert( ptrType );
+					if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
+						// optimization: don't need to copy construct in order to call a copy constructor or
+						// assignment operator
+						return appExpr;
+					}
+				} else if ( funcDecl->get_name() == "^?{}" ) {
+					// correctness: never copy construct arguments to a destructor
+					return appExpr;
+				}
 			}
 		}
+		PRINT( std::cerr << "InsertImplicitCalls: adding a wrapper " << appExpr << std::endl; )
+
 		// wrap each function call so that it is easy to identify nodes that have to be copy constructed
-		appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );
-		assert( appExpr );
 		return new ImplicitCopyCtorExpr( appExpr );
 	}
@@ -140,4 +159,5 @@
 		// should only be one alternative for copy ctor and dtor expressions, since
 		// all arguments are fixed (VariableExpr and already resolved expression)
+		PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
 		ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
 
@@ -151,11 +171,8 @@
 		static UniqueName retNamer("_tmp_cp_ret");
 
-		// resolve function call
-		ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( impCpCtorExpr->get_callExpr(), *this ) );
-		assert( appExpr );
-		delete impCpCtorExpr->get_callExpr();
-		impCpCtorExpr->set_callExpr( appExpr );
-
-		// Visitor::visit( impCpCtorExpr );
+		PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
+		Visitor::visit( impCpCtorExpr );
+
+		ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
 
 		// take each argument and attempt to copy construct it.
@@ -167,4 +184,5 @@
 
 			// create and resolve copy constructor
+			PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
 			ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg );
 
@@ -186,14 +204,20 @@
 		// later
 		// xxx - handle multiple return values
+		ApplicationExpr * callExpr = impCpCtorExpr->get_callExpr();
 		for ( Type * result : appExpr->get_results() ) {
-			ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result->clone(), new SingleInit( impCpCtorExpr->get_callExpr() ) );
+			ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result->clone(), new SingleInit( callExpr ) );
 			ret->get_type()->set_isConst( false );
 			impCpCtorExpr->get_returnDecls().push_back( ret );
+			PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
 			impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
 		}
+		PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
 	}
 
 
 	Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
+		PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
+
+		// assert( impCpCtorExpr->get_callExpr()->get_env() );
 		impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) );
 		assert( impCpCtorExpr );
@@ -219,4 +243,7 @@
 		// xxx - update to work with multiple return values
 		ObjectDecl * returnDecl = returnDecls.empty() ? NULL : returnDecls.front();
+		Expression * callExpr = impCpCtorExpr->get_callExpr();
+
+		PRINT( std::cerr << "Coming out the back..." << impCpCtorExpr << std::endl; )
 
 		// xxx - some of these aren't necessary, and can be removed once this is stable
@@ -225,4 +252,6 @@
 		tempDecls.clear();
 		returnDecls.clear();
+		impCpCtorExpr->set_callExpr( NULL );
+		delete impCpCtorExpr;
 
 		if ( returnDecl ) {
@@ -232,5 +261,6 @@
 		} else {
 			// add call expression - if no return values, can call directly
-			return impCpCtorExpr->get_callExpr();
+			assert( callExpr );
+			return callExpr;
 		}
 	}
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 67b11805a9c9b0a267280de939d17212697a3732)
+++ src/MakeLibCfa.cc	(revision 845cedcae61ca707834e349e69b07e41e766d7c0)
@@ -10,5 +10,5 @@
 // Created On       : Sat May 16 10:33:33 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Tue Jan 19 13:20:26 2016
+// Last Modified On : Fri Apr 22 13:54:15 2016
 // Update Count     : 40
 //
@@ -43,4 +43,5 @@
 	void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
 		if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
+		if ( origFuncDecl->get_statements() ) return;
 
 		FunctionDecl *funcDecl = origFuncDecl->clone();
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 67b11805a9c9b0a267280de939d17212697a3732)
+++ src/SynTree/Expression.cc	(revision 845cedcae61ca707834e349e69b07e41e766d7c0)
@@ -10,5 +10,5 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Mon Apr 18 17:25:06 2016
+// Last Modified On : Fri Apr 22 16:20:43 2016
 // Update Count     : 40
 //
@@ -463,5 +463,4 @@
 
 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
-	cloneAll( other.results, results );
 	cloneAll( other.copyCtors, copyCtors );
 	cloneAll( other.tempDecls, tempDecls );
