Index: src/ResolvExpr/CastCost.cpp
===================================================================
--- src/ResolvExpr/CastCost.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
+++ src/ResolvExpr/CastCost.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -54,10 +54,9 @@
 			cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
 
-			if (Cost::unsafe < cost) {
+			if ( !enumInst->base->isCfa ) {
 				static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
 				Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
 				cost = intCost < cost? intCost: cost;
-			}
-			if ( enumInst->base->isTyped && enumInst->base->base ) {
+			} else if ( enumInst->base->isTyped() ) {
 				auto baseConversionCost = 
 					castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
@@ -74,7 +73,6 @@
 				cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
 				if ( Cost::unsafe < cost ) {
-					if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
-						// Always explict cast only for typed enum
-						if (enumInst->base->isTyped) cost = Cost::unsafe;
+					if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
+						cost = Cost::unsafe;
 					}
 				}
@@ -85,6 +83,6 @@
 			cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
 			if ( Cost::unsafe < cost ) {
-				if (auto enumInst =  dynamic_cast<const ast::EnumInstType *>(dst)) {
-					if (enumInst->base->isTyped) cost = Cost::unsafe;
+				if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
+					cost = Cost::unsafe;
 				}
 			}
@@ -94,6 +92,6 @@
 			cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
 			if ( Cost::unsafe < cost ) {
-				if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
-					if (enumInst->base->isTyped) cost = Cost::unsafe;
+				if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
+					cost = Cost::unsafe;
 				}
 			}
Index: src/ResolvExpr/CommonType.cpp
===================================================================
--- src/ResolvExpr/CommonType.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
+++ src/ResolvExpr/CommonType.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -386,5 +386,5 @@
 		} else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
 			const ast::EnumDecl* enumDecl = enumInst->base;
-			if ( !enumDecl->base ) {
+			if ( !enumDecl->isCfa  ) {
 				ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
 				if (
@@ -642,5 +642,5 @@
 			const ast::EnumDecl* argDecl = argAsEnumInst->base;
 			if (argDecl->isSubTypeOf(paramDecl)) result = param;
-		} else if ( param->base && !param->base->isTyped ) {
+		} else if ( param->base && !param->base->isCfa ) {
 			auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
 			result = commonType( basicType, type2, tenv, need, have, open, widen);
Index: src/ResolvExpr/ConversionCost.cpp
===================================================================
--- src/ResolvExpr/ConversionCost.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
+++ src/ResolvExpr/ConversionCost.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -235,9 +235,20 @@
 			return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
 		}
+		if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
+			if (srcAsInst->base && !srcAsInst->base->isCfa) {
+				static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
+				return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
+			}
+		}
 	} else {
 		assert( -1 == diff );
 		const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
 		assert( dstAsRef );
-		if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
+		auto dstBaseType = dstAsRef->base;
+		const ast::Type * newSrc = src;
+		if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
+			newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
+		}
+		if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
 			if ( srcIsLvalue ) {
 				if ( src->qualifiers == dstAsRef->base->qualifiers ) {
@@ -285,6 +296,6 @@
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
-			cost = Cost::unsafe;
+		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+			cost = Cost::safe;
 		}
 	}
@@ -366,14 +377,7 @@
 	if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
 		cost = enumCastCost(inst, dstInst, symtab, env);
-		return;
-	}
-
-	if ( !inst->base->isTyped ) {
+	} else if ( !inst->base->isCfa ) {
 		static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
 		cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
-		if ( cost < Cost::unsafe ) {
-			cost.incSafe();
-		}
-		return;
 	}
 	// cost.incUnsafe();
@@ -455,6 +459,6 @@
 		// assuming 0p is supposed to be used for pointers?
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
-			cost = Cost::unsafe;
+		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+			cost = Cost::safe;
 		}
 	}
@@ -476,6 +480,6 @@
 		}
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
-			cost = Cost::unsafe;
+		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+			cost = Cost::safe;
 		}
 	}
