Reference equality of identical reference types cannot involve implicit conversion...
authorMarek Safar <marek.safar@gmail.com>
Wed, 4 Jan 2012 22:03:53 +0000 (22:03 +0000)
committerMarek Safar <marek.safar@gmail.com>
Thu, 5 Jan 2012 13:20:04 +0000 (13:20 +0000)
mcs/mcs/expression.cs
mcs/tests/test-786.cs
mcs/tests/ver-il-net_4_5.xml

index ab3116fc8bf3ba6d422aafd084251f6d184a0cc7..0350c99ba80ee34e81be8211753e39f3fdfda6db 100644 (file)
@@ -3389,6 +3389,8 @@ namespace Mono.CSharp
                                return this;
                        }
 
+                       bool no_arg_conv = false;
+
                        //
                        // LAMESPEC: method groups can be compared when they convert to other side delegate
                        //
@@ -3410,6 +3412,8 @@ namespace Mono.CSharp
 
                                left = result;
                                l = r;
+                       } else {
+                               no_arg_conv = l == r && !l.IsStruct;
                        }
 
                        //
@@ -3422,11 +3426,12 @@ namespace Mono.CSharp
                        // bool operator != (bool a, bool b)
                        // bool operator == (bool a, bool b)
                        //
-                       // LAMESPEC: Reference equality comparison can apply to value types when
-                       // they implement an implicit conversion to any of types above.
+                       // LAMESPEC: Reference equality comparison can apply to value/reference types when
+                       // they implement an implicit conversion to any of types above. This does
+                       // not apply when both operands are of same reference type
                        //
                        if (r.BuiltinType != BuiltinTypeSpec.Type.Object && l.BuiltinType != BuiltinTypeSpec.Type.Object) {
-                               result = ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryEquality, false, null);
+                               result = ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryEquality, no_arg_conv, null);
                                if (result != null)
                                        return result;
                        }
index 36cc025ecef486864f85ee550395ed7e30f553e8..47dab4de2ed0c10d613559339c139aa05725291f 100644 (file)
@@ -45,6 +45,14 @@ public struct E
        }
 }
 
+public class F
+{
+       public static implicit operator bool (F f)
+       {
+               throw new ApplicationException ();
+       }
+}
+
 class Program
 {      
        public static int Main ()
@@ -76,6 +84,9 @@ class Program
 
                if (new E () != new E ()  || E.Counter != 2)
                        return 31;
+
+               if (new F () == new F ())
+                       return 40;
                
                Console.WriteLine ("ok");
                return 0;
index 96a6bf10648c91ec357d4a0973af6089252a1c5c..b875055816362eb53fab2a9504d7af5de41ce1d7 100644 (file)
     </type>
     <type name="Program">
       <method name="Int32 Main()">
-        <size>372</size>
+        <size>390</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="F">
+      <method name="Boolean op_Implicit(F)">
+        <size>6</size>
       </method>
       <method name="Void .ctor()">
         <size>7</size>