private bool bindImplicitConversionToEnum(AggregateType aggTypeSrc)
{
// The spec states:
// *****************
// 13.1.3 Implicit enumeration conversions
//
// An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any
// enum-type.
// *****************
// However, we actually allow any constant zero, not just the integer literal zero, to be converted
// to enum. The reason for this is for backwards compatibility with a premature optimization
// that used to be in the binding layer. We would optimize away expressions such as 0 | blah to be
// just 0, but not erase the "is literal" bit. This meant that expression such as 0 | 0 | E.X
// would succeed rather than correctly producing an error pointing out that 0 | 0 is not a literal
// zero and therefore does not convert to any enum.
//
// We have removed the premature optimization but want old code to continue to compile. Rather than
// try to emulate the somewhat complex behaviour of the previous optimizer, it is easier to simply
// say that any compile time constant zero is convertible to any enum. This means unfortunately
// expressions such as (7-7) * 12 are convertible to enum, but frankly, that's better than having
// some terribly complex rule about what constitutes a legal zero and what doesn't.
// Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
if (
aggTypeSrc.getAggregate().GetPredefType() != PredefinedType.PT_BOOL &&
exprSrc != null &&
exprSrc.isZero() &&
exprSrc.type.isNumericType() &&
/*(exprSrc.flags & EXF_LITERALCONST) &&*/
0 == (flags & CONVERTTYPE.STANDARD))
{
// NOTE: This allows conversions from uint, long, ulong, float, double, and hexadecimal int
// NOTE: This is for backwards compatibility with Everett
// REVIEW: : This is another place where we lose EXPR fidelity. We shouldn't fold this
// into a constant here - we should move this to a later pass.
if (needsExprDest)
{
exprDest = GetExprFactory().CreateConstant(typeDest, ConstValFactory.GetDefaultValue(typeDest.constValKind()));
}
return(true);
}
return(false);
}