Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 598f50e631482d663e6fec6a88a01a10da3968a2)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision b0837e4dfda21dcfd8fa2bbaaaf2078ad86ba096)
@@ -122,4 +122,8 @@
 						)
 						mapPlace->second.isAmbiguous = true;
+					} else {
+						PRINT(
+							std::cerr << "cost " << candidate->cost << " loses to " << mapPlace->second.candidate->cost << std::endl;
+						)
 					}
 				} else {
@@ -127,8 +131,4 @@
 				}
 			}
-
-			PRINT(
-				std::cerr << "there are " << selected.size() << " alternatives before elimination" << std::endl;
-			)
 
 			// accept the alternatives that were unambiguous
@@ -181,4 +181,5 @@
 		}
 		if ( prune ) {
+			auto oldsize = alternatives.size();
 			PRINT(
 				std::cerr << "alternatives before prune:" << std::endl;
@@ -198,4 +199,7 @@
 			}
 			alternatives.erase( oldBegin, alternatives.end() );
+			PRINT(
+				std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl;
+			)
 			PRINT(
 				std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 598f50e631482d663e6fec6a88a01a10da3968a2)
+++ src/ResolvExpr/ConversionCost.cc	(revision b0837e4dfda21dcfd8fa2bbaaaf2078ad86ba096)
@@ -28,10 +28,10 @@
 
 namespace ResolvExpr {
-	const Cost Cost::zero = Cost( 0, 0, 0, 0 );
-	const Cost Cost::infinity = Cost( -1, -1, -1, -1 );
-	const Cost Cost::unsafe = Cost( 1, 0, 0, 0 );
-	const Cost Cost::poly = Cost( 0, 1, 0, 0 );
-	const Cost Cost::safe = Cost( 0, 0, 1, 0 );
-	const Cost Cost::reference = Cost( 0, 0, 0, 1 );
+	const Cost Cost::zero =      Cost(  0,  0,  0,  0 );
+	const Cost Cost::infinity =  Cost( -1, -1, -1, -1 );
+	const Cost Cost::unsafe =    Cost(  1,  0,  0,  0 );
+	const Cost Cost::poly =      Cost(  0,  1,  0,  0 );
+	const Cost Cost::safe =      Cost(  0,  0,  1,  0 );
+	const Cost Cost::reference = Cost(  0,  0,  0,  1 );
 
 #if 0
@@ -113,7 +113,7 @@
 					int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
 					PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
-					if ( assignResult < 0 ) {
+					if ( assignResult > 0 ) {
 						return Cost::safe;
-					} else if ( assignResult > 0 ) {
+					} else if ( assignResult < 0 ) {
 						return Cost::unsafe;
 					} // if
@@ -269,5 +269,5 @@
 	}
 
-	void ConversionCost::visit(PointerType *pointerType) {
+	void ConversionCost::visit( PointerType * pointerType ) {
 		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
 			PRINT( std::cerr << pointerType << " ===> " << destAsPtr; )
@@ -284,21 +284,21 @@
 				}
 			} else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
-				int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
+				int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
 				PRINT( std::cerr << " :: " << assignResult << std::endl; )
-				if ( assignResult < 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
+				if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
 					cost = Cost::safe;
-				} else if ( assignResult > 0 ) {
+				} else if ( assignResult < 0 ) {
 					cost = Cost::unsafe;
 				} // if
 				// assignResult == 0 means Cost::Infinity
 			} // if
-		} else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
+		} else if ( dynamic_cast< ZeroType * >( dest ) ) {
 			cost = Cost::unsafe;
 		} // if
 	}
 
-	void ConversionCost::visit(__attribute((unused)) ArrayType *arrayType) {}
-
-	void ConversionCost::visit(ReferenceType *refType) {
+	void ConversionCost::visit( ArrayType * ) {}
+
+	void ConversionCost::visit( ReferenceType * refType ) {
 		// Note: dest can never be a reference, since it would have been caught in an earlier check
 		assert( ! dynamic_cast< ReferenceType * >( dest ) );
@@ -317,7 +317,7 @@
 	}
 
-	void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {}
-
-	void ConversionCost::visit(StructInstType *inst) {
+	void ConversionCost::visit( FunctionType * ) {}
+
+	void ConversionCost::visit( StructInstType * inst ) {
 		if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
@@ -327,5 +327,5 @@
 	}
 
-	void ConversionCost::visit(UnionInstType *inst) {
+	void ConversionCost::visit( UnionInstType * inst ) {
 		if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
@@ -335,5 +335,5 @@
 	}
 
-	void ConversionCost::visit( __attribute((unused)) EnumInstType *inst ) {
+	void ConversionCost::visit( EnumInstType * ) {
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
@@ -344,8 +344,7 @@
 	}
 
-	void ConversionCost::visit( __attribute((unused)) TraitInstType *inst) {
-	}
-
-	void ConversionCost::visit(TypeInstType *inst) {
+	void ConversionCost::visit( TraitInstType * ) {}
+
+	void ConversionCost::visit( TypeInstType *inst ) {
 		EqvClass eqvClass;
 		NamedTypeDecl *namedType;
@@ -366,9 +365,9 @@
 	}
 
-	void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) {
+	void ConversionCost::visit( TupleType * tupleType ) {
 		Cost c = Cost::zero;
-		if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
-			std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
-			std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
+		if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
+			std::list< Type * >::const_iterator srcIt = tupleType->get_types().begin();
+			std::list< Type * >::const_iterator destIt = destAsTuple->get_types().begin();
 			while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
 				Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
@@ -386,5 +385,5 @@
 	}
 
-	void ConversionCost::visit( __attribute((unused)) VarArgsType *varArgsType) {
+	void ConversionCost::visit( VarArgsType * ) {
 		if ( dynamic_cast< VarArgsType* >( dest ) ) {
 			cost = Cost::zero;
@@ -392,6 +391,6 @@
 	}
 
-	void ConversionCost::visit( __attribute((unused)) ZeroType *zeroType) {
-		if ( dynamic_cast< ZeroType* >( dest ) ) {
+	void ConversionCost::visit( ZeroType * ) {
+		if ( dynamic_cast< ZeroType * >( dest ) ) {
 			cost = Cost::zero;
 		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
@@ -409,6 +408,6 @@
 	}
 
-	void ConversionCost::visit( __attribute((unused)) OneType *oneType) {
-		if ( dynamic_cast< OneType* >( dest ) ) {
+	void ConversionCost::visit( OneType * ) {
+		if ( dynamic_cast< OneType * >( dest ) ) {
 			cost = Cost::zero;
 		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
Index: src/ResolvExpr/PolyCost.cc
===================================================================
--- src/ResolvExpr/PolyCost.cc	(revision 598f50e631482d663e6fec6a88a01a10da3968a2)
+++ src/ResolvExpr/PolyCost.cc	(revision b0837e4dfda21dcfd8fa2bbaaaf2078ad86ba096)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// PolyCost.cc -- 
+// PolyCost.cc --
 //
 // Author           : Richard C. Bilson
@@ -31,5 +31,5 @@
 	};
 
-	int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+	int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {
 		PolyCost coster( env, indexer );
 		type->accept( coster );
@@ -37,16 +37,18 @@
 	}
 
-	PolyCost::PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer ) : result( 0 ), env( env ), indexer( indexer ) {
+	PolyCost::PolyCost( const TypeEnvironment & env, const SymTab::Indexer & indexer ) : result( 0 ), env( env ), indexer( indexer ) {
 	}
 
-	void PolyCost::visit(TypeInstType *typeInst) {
+	void PolyCost::visit(TypeInstType * typeInst) {
 		EqvClass eqvClass;
-		if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
+		if ( env.lookup( typeInst->name, eqvClass ) ) {
 			if ( eqvClass.type ) {
-				if ( TypeInstType *otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
-					if ( indexer.lookupType( otherTypeInst->get_name() ) ) {
+				if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
+					if ( indexer.lookupType( otherTypeInst->name ) ) {
+						// bound to opaque type
 						result += 1;
 					} // if
 				} else {
+					// bound to concrete type
 					result += 1;
 				} // if
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision 598f50e631482d663e6fec6a88a01a10da3968a2)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision b0837e4dfda21dcfd8fa2bbaaaf2078ad86ba096)
@@ -47,4 +47,5 @@
 
 	int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
+		// std::cerr << "assignable: " << src << " | " << dest << std::endl;
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
 			EqvClass eqvClass;
@@ -54,5 +55,7 @@
 		} // if
 		if ( dynamic_cast< VoidType* >( dest ) ) {
-			return 1;
+			// void * = T * for any T is unsafe
+			// xxx - this should be safe, but that currently breaks the build
+			return -1;
 		} else {
 			PtrsAssignable ptrs( dest, env );
@@ -65,8 +68,8 @@
 
 	void PtrsAssignable::visit( __attribute((unused)) VoidType *voidType ) {
-		if ( dynamic_cast< FunctionType* >( dest ) ) {
-			result = 0;
-		} else {
-			result = -1;
+		if ( ! dynamic_cast< FunctionType* >( dest ) ) {
+			// T * = void * is safe for any T that is not a function type.
+			// xxx - this should be unsafe...
+			result = 1;
 		} // if
 	}
@@ -75,7 +78,5 @@
 	void PtrsAssignable::visit( __attribute__((unused)) PointerType *pointerType ) {}
 	void PtrsAssignable::visit( __attribute__((unused)) ArrayType *arrayType ) {}
-	void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {
-		result = -1;
-	}
+	void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {}
 
 	void PtrsAssignable::visit(  __attribute__((unused)) StructInstType *inst ) {}
@@ -83,8 +84,11 @@
 
 	void PtrsAssignable::visit( EnumInstType * ) {
-		if ( dynamic_cast< EnumInstType* >( dest ) ) {
+		if ( dynamic_cast< BasicType* >( dest ) ) {
+			// int * = E *, etc. is safe. This isn't technically correct, as each
+			// enum has one basic type that it is compatible with, an that type can
+			// differ from enum to enum. Without replicating GCC's internal logic,
+			// there is no way to know which type this particular enum is compatible
+			// with, so punt on this for now.
 			result = 1;
-		} else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
-			result = bt->get_kind() == BasicType::SignedInt;
 		}
 	}
@@ -94,7 +98,6 @@
 		EqvClass eqvClass;
 		if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
+			// T * = S * for any S depends on the type bound to T
 			result = ptrsAssignable( eqvClass.type, dest, env );
-		} else {
-			result = 0;
 		} // if
 	}
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision 598f50e631482d663e6fec6a88a01a10da3968a2)
+++ src/ResolvExpr/PtrsCastable.cc	(revision b0837e4dfda21dcfd8fa2bbaaaf2078ad86ba096)
@@ -50,25 +50,27 @@
 	};
 
-	int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-		if ( dynamic_cast< FunctionType* >( src ) ) {
-			return -1;
-		} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
-			EqvClass eqvClass;
-			if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
-				if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
-					if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
+	namespace {
+		int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+			if ( dynamic_cast< FunctionType* >( src ) ) {
+				return -1;
+			} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
+				EqvClass eqvClass;
+				if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
+					if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
+						if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
+							return -1;
+						} // if
+					} //if
+				} else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
+					if ( eqvClass.data.kind == TypeDecl::Ftype ) {
 						return -1;
 					} // if
-				} //if
-			} else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
-				if ( eqvClass.data.kind == TypeDecl::Ftype ) {
-					return -1;
 				} // if
-			} // if
-		} //if
-		return 1;
-	}
-	int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-		return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
+			} //if
+			return 1;
+		}
+		int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+			return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
+		}
 	}
 
@@ -93,34 +95,34 @@
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) VoidType *voidType) {
+	void PtrsCastable::visit( VoidType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) BasicType *basicType) {
+	void PtrsCastable::visit( BasicType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) PointerType *pointerType) {
+	void PtrsCastable::visit( PointerType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) ArrayType *arrayType) {
+	void PtrsCastable::visit( ArrayType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) FunctionType *functionType) {
+	void PtrsCastable::visit( FunctionType * ) {
 		// result = -1;
 		result = functionCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) StructInstType *inst) {
+	void PtrsCastable::visit( StructInstType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) UnionInstType *inst) {
+	void PtrsCastable::visit( UnionInstType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) EnumInstType *inst) {
+	void PtrsCastable::visit( EnumInstType * ) {
 		if ( dynamic_cast< EnumInstType* >( dest ) ) {
 			result = 1;
@@ -136,5 +138,5 @@
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) TraitInstType *inst ) {}
+	void PtrsCastable::visit( TraitInstType * ) {}
 
 	void PtrsCastable::visit(TypeInstType *inst) {
@@ -143,17 +145,17 @@
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) TupleType *tupleType) {
+	void PtrsCastable::visit( TupleType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) VarArgsType *varArgsType) {
+	void PtrsCastable::visit( VarArgsType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) ZeroType *zeroType) {
+	void PtrsCastable::visit( ZeroType * ) {
 		result = objectCast( dest, env, indexer );
 	}
 
-	void PtrsCastable::visit( __attribute__((unused)) OneType *oneType) {
+	void PtrsCastable::visit( OneType * ) {
 		result = objectCast( dest, env, indexer );
 	}
