Skip to content

Commit

Permalink
Fix that method resolution would consider all function-pointers to be…
Browse files Browse the repository at this point in the history
… the same (#885)
  • Loading branch information
nulldatamap authored Nov 28, 2022
1 parent cc48622 commit 4ad9c0f
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 2 deletions.
29 changes: 29 additions & 0 deletions Mono.Cecil/MetadataResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,35 @@ static bool AreSame (TypeSpecification a, TypeSpecification b)
if (a.IsArray)
return AreSame ((ArrayType) a, (ArrayType) b);

if (a.IsFunctionPointer)
return AreSame ((FunctionPointerType) a, (FunctionPointerType) b);

return true;
}

static bool AreSame (FunctionPointerType a, FunctionPointerType b)
{
if (a.HasThis != b.HasThis)
return false;

if (a.CallingConvention != b.CallingConvention)
return false;

if (!AreSame (a.ReturnType, b.ReturnType))
return false;

if (a.ContainsGenericParameter != b.ContainsGenericParameter)
return false;

if (a.HasParameters != b.HasParameters)
return false;

if (!a.HasParameters)
return true;

if (!AreSame (a.Parameters, b.Parameters))
return false;

return true;
}

Expand Down
47 changes: 46 additions & 1 deletion Test/Mono.Cecil.Tests/MethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using Mono.Cecil;
using Mono.Cecil.Metadata;

using Mono.Collections.Generic;
using NUnit.Framework;

namespace Mono.Cecil.Tests {
Expand Down Expand Up @@ -236,5 +236,50 @@ public void InstanceAndStaticMethodComparison ()
Assert.AreNotEqual(instance_method, static_method_reference.Resolve ());
});
}

[Test]
public void FunctionPointerArgumentOverload ()
{
TestIL ("others.il", module => {
var others = module.GetType ("Others");
var overloaded_methods = others.Methods.Where (m => m.Name == "OverloadedWithFpArg").ToArray ();
// Manually create the function-pointer type so `AreSame` won't exit early due to reference equality
var overloaded_method_int_reference = new MethodReference ("OverloadedWithFpArg", module.TypeSystem.Void, others)
{
HasThis = false,
Parameters = { new ParameterDefinition ("X", ParameterAttributes.None, new FunctionPointerType () {
HasThis = false,
ReturnType = module.TypeSystem.Int32,
Parameters = { new ParameterDefinition (module.TypeSystem.Int32) }
}) }
};

var overloaded_method_long_reference = new MethodReference ("OverloadedWithFpArg", module.TypeSystem.Void, others)
{
HasThis = false,
Parameters = { new ParameterDefinition ("X", ParameterAttributes.None, new FunctionPointerType () {
HasThis = false,
ReturnType = module.TypeSystem.Int32,
Parameters = { new ParameterDefinition (module.TypeSystem.Int64) }
}) }
};

var overloaded_method_cdecl_reference = new MethodReference ("OverloadedWithFpArg", module.TypeSystem.Void, others)
{
HasThis = false,
Parameters = { new ParameterDefinition ("X", ParameterAttributes.None, new FunctionPointerType () {
CallingConvention = MethodCallingConvention.C,
HasThis = false,
ReturnType = module.TypeSystem.Int32,
Parameters = { new ParameterDefinition (module.TypeSystem.Int32) }
}) }
};


Assert.AreEqual (overloaded_methods[0], overloaded_method_int_reference.Resolve ());
Assert.AreEqual (overloaded_methods[1], overloaded_method_long_reference.Resolve ());
Assert.AreEqual (overloaded_methods[2], overloaded_method_cdecl_reference.Resolve ());
});
}
}
}
17 changes: 16 additions & 1 deletion Test/Resources/il/others.il
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,22 @@
.other instance void Others::dang_Handler (class [mscorlib]System.EventHandler)
.other instance void Others::fang_Handler (class [mscorlib]System.EventHandler)
}


.method public static void OverloadedWithFpArg(method int32 *(int32) X) cil managed
{
ret
}

.method public static void OverloadedWithFpArg(method int32 *(int64) X) cil managed
{
ret
}

.method public static void OverloadedWithFpArg(method unmanaged cdecl int32 *(int32) X) cil managed
{
ret
}

.method public instance void SameMethodNameInstanceStatic() cil managed
{
ret
Expand Down

0 comments on commit 4ad9c0f

Please sign in to comment.