+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,
return null;
Type d = expr.Type;
+ bool d_is_nullable = false;
if (expr is Constant) {
//
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);
throw new NotImplementedException ();
}
}
+
+ public class Nullable
+ {
+ public class HasValue
+ {
+ public static Expression Create (Expression expr, EmitContext ec)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+ }
}
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
{