Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 69d8a9a5be2e446c02321fa381a47f28e3562c18)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 87c3bef2f36114e3144a18260c66331cd41f4c18)
@@ -226,6 +226,20 @@
 
 			if ( (*baseParam)->isComplete() ) {
-				// substitute parameter for complete (otype or sized dtype) type; makes the struct concrete or dynamic depending on the parameter
-				out.push_back( paramType->clone() );
+				// substitute parameter for complete (otype or sized dtype) type
+				int pointerLevels = 0;
+				if ( hasPolyBase( paramType->get_type(), &pointerLevels ) && pointerLevels > 0 ) {
+					// Make a void* with equivalent nesting
+					Type* voidPtr = new VoidType( Type::Qualifiers() );
+					while ( pointerLevels > 0 ) {
+						// Just about data layout, so qualifiers *shouldn't* matter
+						voidPtr = new PointerType( Type::Qualifiers(), voidPtr );
+						--pointerLevels;
+					}
+					out.push_back( new TypeExpr( voidPtr ) );
+				} else {
+					// Just clone parameter type
+					out.push_back( paramType->clone() );
+				}
+				// make the struct concrete or dynamic depending on the parameter
 				gt |= isPolyType( paramType->get_type() ) ? genericType::dynamic : genericType::concrete;
 			} else switch ( (*baseParam)->get_kind() ) {
