diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2011-06-02 23:21:07 +0400 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2011-06-10 05:44:16 +0400 |
commit | cd376b7a96347a9d94764fb3ac6e6aacf84d7917 (patch) | |
tree | b839a30dd3684fc2fcc397d0fa0aa39fbf1a97c6 /mcs/class/corlib/System/Delegate.cs | |
parent | 3f3825bf8bc062caba1eb7e87a67aefc1d3d15e3 (diff) |
Fixes Delegate.CreateDelegate with valuetype argument on the 'this' position.
* Delegate.cs (CreateDelegate): Allow binding del(vt&) to an instance
method of vt.
* DelegateTest.cs: Add regression tests.
Fixes #695978
Diffstat (limited to 'mcs/class/corlib/System/Delegate.cs')
-rw-r--r-- | mcs/class/corlib/System/Delegate.cs | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/mcs/class/corlib/System/Delegate.cs b/mcs/class/corlib/System/Delegate.cs index d36aa03100b..5bf2e52cd78 100644 --- a/mcs/class/corlib/System/Delegate.cs +++ b/mcs/class/corlib/System/Delegate.cs @@ -136,6 +136,16 @@ namespace System return match; } + private static bool arg_type_match_this (Type delArgType, Type argType, bool boxedThis) { + bool match; + if (argType.IsValueType) + match = delArgType.IsByRef && delArgType.GetElementType () == argType || + (boxedThis && delArgType == argType); + else + match = delArgType == argType || argType.IsAssignableFrom (delArgType); + + return match; + } private static bool return_type_match (Type delReturnType, Type returnType) { bool returnMatch = returnType == delReturnType; @@ -216,7 +226,7 @@ namespace System bool argsMatch; if (target != null) { if (!method.IsStatic) { - argsMatch = arg_type_match (target.GetType (), method.DeclaringType); + argsMatch = arg_type_match_this (target.GetType (), method.DeclaringType, true); for (int i = 0; i < args.Length; i++) argsMatch &= arg_type_match (delargs [i].ParameterType, args [i].ParameterType); } else { @@ -228,7 +238,7 @@ namespace System if (!method.IsStatic) { if (args.Length + 1 == delargs.Length) { // The first argument should match this - argsMatch = arg_type_match (delargs [0].ParameterType, method.DeclaringType); + argsMatch = arg_type_match_this (delargs [0].ParameterType, method.DeclaringType, false); for (int i = 0; i < args.Length; i++) argsMatch &= arg_type_match (delargs [i + 1].ParameterType, args [i].ParameterType); } else { @@ -240,7 +250,7 @@ namespace System } else { if (delargs.Length + 1 == args.Length) { // closed over a null reference - argsMatch = !args [0].ParameterType.IsValueType && allowClosed; + argsMatch = !(args [0].ParameterType.IsValueType || args [0].ParameterType.IsByRef) && allowClosed; for (int i = 0; i < delargs.Length; i++) argsMatch &= arg_type_match (delargs [i].ParameterType, args [i + 1].ParameterType); } else { |