Pass checked context to compound member access setters
authorMarek Safar <marek.safar@gmail.com>
Wed, 3 Nov 2010 09:38:40 +0000 (09:38 +0000)
committerMarek Safar <marek.safar@gmail.com>
Wed, 3 Nov 2010 10:34:06 +0000 (10:34 +0000)
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpSetIndexBinder.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpSetMemberBinder.cs
mcs/mcs/assign.cs
mcs/tests/dtest-033.cs
mcs/tests/ver-il-dmcs.xml

index 2c72f1fa0b508e6d595e26ac28c3c68ce650a31c..ad2f51a1dbf85f2c62ffa6d9149fbf00a133694d 100644 (file)
@@ -72,6 +72,9 @@ namespace Microsoft.CSharp.RuntimeBinder
                        }
                        expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
 
+                       if ((flags & CSharpBinderFlags.CheckedContext) != 0)
+                               expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
+
                        var binder = new CSharpBinder (this, expr, errorSuggestion);
                        binder.AddRestrictions (target);
                        binder.AddRestrictions (value);
index 52fb4dd0adafa7ba4065691e821463924008ea19..aaf2b251c52a9cfe2a9c469c5f16a7dcc45dca5a 100644 (file)
@@ -69,6 +69,9 @@ namespace Microsoft.CSharp.RuntimeBinder
 
                        expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
 
+                       if ((flags & CSharpBinderFlags.CheckedContext) != 0)
+                               expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
+
                        var binder = new CSharpBinder (this, expr, errorSuggestion);
                        binder.AddRestrictions (target);
                        binder.AddRestrictions (value);
index 302b60e2e164f1c40f5deabd4071ff8e580ff1a6..0f8c64ec508c660ad6996d9da86a124e5e0ad95a 100644 (file)
@@ -450,11 +450,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;
                }
        }
 
@@ -668,8 +665,18 @@ 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) {
@@ -688,7 +695,7 @@ namespace Mono.CSharp {
                                                        (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;
index 4b5ed6a7b5fa5b84c7736c045ffa21099cba5009..f64fdc0b53c2afa1e247eaee8f0739dd7615ab60 100644 (file)
@@ -11,6 +11,11 @@ public class Test
                get { return 2; }
                set { }
        }
+       
+       byte Byte = 200;
+       static dynamic V;
+       dynamic DynamicByte;
+       byte[] ByteArray = { 1, 100 };
 
        public static int Main ()
        {
@@ -39,13 +44,51 @@ public class Test
                try {
                        checked {
                                b += d;
-                               return 1;
+                               return 3;
                        }
                } catch (OverflowException) {
                }
-               
+                       
                b += d;
+               
+               try {
+                       checked {
+                               a.Byte += 100;
+                               return 4;
+                       }
+               } catch (OverflowException) {
+               }
+               
+               a.Byte += 100;
+               
+               checked {
+                       d = byte.MaxValue;
+                       d += 100;
+               }
+
+               checked {
+                       V = byte.MaxValue;
+                       V -= 300;
+               }
+
+               var t = new Test ();
+               t.DynamicByte = byte.MaxValue;
+               d = t;
+               checked {
+                       d.DynamicByte -= 500;
+               }
+               
+               if (t.DynamicByte != -245)
+                       return 5;
+
+               try {
+                       checked {
+                               d.ByteArray[1] += 200;
+                               return 6;
+                       }                       
+               } catch (OverflowException) {
+               }
 
                return 0;
        }
-}
\ No newline at end of file
+}
index 1bb8348a6113421a0189f9ff6b2ae9b784717d7c..722236341ef1ad9f07fd3a4b26da1f99173d83d6 100644 (file)
         <size>1</size>
       </method>
       <method name="Int32 Main()">
-        <size>1420</size>
+        <size>3585</size>
       </method>
       <method name="Void .ctor()">
-        <size>7</size>
+        <size>39</size>
       </method>
     </type>
   </test>