[mcs] lifted binary operator for decimal arguments need to call user operator for...
authorMarek Safar <marek.safar@gmail.com>
Wed, 15 Feb 2017 16:17:44 +0000 (17:17 +0100)
committerMarek Safar <marek.safar@gmail.com>
Wed, 15 Feb 2017 16:20:29 +0000 (17:20 +0100)
mcs/mcs/expression.cs
mcs/mcs/nullable.cs
mcs/tests/gtest-644.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index 1a421ea68a21f1534c89283addb443c5d7744e23..c7747f014fdee5da31e0b772c45dbdaa148c769c 100644 (file)
@@ -3448,7 +3448,7 @@ namespace Mono.CSharp
                        }
                }
 
-               static CSharp.Operator.OpType ConvertBinaryToUserOperator (Operator op)
+               public static CSharp.Operator.OpType ConvertBinaryToUserOperator (Operator op)
                {
                        switch (op) {
                        case Operator.Addition:
index 93314df322ad9c202cbc1667077a1f050738f27e..754c888e8b1158711b9f4200666e7a22e6ff273f 100644 (file)
@@ -695,6 +695,20 @@ namespace Mono.CSharp.Nullable
                                        Right = Unwrap.CreateUnwrapped (Right);
                                        UnwrapRight = Right as Unwrap;
                                }
+
+                               if (Left.Type.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
+                                       var decimal_operators = MemberCache.GetUserOperator (Left.Type, Binary.ConvertBinaryToUserOperator (Binary.Oper), false);
+
+                                       Arguments args = new Arguments (2);
+                                       args.Add (new Argument (Left));
+                                       args.Add (new Argument (Right));
+
+                                       const OverloadResolver.Restrictions restr = OverloadResolver.Restrictions.ProbingOnly |
+                                               OverloadResolver.Restrictions.NoBaseMembers | OverloadResolver.Restrictions.BaseMembersIncluded;
+
+                                       var res = new OverloadResolver (decimal_operators, restr, loc);
+                                       UserOperator = res.ResolveOperator (rc, ref args);
+                               }
                        }
 
                        type = Binary.Type;
diff --git a/mcs/tests/gtest-644.cs b/mcs/tests/gtest-644.cs
new file mode 100644 (file)
index 0000000..609f879
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+
+public struct MoneyValue
+{
+       private readonly decimal _amount;
+
+       public MoneyValue (decimal amount)
+       {
+               _amount = amount;
+       }
+
+       public static implicit operator decimal (MoneyValue moneyValue)
+       {
+               return moneyValue._amount;
+       }
+}
+
+public class Program
+{
+       static void Main ()
+       {
+               var nullMoneyValue = (MoneyValue?) null;
+               var moneyValue = new MoneyValue (123);
+
+               var crashApplication = nullMoneyValue < moneyValue; 
+
+               Console.WriteLine("All OK");
+       }
+}
index 52f368f4d79c5b43b9de3fe3066705459491b6c3..058f365c1bda16a7d491ddfe2fc87b16ab2477bf 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-644.cs">
+    <type name="MoneyValue">
+      <method name="System.Decimal op_Implicit(MoneyValue)" attrs="2198">
+        <size>16</size>
+      </method>
+      <method name="Void .ctor(Decimal)" attrs="6278">
+        <size>9</size>
+      </method>
+    </type>
+    <type name="Program">
+      <method name="Void Main()" attrs="145">
+        <size>75</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anontype-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="150">