Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 05d55ffed10db511d8a2eec6a4ec6ccfbd8079dd)
+++ src/AST/Node.hpp	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -99,14 +99,26 @@
 
 /// Mutate a node field (only clones if not equal to existing value)
-template<typename node_t, typename field_t>
-const node_t * mutate_field( 
-	const node_t * node, 
-	typename std::remove_const<typename std::remove_reference<field_t>::type>::type node_t::* field,
-	field_t&& val 
-) {
+template<typename node_t, typename field_t, typename assn_t>
+const node_t * mutate_field( const node_t * node, field_t node_t::* field, assn_t && val ) {
+	// skip mutate if equivalent
 	if ( node->*field == val ) return node;
 	
+	// mutate and return
 	node_t * ret = mutate( node );
-	ret->*field = std::forward< field_t >( val );
+	ret->*field = std::forward< assn_t >( val );
+	return ret;
+}
+
+/// Mutate a single index of a node field (only clones if not equal to existing value)
+template<typename node_t, typename coll_t, typename ind_t, typename field_t>
+const node_t * mutate_field_index(
+	const node_t * node, coll_t node_t::* field, ind_t i, field_t && val
+) {
+	// skip mutate if equivalent
+	if  ( (node->*field)[i] == val ) return node;
+
+	// mutate and return
+	node_t * ret = mutate( node );
+	(ret->*field)[i] = std::forward< field_t >( val );
 	return ret;
 }
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 05d55ffed10db511d8a2eec6a4ec6ccfbd8079dd)
+++ src/InitTweak/InitTweak.cc	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -1,2 +1,17 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// InitTweak.cc --
+//
+// Author           : Rob Schluntz
+// Created On       : Fri May 13 11:26:36 2016
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Mon Jun 10 13:30:00 2019
+// Update Count     : 5
+//
+
 #include <algorithm>               // for find, all_of
 #include <cassert>                 // for assertf, assert, strict_dynamic_cast
@@ -4,4 +19,5 @@
 #include <iterator>                // for back_insert_iterator, back_inserter
 #include <memory>                  // for __shared_ptr
+#include <vector>
 
 #include "AST/Expr.hpp"
@@ -307,6 +323,6 @@
 	}
 
-	struct CallFinder {
-		CallFinder( const std::list< std::string > & names ) : names( names ) {}
+	struct CallFinder_old {
+		CallFinder_old( const std::list< std::string > & names ) : names( names ) {}
 
 		void postvisit( ApplicationExpr * appExpr ) {
@@ -331,8 +347,31 @@
 	};
 
+	struct CallFinder_new final {
+		std::vector< ast::ptr< ast::Expr > > matches;
+		const std::vector< std::string > names;
+
+		CallFinder_new( std::vector< std::string > && ns ) : matches(), names( std::move(ns) ) {}
+
+		void handleCallExpr( const ast::Expr * expr ) {
+			std::string fname = getFunctionName( expr );
+			if ( std::find( names.begin(), names.end(), fname ) != names.end() ) {
+				matches.emplace_back( expr );
+			}
+		}
+
+		void postvisit( const ast::ApplicationExpr * expr ) { handleCallExpr( expr ); }
+		void postvisit( const ast::UntypedExpr *     expr ) { handleCallExpr( expr ); }
+	};
+
 	void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) {
-		static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } );
+		static PassVisitor<CallFinder_old> finder( std::list< std::string >{ "?{}", "^?{}" } );
 		finder.pass.matches = &matches;
 		maybeAccept( stmt, finder );
+	}
+
+	std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) {
+		ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } };
+		maybe_accept( stmt, finder );
+		return std::move( finder.pass.matches );
 	}
 
@@ -436,4 +475,18 @@
 	}
 
+	const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr ) {
+		auto appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr );
+		if ( ! appExpr ) return nullptr;
+
+		const ast::DeclWithType * func = getCalledFunction( appExpr->func );
+		assertf( func, 
+			"getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );
+		
+		// check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 
+		// autogenerated ctor/dtor will call all member dtors, and some members may have a 
+		// user-defined dtor
+		return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;
+	}
+
 	namespace {
 		template <typename Predicate>
@@ -444,4 +497,10 @@
 			return std::all_of( callExprs.begin(), callExprs.end(), pred);
 		}
+
+		template <typename Predicate>
+		bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) {
+			std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt );
+			return std::all_of( callExprs.begin(), callExprs.end(), pred );
+		}
 	}
 
@@ -452,4 +511,16 @@
 				assert( funcType );
 				return funcType->get_parameters().size() == 1;
+			}
+			return false;
+		});
+	}
+
+	bool isIntrinsicSingleArgCallStmt( const ast::Stmt * stmt ) {
+		return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){
+			if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
+				const ast::FunctionType * funcType = 
+					GenPoly::getFunctionType( appExpr->func->result );
+				assert( funcType );
+				return funcType->params.size() == 1;
 			}
 			return false;
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 05d55ffed10db511d8a2eec6a4ec6ccfbd8079dd)
+++ src/InitTweak/InitTweak.h	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// RemoveInit.h --
+// InitTweak.h --
 //
 // Author           : Rob Schluntz
 // Created On       : Fri May 13 11:26:36 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:30:33 2017
-// Update Count     : 4
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Mon Jun 10 13:30:00 2019
+// Update Count     : 5
 //
 
@@ -19,4 +19,5 @@
 #include <memory>             // for shared_ptr
 #include <string>             // for string, allocator
+#include <vector>
 
 #include "AST/Fwd.hpp"        // for AST nodes
@@ -63,4 +64,5 @@
 	/// Non-Null if expr is a call expression whose target function is intrinsic
 	ApplicationExpr * isIntrinsicCallExpr( Expression * expr );
+	const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr);
 
 	/// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
@@ -68,4 +70,5 @@
 	/// Currently has assertions that make it less than fully general.
 	bool isIntrinsicSingleArgCallStmt( Statement * stmt );
+	bool isIntrinsicSingleArgCallStmt( const ast::Stmt * stmt );
 
 	/// True if stmt is a call statement where the function called is intrinsic.
@@ -74,4 +77,5 @@
 	/// get all Ctor/Dtor call expressions from a Statement
 	void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches );
+	std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt );
 
 	/// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
Index: src/ResolvExpr/CurrentObject.cc
===================================================================
--- src/ResolvExpr/CurrentObject.cc	(revision 05d55ffed10db511d8a2eec6a4ec6ccfbd8079dd)
+++ src/ResolvExpr/CurrentObject.cc	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -946,5 +946,78 @@
 	}
 
-	void CurrentObject::setNext( const ast::Designation * designation ) {
+	const Designation * CurrentObject::findNext( const Designation * designation ) {
+		using DesignatorChain = std::deque< ptr< Expr > >;
+		PRINT( std::cerr << "___findNext" << std::endl; )
+		
+		// find all the d's
+		std::vector< DesignatorChain > desigAlts{ {} }, newDesigAlts;
+		std::deque< const Type * > curTypes{ objStack.back()->getType() }, newTypes;
+		for ( const Expr * expr : designation->designators ) {
+			PRINT( std::cerr << "____untyped: " << expr << std::endl; )
+			auto dit = desigAlts.begin();
+			if ( auto nexpr = dynamic_cast< const NameExpr * >( expr ) ) {
+				for ( const Type * t : curTypes ) {
+					assert( dit != desigAlts.end() );
+
+					DesignatorChain & d = *dit;
+					PRINT( std::cerr << "____actual: " << t << std::endl; )
+					if ( auto refType = dynamic_cast< const ReferenceToType * >( t ) ) {
+						// concatenate identical field names
+						for ( const Decl * mem : refType->lookup( nexpr->name ) ) {
+							if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) {
+								PRINT( std::cerr << "____alt: " << field->type << std::endl; )
+								DesignatorChain d2 = d;
+								d2.emplace_back( new VariableExpr{ expr->location, field } );
+								newDesigAlts.emplace_back( std::move( d2 ) );
+								newTypes.emplace_back( field->type );
+							}
+						}
+					}
+
+					++dit;
+				}
+			} else {
+				for ( const Type * t : curTypes ) {
+					assert( dit != desigAlts.end() );
+
+					DesignatorChain & d = *dit;
+					if ( auto at = dynamic_cast< const ArrayType * >( t ) ) {
+						PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; )
+						d.emplace_back( expr );
+						newDesigAlts.emplace_back( d );
+						newTypes.emplace_back( at->base );
+					}
+				}
+			}
+
+			// reset queue
+			desigAlts = std::move( newDesigAlts );
+			newDesigAlts.clear();
+			curTypes = std::move( newTypes );
+			newTypes.clear();
+			assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%zu) and current types (%zu) out of sync", desigAlts.size(), curTypes.size() );
+		}
+
+		if ( desigAlts.size() > 1 ) {
+			SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") );
+		} else if ( desigAlts.empty() ) {
+			SemanticError( designation, "No reasonable alternatives for designation: " );
+		}
+
+		DesignatorChain & d = desigAlts.back();
+		PRINT( for ( Expression * expr : d ) {
+			std::cerr << "____desig: " << expr << std::endl;
+		} ) // for
+		assertf( ! curTypes.empty(), "empty designator chosen");
+
+		// set new designators
+		assertf( ! objStack.empty(), "empty object stack when setting designation" );
+		Designation * actualDesignation = 
+			new Designation{ designation->location, DesignatorChain{d} };
+		objStack.back()->setPosition( d ); // destroys d
+		return actualDesignation;
+	}
+
+	void CurrentObject::setNext( const Designation * designation ) {
 		PRINT( std::cerr << "____setNext" << designation << std::endl; )
 		assertf( ! objStack.empty(), "obj stack empty in setNext" );
Index: src/ResolvExpr/CurrentObject.h
===================================================================
--- src/ResolvExpr/CurrentObject.h	(revision 05d55ffed10db511d8a2eec6a4ec6ccfbd8079dd)
+++ src/ResolvExpr/CurrentObject.h	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -111,4 +111,6 @@
 		CurrentObject( const CodeLocation & loc, const Type * type );
 
+		/// resolves unresolved designation
+		const Designation * findNext( const Designation * designation );
 		/// sets current position using the resolved designation
 		void setNext( const ast::Designation * designation );
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 05d55ffed10db511d8a2eec6a4ec6ccfbd8079dd)
+++ src/ResolvExpr/Resolver.cc	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -1227,7 +1227,7 @@
 		void previsit( const ast::WaitForStmt * );
 
-		const ast::SingleInit * previsit( const ast::SingleInit * );
-		const ast::ListInit * previsit( const ast::ListInit * );
-		void previsit( const ast::ConstructorInit * );
+		const ast::SingleInit *      previsit( const ast::SingleInit * );
+		const ast::ListInit *        previsit( const ast::ListInit * );
+		const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
 	};
 
@@ -1510,7 +1510,14 @@
 			// iterate designations and initializers in pairs, moving the cursor to the current 
 			// designated object and resolving the initializer against that object
-			#warning unimplemented; Resolver port in progress
-			assert(false);
-		}
+			listInit = ast::mutate_field_index(
+				listInit, &ast::ListInit::designations, i, 
+				currentObject.findNext( listInit->designations[i] ) );
+			listInit = ast::mutate_field_index(
+				listInit, &ast::ListInit::initializers, i,
+				listInit->initializers[i]->accept( *visitor ) );
+		}
+
+		// move cursor out of brace-enclosed initializer-list
+		currentObject.exitListInit();
 
 		visit_children = false;
@@ -1518,8 +1525,23 @@
 	}
 
-	void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
-		#warning unimplemented; Resolver port in progress
-		(void)ctorInit;
-		assert(false);
+	const ast::ConstructorInit * Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
+		visitor->maybe_accept( ctorInit, &ast::ConstructorInit::ctor );
+		visitor->maybe_accept( ctorInit, &ast::ConstructorInit::dtor );
+
+		// found a constructor - can get rid of C-style initializer
+		// xxx - Rob suggests this field is dead code
+		ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
+
+		// intrinsic single-parameter constructors and destructors do nothing. Since this was 
+		// implicitly generated, there's no way for it to have side effects, so get rid of it to 
+		// clean up generated code
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
+			ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::ctor, nullptr );
+		}
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
+			ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::dtor, nullptr );
+		}
+
+		return ctorInit;
 	}
 
