Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision e1f7eefc84701acc2af857cd1c484e5650e81cba)
+++ src/ResolvExpr/ConversionCost.cc	(revision 4cf2472f2b5659dfb57b51b9748e18e9dcb9c543)
@@ -28,12 +28,13 @@
 
 namespace ResolvExpr {
-	const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0 };
-	const Cost Cost::infinity =  Cost{ -1, -1, -1, -1,  1, -1 };
-	const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0 };
-	const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0 };
-	const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0 };
-	const Cost Cost::var =       Cost{  0,  0,  0,  1,  0,  0 };
-	const Cost Cost::spec =      Cost{  0,  0,  0,  0, -1,  0 };
-	const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  1 };
+	const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0,  0 };
+	const Cost Cost::infinity =  Cost{ -1, -1, -1, -1, -1,  1, -1 };
+	const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0,  0 };
+	const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0,  0 };
+	const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0,  0 };
+	const Cost Cost::sign =      Cost{  0,  0,  0,  1,  0,  0,  0 };
+	const Cost Cost::var =       Cost{  0,  0,  0,  0,  1,  0,  0 };
+	const Cost Cost::spec =      Cost{  0,  0,  0,  0,  0, -1,  0 };
+	const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  0,  1 };
 
 #if 0
@@ -266,4 +267,40 @@
 	);
 
+	static const int signMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
+	/* Src \ Dest:	Bool	Char	SChar	UChar	Short	UShort	Int 	UInt	Long	ULong	LLong	ULLong	Float	Double	LDbl	FCplex	DCplex	LDCplex	FImag	DImag	LDImag	I128,	U128, F80, F128 */
+		/* Bool */ 	{ 0,	1,		1,		0,		1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+		/* Char */ 	{ -1,	0,		-1,		1,		0,		1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* SChar */ { -1,	-1,		0,		1,		0,		1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* UChar */ { -1,	-1,		-1,		0,		1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+		/* Short */ { -1,	-1,		-1,		-1,		0,		1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* UShort */{ -1,	-1,		-1,		-1,		-1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+		/* Int */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		0,		1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* UInt */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		0,		1,		0,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+		/* Long */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		0,		1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* ULong */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		0,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+		/* LLong */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* ULLong */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+
+		/* Float */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		-1,		-1,	  0,    0},
+		/* Double */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		-1,		0,		0,		-1,		-1,		-1,		-1,		-1,	  0,    0},
+		/* LDbl */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		0,		-1,		-1,		-1,		-1,		-1,	  -1,   0},
+		/* FCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		0,		-1,		-1,		-1,		-1,		-1,	  -1,   -1},
+		/* DCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		-1,		-1,		-1,		-1,		-1,	  -1,   -1},
+		/* LDCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		-1,		-1,		-1,	  -1,   -1},
+		/* FImag */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		0,		0,		0,		0,		-1,		-1,	  -1,   -1},
+		/* DImag */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		-1,		0,		0,		-1,		-1,	  -1,   -1},
+		/* LDImag */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		0,		-1,		-1,	  -1,   -1},
+
+		/* I128 */  { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		0,		1,	  0,    0},
+		/* U128 */  { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		0,		0,		0,		0,		0,		-1,		-1,		-1,		1,		0,	  0,    0},
+
+		/* F80 */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		0,		-1,		-1,		-1,		-1,		-1,	  0,    0},
+		/* F128 */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		-1,		-1,		-1,	  -1,   0},
+	};
+	static_assert(
+		sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
+		"Each basic type kind should have a corresponding row in the sign matrix"
+	);
+
 
 	void ConversionCost::postvisit( VoidType * ) {
@@ -279,4 +316,5 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult );
+				cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
 			} // if
 		} else if ( dynamic_cast< EnumInstType *>( dest ) ) {
@@ -422,4 +460,5 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult + 1 );
+				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
 			}
 		} else if ( dynamic_cast< PointerType* >( dest ) ) {
@@ -439,4 +478,5 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult + 1 );
+				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
 			}
 		}
Index: src/ResolvExpr/Cost.h
===================================================================
--- src/ResolvExpr/Cost.h	(revision e1f7eefc84701acc2af857cd1c484e5650e81cba)
+++ src/ResolvExpr/Cost.h	(revision 4cf2472f2b5659dfb57b51b9748e18e9dcb9c543)
@@ -21,6 +21,6 @@
 	class Cost {
 	  private:
-		Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost,
-			int referenceCost );
+		Cost( int unsafeCost, int polyCost, int safeCost, int signCost, 
+			int varCost, int specCost, int referenceCost );
 
 	  public:
@@ -28,4 +28,5 @@
 		Cost & incPoly( int inc = 1 );
 		Cost & incSafe( int inc = 1 );
+		Cost & incSign( int inc = 1 );
 		Cost & incVar( int inc = 1 );
 		Cost & decSpec( int inc = 1 );
@@ -35,4 +36,5 @@
 		int get_polyCost() const { return polyCost; }
 		int get_safeCost() const { return safeCost; }
+		int get_signCost() const { return signCost; }
 		int get_varCost() const { return varCost; }
 		int get_specCost() const { return specCost; }
@@ -40,5 +42,4 @@
 
 		Cost operator+( const Cost &other ) const;
-		Cost operator-( const Cost &other ) const;
 		Cost &operator+=( const Cost &other );
 		bool operator<( const Cost &other ) const;
@@ -55,4 +56,5 @@
 		static const Cost poly;
 		static const Cost safe;
+		static const Cost sign;
 		static const Cost var;
 		static const Cost spec;
@@ -63,4 +65,5 @@
 		int polyCost;       ///< Count of parameters and return values bound to some poly type
 		int safeCost;       ///< Safe (widening) conversions
+		int signCost;       ///< Count of safe sign conversions
 		int varCost;        ///< Count of polymorphic type variables
 		int specCost;       ///< Polymorphic type specializations (type assertions), negative cost
@@ -68,8 +71,8 @@
 	};
 
-	inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost, 
-			int referenceCost ) 
-		: unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), varCost( varCost ), 
-		  specCost( specCost ), referenceCost( referenceCost ) {}
+	inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost, 
+			int varCost, int specCost, int referenceCost ) 
+		: unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ), 
+		  varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}
 
 	inline Cost & Cost::incUnsafe( int inc ) {
@@ -88,4 +91,10 @@
 		if ( *this == infinity ) return *this;
 		safeCost += inc;
+		return *this;
+	}
+
+	inline Cost & Cost::incSign( int inc ) {
+		if ( *this == infinity ) return *this;
+		signCost += inc;
 		return *this;
 	}
@@ -113,14 +122,6 @@
 		return Cost{ 
 			unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, 
-			varCost + other.varCost, specCost + other.specCost, 
+			signCost + other.signCost, varCost + other.varCost, specCost + other.specCost, 
 			referenceCost + other.referenceCost };
-	}
-
-	inline Cost Cost::operator-( const Cost &other ) const {
-		if ( *this == infinity || other == infinity ) return infinity;
-		return Cost{ 
-			unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, 
-			varCost - other.varCost, specCost - other.specCost, 
-			referenceCost - other.referenceCost };
 	}
 
@@ -134,4 +135,5 @@
 		polyCost += other.polyCost;
 		safeCost += other.safeCost;
+		signCost += other.signCost;
 		varCost += other.varCost;
 		specCost += other.specCost;
@@ -156,4 +158,8 @@
 		} else if ( safeCost < other.safeCost ) {
 			return true;
+		} else if ( signCost > other.signCost ) {
+			return false;
+		} else if ( signCost < other.signCost ) {
+			return true;
 		} else if ( varCost > other.varCost ) {
 			return false;
@@ -180,4 +186,5 @@
 		c = polyCost - other.polyCost; if ( c ) return c;
 		c = safeCost - other.safeCost; if ( c ) return c;
+		c = signCost - other.signCost; if ( c ) return c;
 		c = varCost - other.varCost; if ( c ) return c;
 		c = specCost - other.specCost; if ( c ) return c;
@@ -189,4 +196,5 @@
 			&& polyCost == other.polyCost
 			&& safeCost == other.safeCost
+			&& signCost == other.signCost
 			&& varCost == other.varCost
 			&& specCost == other.specCost
@@ -200,5 +208,6 @@
 	inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
 		return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " 
-		          << cost.safeCost << ", " << cost.varCost << ", " << cost.specCost << ", "
+		          << cost.safeCost << ", " << cost.signCost << ", " 
+				  << cost.varCost << ", " << cost.specCost << ", "
 		          << cost.referenceCost << " )";
 	}
