Author: marek Date: 2008-02-20 12:28:30 -0500 (Wed, 20 Feb 2008) New Revision: 96275
Modified: trunk/mcs/mcs/ChangeLog trunk/mcs/mcs/cfold.cs trunk/mcs/mcs/constant.cs trunk/mcs/mcs/expression.cs Log: 2008-02-20 Marek Safar <[EMAIL PROTECTED]> * expression.cs, constant.cs, cfold.cs: Yet another side-effect constant update. This time to deal correctly with SideEffectConstant expression used as an argument for another constant folding. Modified: trunk/mcs/mcs/ChangeLog =================================================================== --- trunk/mcs/mcs/ChangeLog 2008-02-20 17:21:42 UTC (rev 96274) +++ trunk/mcs/mcs/ChangeLog 2008-02-20 17:28:30 UTC (rev 96275) @@ -1,3 +1,9 @@ +2008-02-20 Marek Safar <[EMAIL PROTECTED]> + + * expression.cs, constant.cs, cfold.cs: Yet another side-effect constant + update. This time to deal correctly with SideEffectConstant expression used + as an argument for another constant folding. + 2008-02-20 Raja R Harinath <[EMAIL PROTECTED]> * typemanager.cs (DropGenericMethodArguments): Ensure we get an underlying Modified: trunk/mcs/mcs/cfold.cs =================================================================== --- trunk/mcs/mcs/cfold.cs 2008-02-20 17:21:42 UTC (rev 96274) +++ trunk/mcs/mcs/cfold.cs 2008-02-20 17:28:30 UTC (rev 96275) @@ -55,22 +55,31 @@ static public Constant BinaryFold (EmitContext ec, Binary.Operator oper, Constant left, Constant right, Location loc) { + Constant result = null; + if (left is EmptyConstantCast) return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc); - if (left is SideEffectConstant) - return BinaryFold (ec, oper, ((SideEffectConstant) left).left, right, loc); + if (left is SideEffectConstant) { + result = BinaryFold (ec, oper, ((SideEffectConstant) left).left, right, loc); + if (result == null) + return null; + return new SideEffectConstant (result, left, loc); + } if (right is EmptyConstantCast) return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc); - if (right is SideEffectConstant) - return BinaryFold (ec, oper, left, ((SideEffectConstant) right).left, loc); + if (right is SideEffectConstant) { + result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).left, loc); + if (result == null) + return null; + return new SideEffectConstant (result, right, loc); + } Type lt = left.Type; Type rt = right.Type; bool bool_res; - Constant result = null; if (lt == TypeManager.bool_type && lt == rt) { bool lv = ((BoolConstant) left ).Value; Modified: trunk/mcs/mcs/constant.cs =================================================================== --- trunk/mcs/mcs/constant.cs 2008-02-20 17:21:42 UTC (rev 96274) +++ trunk/mcs/mcs/constant.cs 2008-02-20 17:28:30 UTC (rev 96275) @@ -1784,6 +1784,15 @@ public override void Emit (EmitContext ec) { + // + // This happens when both sides have side-effects and + // the result is a constant + // + if (left is SideEffectConstant) { + left.Emit (ec); + ec.ig.Emit (OpCodes.Pop); + } + right.Emit (ec); } Modified: trunk/mcs/mcs/expression.cs =================================================================== --- trunk/mcs/mcs/expression.cs 2008-02-20 17:21:42 UTC (rev 96274) +++ trunk/mcs/mcs/expression.cs 2008-02-20 17:28:30 UTC (rev 96275) @@ -2529,11 +2529,14 @@ return null; Constant lc = left as Constant; - if (lc != null && lc.Type == TypeManager.bool_type && - ((oper == Operator.LogicalAnd && (bool)lc.GetValue () == false) || - (oper == Operator.LogicalOr && (bool)lc.GetValue () == true))) { - // TODO: make a sense to resolve unreachable expression as we do for statement + if (lc != null && lc.Type == TypeManager.bool_type && + ((oper == Operator.LogicalAnd && lc.IsDefaultValue) || + (oper == Operator.LogicalOr && !lc.IsDefaultValue))) { + + // FIXME: resolve right expression as unreachable + // right.Resolve (ec); + Report.Warning (429, 4, loc, "Unreachable expression code detected"); return left; } @@ -2556,54 +2559,34 @@ return null; } - if (oper == Operator.BitwiseAnd) { - if (rc != null && rc.IsZeroInteger) { - return lc is EnumConstant ? - new EnumConstant (rc, lc.Type): - rc; - } + if (rc != null && lc != null) { + int prev_e = Report.Errors; + Expression e = ConstantFold.BinaryFold ( + ec, oper, lc, rc, loc); + if (e != null || Report.Errors != prev_e) + return e; + } else { + if ((oper == Operator.BitwiseAnd || oper == Operator.LogicalAnd) && + ((lc != null && lc.IsDefaultValue) || (rc != null && rc.IsDefaultValue))) { - if (lc != null && lc.IsZeroInteger) { - if (rc is EnumConstant) - return new EnumConstant (lc, rc.Type); + if ((ResolveOperator (ec)) == null) + return null; - // - // Optimize cases that have no side-effects - // - if (rc != null) + if (rc != null) { + right = left; + lc = rc; + } + + // TODO: there must be better way how to check that the expression + // does not have any mutator + if (right is MemberExpr) return lc; - // Side effect code: + // The result is a constant with side-effect return new SideEffectConstant (lc, right, loc); } } - else if (oper == Operator.BitwiseOr) { - if (lc is EnumConstant && - rc != null && rc.IsZeroInteger) - return lc; - if (rc is EnumConstant && - lc != null && lc.IsZeroInteger) - return rc; - } else if (oper == Operator.LogicalAnd) { - if (rc != null && rc.IsDefaultValue && rc.Type == TypeManager.bool_type) { - if (lc != null) - return rc; - return new SideEffectConstant (rc, left, loc); - } - - if (lc != null && lc.IsDefaultValue && lc.Type == TypeManager.bool_type) - return lc; - } - - if (rc != null && lc != null){ - int prev_e = Report.Errors; - Expression e = ConstantFold.BinaryFold ( - ec, oper, lc, rc, loc); - if (e != null || Report.Errors != prev_e) - return e; - } - #if GMCS_SOURCE if ((left is NullLiteral || left.Type.IsValueType) && (right is NullLiteral || right.Type.IsValueType) && _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches