Fix effective base class for value types
[mono.git] / mcs / mcs / assign.cs
index 9967e31ea58a506b472b6088ec59fe2792b5d721..5ea834792cf3dc7cd3e2ede2b8847b247689831b 100644 (file)
 // Copyright 2004-2008 Novell, Inc
 //
 using System;
-using System.Reflection;
+
+#if STATIC
+using IKVM.Reflection.Emit;
+#else
 using System.Reflection.Emit;
+#endif
 
 namespace Mono.CSharp {
 
@@ -361,13 +365,19 @@ namespace Mono.CSharp {
                        if (target_object.NodeType == System.Linq.Expressions.ExpressionType.Block)
                                return target_object;
 
-                       var source_object = System.Linq.Expressions.Expression.Convert (source.MakeExpression (ctx), target_object.Type);
+                       System.Linq.Expressions.UnaryExpression source_object;
+                       if (ctx.HasSet (BuilderContext.Options.CheckedScope)) {
+                               source_object = System.Linq.Expressions.Expression.ConvertChecked (source.MakeExpression (ctx), target_object.Type);
+                       } else {
+                               source_object = System.Linq.Expressions.Expression.Convert (source.MakeExpression (ctx), target_object.Type);
+                       }
+
                        return System.Linq.Expressions.Expression.Assign (target_object, source_object);
                }
 #endif
                protected virtual Expression ResolveConversions (ResolveContext ec)
                {
-                       source = Convert.ImplicitConversionRequired (ec, source, target.Type, loc);
+                       source = Convert.ImplicitConversionRequired (ec, source, target.Type, source.Location);
                        if (source == null)
                                return null;
 
@@ -444,11 +454,8 @@ namespace Mono.CSharp {
 
                protected override Expression ResolveConversions (ResolveContext ec)
                {
-                       source = Convert.ExplicitConversion (ec, source, target.Type, loc);
-                       if (source != null)
-                               return this;
-
-                       return base.ResolveConversions (ec);
+                       source = EmptyCast.Create (source, target.Type);
+                       return this;
                }
        }
 
@@ -506,7 +513,7 @@ namespace Mono.CSharp {
                {
                        this.mc = mc;
                        if (!spec.IsStatic)
-                               ((FieldExpr)target).InstanceExpression = CompilerGeneratedThis.Instance;
+                               ((FieldExpr)target).InstanceExpression = new CompilerGeneratedThis (mc.CurrentType, expression.Location);
                }
 
                protected override Expression DoResolve (ResolveContext ec)
@@ -662,12 +669,22 @@ namespace Mono.CSharp {
                                Arguments args = new Arguments (targs.Count + 1);
                                args.AddRange (targs);
                                args.Add (new Argument (source));
+
+                               var binder_flags = CSharpBinderFlags.ValueFromCompoundAssignment;
+
+                               //
+                               // Compound assignment does target conversion using additional method
+                               // call, set checked context as the binary operation can overflow
+                               //
+                               if (ec.HasSet (ResolveContext.Options.CheckedScope))
+                                       binder_flags |= CSharpBinderFlags.CheckedContext;
+
                                if (target is DynamicMemberBinder) {
-                                       source = new DynamicMemberBinder (ma.Name, CSharpBinderFlags.ValueFromCompoundAssignment, args, loc).Resolve (ec);
+                                       source = new DynamicMemberBinder (ma.Name, binder_flags, args, loc).Resolve (ec);
 
                                        // Handles possible event addition/subtraction
                                        if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction) {
-                                               args = new Arguments (2);
+                                               args = new Arguments (targs.Count + 1);
                                                args.AddRange (targs);
                                                args.Add (new Argument (right));
                                                string method_prefix = op == Binary.Operator.Addition ?
@@ -676,13 +693,13 @@ namespace Mono.CSharp {
                                                var invoke = DynamicInvocation.CreateSpecialNameInvoke (
                                                        new MemberAccess (right, method_prefix + ma.Name, loc), args, loc).Resolve (ec);
 
-                                               args = new Arguments (1);
+                                               args = new Arguments (targs.Count);
                                                args.AddRange (targs);
                                                source = new DynamicEventCompoundAssign (ma.Name, args,
                                                        (ExpressionStatement) source, (ExpressionStatement) invoke, loc).Resolve (ec);
                                        }
                                } else {
-                                       source = new DynamicIndexBinder (CSharpBinderFlags.ValueFromCompoundAssignment, args, loc).Resolve (ec);
+                                       source = new DynamicIndexBinder (binder_flags, args, loc).Resolve (ec);
                                }
 
                                return source;
@@ -732,7 +749,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (source.Type == InternalType.Dynamic) {
+                       if (source.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
                                Arguments arg = new Arguments (1);
                                arg.Add (new Argument (source));
                                return new SimpleAssign (target, new DynamicConversion (target_type, CSharpBinderFlags.ConvertExplicit, arg, loc), loc).Resolve (ec);