Don't crash when nullable user conversion requires lifted constant argument
authorMarek Safar <marek.safar@gmail.com>
Thu, 26 Jul 2012 14:10:09 +0000 (15:10 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 26 Jul 2012 16:27:11 +0000 (17:27 +0100)
mcs/mcs/convert.cs
mcs/mcs/expression.cs
mcs/tests/gtest-570.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index 3020c8814c54ce37961edf1950b9e89c7db791e4..f0e743adc5040499fe91e8e87aaf5b496618f352 100644 (file)
@@ -1090,12 +1090,13 @@ namespace Mono.CSharp {
                        Expression source_type_expr;
 
                        if (source_type.IsNullableType) {
-                               // No implicit conversion S? -> T for non-reference types
-                               if (implicitOnly && !TypeSpec.IsReferenceType (target_type) && !target_type.IsNullableType)
-                                       return null;
-
-                               source_type_expr = Nullable.Unwrap.Create (source);
-                               source_type = source_type_expr.Type;
+                               // No unwrapping conversion S? -> T for non-reference types
+                               if (implicitOnly && !TypeSpec.IsReferenceType (target_type) && !target_type.IsNullableType) {
+                                       source_type_expr = source;
+                               } else {
+                                       source_type_expr = Nullable.Unwrap.Create (source);
+                                       source_type = source_type_expr.Type;
+                               }
                        } else {
                                source_type_expr = source;
                        }
@@ -1196,7 +1197,11 @@ namespace Mono.CSharp {
                                var c = source as Constant;
                                if (c != null) {
                                        source = c.TryReduce (ec, s_x);
-                               } else {
+                                       if (source == null)
+                                               c = null;
+                               }
+
+                               if (c == null) {
                                        source = implicitOnly ?
                                                ImplicitConversionStandard (ec, source_type_expr, s_x, loc) :
                                                ExplicitConversionStandard (ec, source_type_expr, s_x, loc);
index c0800aa439564d40f8d7854f658044a53e08db9a..0f4c0ddd3c41cae0f1ac61e6d20b771f257131a6 100644 (file)
@@ -9300,6 +9300,9 @@ namespace Mono.CSharp
                
                public UserCast (MethodSpec method, Expression source, Location l)
                {
+                       if (source == null)
+                               throw new ArgumentNullException ("source");
+
                        this.method = method;
                        this.source = source;
                        type = method.ReturnType;
diff --git a/mcs/tests/gtest-570.cs b/mcs/tests/gtest-570.cs
new file mode 100644 (file)
index 0000000..be9535d
--- /dev/null
@@ -0,0 +1,16 @@
+struct C<T>
+{
+       public static implicit operator C<T> (T value)
+       {
+               return default (C<T>);
+       }
+}
+
+class C
+{
+       public static void Main ()
+       {
+               C<bool?> p = true;
+               C<int?> p2 = (int?)null;
+       }
+}
index 4a410d3055c438e10650791d77be5ccd30f232bc..d914e52d437b8790d8164aee3c425279b64ebdb6 100644 (file)
       </method>\r
     </type>\r
   </test>\r
+  <test name="gtest-570.cs">\r
+    <type name="C">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>29</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="C`1[T]">\r
+      <method name="C`1 op_Implicit(T)" attrs="2198">\r
+        <size>18</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="gtest-anontype-01.cs">\r
     <type name="Test">\r
       <method name="Int32 Main()" attrs="145">\r