2007-11-12 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Mon, 12 Nov 2007 18:50:16 +0000 (18:50 -0000)
committerMarek Safar <marek.safar@gmail.com>
Mon, 12 Nov 2007 18:50:16 +0000 (18:50 -0000)
  A fix for bug #324996
  * expression.cs (Is): Handle case where D is nullable and T is not
  correctly.

  * generics.cs (Nullable.HasValue): Nullable HasValue expression.

svn path=/trunk/mcs/; revision=89482

mcs/mcs/ChangeLog
mcs/mcs/expression.cs
mcs/mcs/generic-mcs.cs
mcs/mcs/generic.cs

index 03a2976a21b02ec67afd9686ef4c72ad98f60139..2a56422f8e977261460af57b28c4f45f42eaf1c7 100644 (file)
@@ -1,3 +1,11 @@
+2007-11-12  Marek Safar  <marek.safar@gmail.com>
+
+       A fix for bug #324996
+       * expression.cs (Is): Handle case where D is nullable and T is not
+       correctly.
+       
+       * generics.cs (Nullable.HasValue): Nullable HasValue expression.
+       
 2007-11-12  Marek Safar  <marek.safar@gmail.com>
 
        * generic.cs, literal.cs, ecore.cs, class.cs, delegate.cs, const.cs,
index 5cb07a207de3a70d4a91f1f655aec140f36ea07e..60c032d8a578ae1a0ad77973b4d48d25df82492c 100644 (file)
@@ -1150,6 +1150,7 @@ namespace Mono.CSharp {
                                return null;
 
                        Type d = expr.Type;
+                       bool d_is_nullable = false;
 
                        if (expr is Constant) {
                                //
@@ -1160,21 +1161,31 @@ namespace Mono.CSharp {
                                        return CreateConstantResult (false);
                        } else if (TypeManager.IsNullableType (d) && !TypeManager.ContainsGenericParameters (d)) {
                                d = TypeManager.GetTypeArguments (d) [0];
+                               d_is_nullable = true;
                        }
 
                        type = TypeManager.bool_type;
                        eclass = ExprClass.Value;
                        Type t = probe_type_expr.Type;
-
-                       if (TypeManager.IsNullableType (t) && !TypeManager.ContainsGenericParameters (t))
+                       bool t_is_nullable = false;
+                       if (TypeManager.IsNullableType (t) && !TypeManager.ContainsGenericParameters (t)) {
                                t = TypeManager.GetTypeArguments (t) [0];
+                               t_is_nullable = true;
+                       }
 
                        if (t.IsValueType) {
-                               //
-                               // The result is true if D and T are the same value types
-                               //
-                               if (d == t)
+                               if (d == t) {
+                                       //
+                                       // D and T are the same value types but D can be null
+                                       //
+                                       if (d_is_nullable && !t_is_nullable)
+                                               return Nullable.HasValue.Create (expr, ec);
+                                       
+                                       //
+                                       // The result is true if D and T are the same value types
+                                       //
                                        return CreateConstantResult (true);
+                               }
 
                                if (TypeManager.IsGenericParameter (d))
                                        return ResolveGenericParameter (t, d);
index afaf301b294b2696bf0321164bec1a70d6e0ba76..69d9617410fcb1ca06a411ef198aeda244df73b6 100644 (file)
@@ -350,4 +350,15 @@ namespace Mono.CSharp
                        throw new NotImplementedException ();           
                }
        }
+       
+       public class Nullable
+       {
+               public class HasValue
+               {
+                       public static Expression Create (Expression expr, EmitContext ec)
+                       {
+                               throw new NotImplementedException ();
+                       }
+               }
+       }
 }
index 3d095da6780aa12da9634752fef14cc885d0a3f8..9eae0fa4338edb2a191b3f00d1ae18c8b7cba128 100644 (file)
@@ -3192,6 +3192,37 @@ namespace Mono.CSharp {
                                Constructor = type.GetConstructor (new Type[] { UnderlyingType });
                        }
                }
+               
+               public class HasValue : Expression
+               {
+                       Expression expr;
+                       NullableInfo info;
+
+                       private HasValue (Expression expr)
+                       {
+                               this.expr = expr;
+                       }
+                       
+                       public static Expression Create (Expression expr, EmitContext ec)
+                       {
+                               return new HasValue (expr).Resolve (ec);
+                       }
+
+                       public override void Emit (EmitContext ec)
+                       {
+                               ((IMemoryLocation) expr).AddressOf (ec, AddressOp.LoadStore);
+                               ec.ig.EmitCall (OpCodes.Call, info.HasValue, null);
+                       }
+
+                       public override Expression DoResolve (EmitContext ec)
+                       {
+                               this.info = new NullableInfo (expr.Type);
+
+                               type = TypeManager.bool_type;
+                               eclass = expr.eclass;
+                               return this;
+                       }
+               }               
 
                public class Unwrap : Expression, IMemoryLocation, IAssignMethod
                {