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 // 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, ConstVal.GetDefaultValue(_typeDest.constValKind())); } return(true); } return(false); }