Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 8135d4c79504a6c3047246007261186efa5ba4c9)
+++ src/GenPoly/Lvalue.cc	(revision 9aaac6e93085196ddc22e508c0fdfa1ee11ae660)
@@ -70,6 +70,8 @@
 		};
 
-		struct FixIntrinsicResult final {
+		struct FixIntrinsicResult final : public WithGuards {
 			Expression * postmutate( ApplicationExpr * appExpr );
+			void premutate( FunctionDecl * funcDecl );
+			bool inIntrinsic = false;
 		};
 
@@ -162,10 +164,20 @@
 				appExpr->set_result( result->stripReferences()->clone() );
 				appExpr->get_result()->set_lvalue( true );
-				Expression * ret = new CastExpr( appExpr, result );
-				ret->set_env( appExpr->get_env() );
-				appExpr->set_env( nullptr );
-				return ret;
+				if ( ! inIntrinsic ) {
+					// when not in an intrinsic function, add a cast to
+					// don't add cast when in an intrinsic function, since they already have the cast
+					Expression * ret = new CastExpr( appExpr, result );
+					ret->set_env( appExpr->get_env() );
+					appExpr->set_env( nullptr );
+					return ret;
+				}
+				delete result;
 			}
 			return appExpr;
+		}
+
+		void FixIntrinsicResult::premutate( FunctionDecl * funcDecl ) {
+			GuardValue( inIntrinsic );
+			inIntrinsic =  funcDecl->linkage == LinkageSpec::Intrinsic;
 		}
 
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 8135d4c79504a6c3047246007261186efa5ba4c9)
+++ src/MakeLibCfa.cc	(revision 9aaac6e93085196ddc22e508c0fdfa1ee11ae660)
@@ -16,8 +16,9 @@
 #include "MakeLibCfa.h"
 
-#include <cassert>                 // for assert
+#include <cassert>                  // for assert
 #include <string>                   // for operator==, string
 
 #include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup, Ope...
+#include "Common/PassVisitor.h"     // for PassVisitor
 #include "Common/SemanticError.h"   // for SemanticError
 #include "Common/UniqueName.h"      // for UniqueName
@@ -32,73 +33,110 @@
 
 namespace LibCfa {
-	class MakeLibCfa : public Visitor {
-	  public:
-		void visit( FunctionDecl* funcDecl );
-		void visit( ObjectDecl* objDecl );
+	namespace {
+		struct MakeLibCfa {
+		  public:
+			void postvisit( FunctionDecl* funcDecl );
 
-		std::list< Declaration* > &get_newDecls() { return newDecls; }
-	  private:
-		std::list< Declaration* > newDecls;
-	};
+			std::list< Declaration* > newDecls;
+		};
+	}
 
 	void makeLibCfa( std::list< Declaration* > &prelude ) {
-		MakeLibCfa maker;
+		PassVisitor<MakeLibCfa> maker;
 		acceptAll( prelude, maker );
-		prelude.splice( prelude.end(), maker.get_newDecls() );
+		prelude.splice( prelude.end(), maker.pass.newDecls );
 	}
 
-	void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
-		if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
-		if ( origFuncDecl->get_statements() ) return;
+	namespace {
+		struct TypeFinder	{
+			void postvisit( TypeInstType * inst ) {
+				// if a type variable is seen, assume all zero_t/one_t in the parameter list
+				//  can be replaced with the equivalent 'general' pointer.
+				if ( type ) return;
+				if ( inst->isFtype ) {
+					type = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), false ) );
+				} else {
+					type = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
+				}
+			}
+			Type * type = nullptr;
+		};
 
-		FunctionDecl *funcDecl = origFuncDecl->clone();
-		CodeGen::OperatorInfo opInfo;
-		bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
-		assert( lookResult );
-		assert( ! funcDecl->get_statements() );
-		UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
-		UniqueName paramNamer( "_p" );
-		std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
-		assert( param != funcDecl->get_functionType()->get_parameters().end() );
+		struct ZeroOneReplacer {
+			ZeroOneReplacer( Type * t ) : type( t ) {}
+			~ZeroOneReplacer() { delete type; }
+			Type * type = nullptr;
 
-		for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
-			if ( (*param)->get_name() == "" ) {
-				(*param)->set_name( paramNamer.newName() );
-				(*param)->set_linkage( LinkageSpec::C );
+			Type * common( Type * t ) {
+				if ( ! type ) return t;
+				delete t;
+				return type->clone();
 			}
-			newExpr->get_args().push_back( new VariableExpr( *param ) );
-		} // for
 
-		funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
-		newDecls.push_back( funcDecl );
+			Type * postmutate( OneType * t ) { return common( t ); }
+			Type * postmutate( ZeroType * t ) { return common( t ); }
+		};
 
-		switch ( opInfo.type ) {
-		  case CodeGen::OT_INDEX:
-		  case CodeGen::OT_CALL:
-		  case CodeGen::OT_PREFIX:
-		  case CodeGen::OT_POSTFIX:
-		  case CodeGen::OT_INFIX:
-		  case CodeGen::OT_PREFIXASSIGN:
-		  case CodeGen::OT_POSTFIXASSIGN:
-		  case CodeGen::OT_INFIXASSIGN:
-		  case CodeGen::OT_CTOR:
-		  case CodeGen::OT_DTOR:
-				funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
-				break;
-		  case CodeGen::OT_CONSTANT:
-		  case CodeGen::OT_LABELADDRESS:
-			// there are no intrinsic definitions of 0/1 or label addresses as functions
-			assert( false );
-		} // switch
-	}
+		void fixZeroOneType( FunctionDecl * origFuncDecl ) {
+			// find appropriate type to replace zero_t/one_t with
+			PassVisitor<TypeFinder> finder;
+			origFuncDecl->type->accept( finder );
+			// replace zero_t/one_t in function type
+			PassVisitor<ZeroOneReplacer> replacer( finder.pass.type );
+			origFuncDecl->type->acceptMutator( replacer );
+		}
 
-	void MakeLibCfa::visit( ObjectDecl* origObjDecl ) {
-		if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
+		void MakeLibCfa::postvisit( FunctionDecl* origFuncDecl ) {
+			// don't change non-intrinsic functions
+			if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
+			// replace zero_t/one_t with void */void (*)(void)
+			fixZeroOneType( origFuncDecl );
+			// skip functions already defined
+			if ( origFuncDecl->get_statements() ) return;
 
-		ObjectDecl *objDecl = origObjDecl->clone();
-		assert( ! objDecl->get_init() );
-		std::list< Expression* > noDesignators;
-		objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed
-		newDecls.push_back( objDecl );
-	}
+			FunctionDecl *funcDecl = origFuncDecl->clone();
+			CodeGen::OperatorInfo opInfo;
+			bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
+			assert( lookResult );
+			assert( ! funcDecl->get_statements() );
+			// build a recursive call - this is okay, as the call will actually be codegen'd using operator syntax
+			UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
+			UniqueName paramNamer( "_p" );
+			std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
+			assert( param != funcDecl->get_functionType()->get_parameters().end() );
+
+			for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
+				// name each unnamed parameter
+				if ( (*param)->get_name() == "" ) {
+					(*param)->set_name( paramNamer.newName() );
+					(*param)->set_linkage( LinkageSpec::C );
+				}
+				// add parameter to the expression
+				newExpr->get_args().push_back( new VariableExpr( *param ) );
+			} // for
+
+			funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
+			newDecls.push_back( funcDecl );
+
+			switch ( opInfo.type ) {
+			  case CodeGen::OT_INDEX:
+			  case CodeGen::OT_CALL:
+			  case CodeGen::OT_PREFIX:
+			  case CodeGen::OT_POSTFIX:
+			  case CodeGen::OT_INFIX:
+			  case CodeGen::OT_PREFIXASSIGN:
+			  case CodeGen::OT_POSTFIXASSIGN:
+			  case CodeGen::OT_INFIXASSIGN:
+			  case CodeGen::OT_CTOR:
+			  case CodeGen::OT_DTOR:
+			  	// return the recursive call
+					funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
+					break;
+			  case CodeGen::OT_CONSTANT:
+			  case CodeGen::OT_LABELADDRESS:
+				// there are no intrinsic definitions of 0/1 or label addresses as functions
+				assert( false );
+			} // switch
+		}
+	} // namespace
 } // namespace LibCfa
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 8135d4c79504a6c3047246007261186efa5ba4c9)
+++ src/SynTree/Declaration.h	(revision 9aaac6e93085196ddc22e508c0fdfa1ee11ae660)
@@ -109,5 +109,5 @@
 	virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
 
-	virtual Type *get_type() const = 0;
+	virtual Type * get_type() const = 0;
 	virtual void set_type(Type *) = 0;
 
@@ -128,5 +128,5 @@
 	virtual ~ObjectDecl();
 
-	virtual Type *get_type() const { return type; }
+	virtual Type * get_type() const { return type; }
 	virtual void set_type(Type *newType) { type = newType; }
 
@@ -155,8 +155,8 @@
 	virtual ~FunctionDecl();
 
-	Type *get_type() const;
+	Type * get_type() const;
 	virtual void set_type(Type *);
 
-	FunctionType *get_functionType() const { return type; }
+	FunctionType * get_functionType() const { return type; }
 	void set_functionType( FunctionType *newValue ) { type = newValue; }
 	CompoundStmt *get_statements() const { return statements; }
