Author: raja
Date: 2006-05-25 07:16:31 -0400 (Thu, 25 May 2006)
New Revision: 61104
Modified:
trunk/mcs/gmcs/ChangeLog
trunk/mcs/gmcs/expression.cs
trunk/mcs/gmcs/generic.cs
trunk/mcs/tests/ChangeLog
trunk/mcs/tests/gtest-211.cs
Log:
In gmcs:
Fix #78324
* expression.cs (Binary.DoResolve): Use Nullable.LiftedBinaryOperator
also when one of the operands is a null literal.
* generic.cs (Nullable.LiftedBinaryOperator.EmitEquality): Rewrite
to improve clarity, and generate slightly better code.
In tests:
* gtest-211.cs: Add a couple more tests for better coverage.
Modified: trunk/mcs/gmcs/ChangeLog
===================================================================
--- trunk/mcs/gmcs/ChangeLog 2006-05-25 11:07:39 UTC (rev 61103)
+++ trunk/mcs/gmcs/ChangeLog 2006-05-25 11:16:31 UTC (rev 61104)
@@ -1,3 +1,11 @@
+2006-05-25 Raja R Harinath <[EMAIL PROTECTED]>
+
+ Fix #78324
+ * expression.cs (Binary.DoResolve): Use Nullable.LiftedBinaryOperator
+ also when one of the operands is a null literal.
+ * generic.cs (Nullable.LiftedBinaryOperator.EmitEquality): Rewrite
+ to improve clarity, and generate slightly better code.
+
2006-05-24 Raja R Harinath <[EMAIL PROTECTED]>
* flowanalysis.cs (FlowBranchingToplevel.AddReturnOrigin): Move
Modified: trunk/mcs/gmcs/expression.cs
===================================================================
--- trunk/mcs/gmcs/expression.cs 2006-05-25 11:07:39 UTC (rev 61103)
+++ trunk/mcs/gmcs/expression.cs 2006-05-25 11:16:31 UTC (rev 61104)
@@ -2464,7 +2464,9 @@
}
Type ltype = left.Type, rtype = right.Type;
- if (ltype.IsValueType && rtype.IsValueType &&
+ if ((left is NullLiteral || ltype.IsValueType) &&
+ (right is NullLiteral || rtype.IsValueType) &&
+ !(left is NullLiteral && right is NullLiteral) &&
(TypeManager.IsNullableType (ltype) ||
TypeManager.IsNullableType (rtype)))
return new Nullable.LiftedBinaryOperator (oper,
left, right, loc).Resolve (ec);
Modified: trunk/mcs/gmcs/generic.cs
===================================================================
--- trunk/mcs/gmcs/generic.cs 2006-05-25 11:07:39 UTC (rev 61103)
+++ trunk/mcs/gmcs/generic.cs 2006-05-25 11:16:31 UTC (rev 61104)
@@ -3150,96 +3150,72 @@
{
ILGenerator ig = ec.ig;
- Label left_not_null_label = ig.DefineLabel ();
- Label false_label = ig.DefineLabel ();
- Label true_label = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ // Given 'X? x;' for any value type X: 'x !=
null' is the same as 'x.HasValue'
+ if (left is NullLiteral) {
+ if (right_unwrap == null)
+ throw new
InternalErrorException ();
+ right_unwrap.EmitCheck (ec);
+ if (Oper == Binary.Operator.Equality) {
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Ceq);
+ }
+ return;
+ }
- bool false_label_used = false;
- bool true_label_used = false;
-
- if (left_unwrap != null) {
+ if (right is NullLiteral) {
+ if (left_unwrap == null)
+ throw new
InternalErrorException ();
left_unwrap.EmitCheck (ec);
- if (right is NullLiteral) {
- if (Oper ==
Binary.Operator.Equality) {
- true_label_used = true;
- ig.Emit
(OpCodes.Brfalse, true_label);
- } else {
- false_label_used = true;
- ig.Emit
(OpCodes.Brfalse, false_label);
- }
- } else if (right_unwrap != null) {
- ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Brtrue,
left_not_null_label);
- right_unwrap.EmitCheck (ec);
+ if (Oper == Binary.Operator.Equality) {
+ ig.Emit (OpCodes.Ldc_I4_0);
ig.Emit (OpCodes.Ceq);
- if (Oper ==
Binary.Operator.Inequality) {
- ig.Emit
(OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ceq);
- }
- ig.Emit (OpCodes.Br, end_label);
-
- ig.MarkLabel
(left_not_null_label);
- ig.Emit (OpCodes.Pop);
- } else {
- if (Oper ==
Binary.Operator.Equality) {
- false_label_used = true;
- ig.Emit
(OpCodes.Brfalse, false_label);
- } else {
- true_label_used = true;
- ig.Emit
(OpCodes.Brfalse, true_label);
- }
}
+ return;
}
- if (right_unwrap != null) {
+ Label both_have_value_label = ig.DefineLabel ();
+ Label end_label = ig.DefineLabel ();
+
+ if (left_unwrap != null && right_unwrap !=
null) {
+ Label dissimilar_label = ig.DefineLabel
();
+
+ left_unwrap.EmitCheck (ec);
+ ig.Emit (OpCodes.Dup);
right_unwrap.EmitCheck (ec);
- if (left is NullLiteral) {
- if (Oper ==
Binary.Operator.Equality) {
- true_label_used = true;
- ig.Emit
(OpCodes.Brfalse, true_label);
- } else {
- false_label_used = true;
- ig.Emit
(OpCodes.Brfalse, false_label);
- }
- } else {
- if (Oper ==
Binary.Operator.Equality) {
- false_label_used = true;
- ig.Emit
(OpCodes.Brfalse, false_label);
- } else {
- true_label_used = true;
- ig.Emit
(OpCodes.Brfalse, true_label);
- }
- }
- }
+ ig.Emit (OpCodes.Ceq);
+ ig.Emit (OpCodes.Brfalse,
dissimilar_label);
- bool left_is_null = left is NullLiteral;
- bool right_is_null = right is NullLiteral;
- if (left_is_null || right_is_null) {
- if (((Oper == Binary.Operator.Equality)
&& (left_is_null == right_is_null)) ||
- ((Oper ==
Binary.Operator.Inequality) && (left_is_null != right_is_null))) {
- true_label_used = true;
- ig.Emit (OpCodes.Br,
true_label);
- } else {
- false_label_used = true;
- ig.Emit (OpCodes.Br,
false_label);
- }
- } else {
- underlying.Emit (ec);
+ ig.Emit (OpCodes.Brtrue,
both_have_value_label);
+
+ // both are null
+ if (Oper == Binary.Operator.Equality)
+ ig.Emit (OpCodes.Ldc_I4_1);
+ else
+ ig.Emit (OpCodes.Ldc_I4_0);
ig.Emit (OpCodes.Br, end_label);
- }
- ig.MarkLabel (false_label);
- if (false_label_used) {
- ig.Emit (OpCodes.Ldc_I4_0);
- if (true_label_used)
- ig.Emit (OpCodes.Br, end_label);
+ ig.MarkLabel (dissimilar_label);
+ ig.Emit (OpCodes.Pop);
+ } else if (left_unwrap != null) {
+ left_unwrap.EmitCheck (ec);
+ ig.Emit (OpCodes.Brtrue,
both_have_value_label);
+ } else if (right_unwrap != null) {
+ right_unwrap.EmitCheck (ec);
+ ig.Emit (OpCodes.Brtrue,
both_have_value_label);
+ } else {
+ throw new InternalErrorException
("shouldn't get here");
}
- ig.MarkLabel (true_label);
- if (true_label_used)
+ // one is null while the other isn't
+ if (Oper == Binary.Operator.Equality)
+ ig.Emit (OpCodes.Ldc_I4_0);
+ else
ig.Emit (OpCodes.Ldc_I4_1);
+ ig.Emit (OpCodes.Br, end_label);
+ ig.MarkLabel (both_have_value_label);
+ underlying.Emit (ec);
+
ig.MarkLabel (end_label);
}
Modified: trunk/mcs/tests/ChangeLog
===================================================================
--- trunk/mcs/tests/ChangeLog 2006-05-25 11:07:39 UTC (rev 61103)
+++ trunk/mcs/tests/ChangeLog 2006-05-25 11:16:31 UTC (rev 61104)
@@ -1,3 +1,7 @@
+2006-05-25 Raja R Harinath <[EMAIL PROTECTED]>
+
+ * gtest-211.cs: Add a couple more tests for better coverage.
+
2006-05-23 Raja R Harinath <[EMAIL PROTECTED]>
* test-519.cs: New test for compiler crash.
Modified: trunk/mcs/tests/gtest-211.cs
===================================================================
--- trunk/mcs/tests/gtest-211.cs 2006-05-25 11:07:39 UTC (rev 61103)
+++ trunk/mcs/tests/gtest-211.cs 2006-05-25 11:16:31 UTC (rev 61104)
@@ -6,17 +6,24 @@
}
public static void Main()
{
+ int? w = null;
int? x = null;
int? y = 0;
+ int? z = 1;
+
f (false, x == 0);
f (true, x != 0);
f (false, x == y);
f (true, x != y);
+ f (true, x == w);
+ f (false, x != w);
f (true, x == null);
f (false, x != null);
f (true, 0 == y);
f (false, 0 != y);
+ f (false, z == y);
+ f (true, z != y);
f (false, null == y);
f (true, null != y);
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches