[mcs] coalescing operator if the lhs of a null is a integer type that is larger than...
authorMarek Safar <marek.safar@gmail.com>
Thu, 14 Aug 2014 09:49:46 +0000 (11:49 +0200)
committerMarek Safar <marek.safar@gmail.com>
Thu, 14 Aug 2014 09:50:54 +0000 (11:50 +0200)
mcs/mcs/nullable.cs
mcs/tests/gtest-621.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index 9ed67e140745206db305c5d495a22852c5bde0de..4cf665625cecdf26f4fa4e7cd8a49af52a3fc471 100644 (file)
@@ -1135,24 +1135,35 @@ namespace Mono.CSharp.Nullable
                                if (right.IsNull)
                                        return ReducedExpression.Create (left, this);
 
-                               if (Convert.ImplicitConversionExists (ec, right, unwrap.Type)) {
-                                       left = unwrap;
-                                       ltype = left.Type;
+                               Expression conv;
+                               if (right.Type.IsNullableType) {
+                                       conv = right.Type == ltype ? right : Convert.ImplicitNulableConversion (ec, right, ltype);
+                                       if (conv != null) {
+                                               right = conv;
+                                               type = ltype;
+                                               return this;
+                                       }
+                               } else {
+                                       conv = Convert.ImplicitConversion (ec, right, unwrap.Type, loc);
+                                       if (conv != null) {
+                                               left = unwrap;
+                                               ltype = left.Type;
 
-                                       //
-                                       // If right is a dynamic expression, the result type is dynamic
-                                       //
-                                       if (right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
-                                               type = right.Type;
+                                               //
+                                               // If right is a dynamic expression, the result type is dynamic
+                                               //
+                                               if (right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
+                                                       type = right.Type;
 
-                                               // Need to box underlying value type
-                                               left = Convert.ImplicitBoxingConversion (left, ltype, type);
+                                                       // Need to box underlying value type
+                                                       left = Convert.ImplicitBoxingConversion (left, ltype, type);
+                                                       return this;
+                                               }
+
+                                               right = conv;
+                                               type = ltype;
                                                return this;
                                        }
-
-                                       right = Convert.ImplicitConversion (ec, right, ltype, loc);
-                                       type = ltype;
-                                       return this;
                                }
                        } else if (TypeSpec.IsReferenceType (ltype)) {
                                if (Convert.ImplicitConversionExists (ec, right, ltype)) {
diff --git a/mcs/tests/gtest-621.cs b/mcs/tests/gtest-621.cs
new file mode 100644 (file)
index 0000000..cfff301
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+
+class X
+{
+       static int Main ()
+       {
+               int? intArg = 1;
+               long? longArg = 2;
+
+               var g = intArg ?? longArg;
+               Console.WriteLine (g);
+               if (g != 1)
+                       return 1;
+
+               intArg = null;
+               g = intArg ?? longArg;
+               Console.WriteLine (g);
+               if (g != 2)
+                       return 2;
+
+               longArg = null;
+               g = intArg ?? longArg;
+               Console.WriteLine (g);
+               if (g != null)
+                       return 3;
+                       
+               return 0;
+       }
+}
\ No newline at end of file
index 37782bb451fc77a032a929f7350469a516df7482..6f62c5477a91bdf6ae85cabbf29ce240dd632598 100644 (file)
       </method>\r
     </type>\r
   </test>\r
+  <test name="gtest-621.cs">\r
+    <type name="X">\r
+      <method name="Int32 Main()" attrs="145">\r
+        <size>267</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="gtest-anontype-01.cs">\r
     <type name="Test">\r
       <method name="Int32 Main()" attrs="150">\r