Make reflection tracking work with unnormalized VirtualMethodUse

This commit is contained in:
Michal Strehovský 2018-01-19 13:31:59 +01:00
Родитель c1319a660c
Коммит 48183632f6
3 изменённых файлов: 26 добавлений и 2 удалений

Просмотреть файл

@ -22,6 +22,8 @@ namespace ILCompiler.DependencyAnalysis
public ReflectableMethodNode(MethodDesc method) public ReflectableMethodNode(MethodDesc method)
{ {
Debug.Assert(method.IsAbstract || method.IsPInvoke); Debug.Assert(method.IsAbstract || method.IsPInvoke);
Debug.Assert(!method.IsCanonicalMethod(CanonicalFormKind.Any) ||
method.GetCanonMethodTarget(CanonicalFormKind.Specific) == method);
_method = method; _method = method;
} }
@ -45,4 +47,4 @@ namespace ILCompiler.DependencyAnalysis
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null; public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
} }
} }

Просмотреть файл

@ -68,7 +68,9 @@ namespace ILCompiler.DependencyAnalysis
dependencies.Add(new DependencyListEntry(factory.VTable(_decl.OwningType), "VTable of a VirtualMethodUse")); dependencies.Add(new DependencyListEntry(factory.VTable(_decl.OwningType), "VTable of a VirtualMethodUse"));
factory.MetadataManager.GetDependenciesDueToVirtualMethodReflectability(ref dependencies, factory, _decl); // Do not report things like Foo<object, __Canon>.Frob().
if (!_decl.IsCanonicalMethod(CanonicalFormKind.Any) || canonDecl == _decl)
factory.MetadataManager.GetDependenciesDueToVirtualMethodReflectability(ref dependencies, factory, _decl);
return dependencies; return dependencies;
} }

Просмотреть файл

@ -423,6 +423,21 @@ internal class ReflectionTest
} }
} }
class Gen<T> { }
interface IFoo<out T>
{
string Frob();
}
class Foo<T> : IFoo<Gen<T>>
{
public string Frob()
{
return typeof(T).ToString();
}
}
public static void Run() public static void Run()
{ {
Console.WriteLine(nameof(TestInterfaceMethod)); Console.WriteLine(nameof(TestInterfaceMethod));
@ -431,11 +446,16 @@ internal class ReflectionTest
if (string.Empty.Length > 0) if (string.Empty.Length > 0)
{ {
((IFoo)new Foo()).Frob(1); ((IFoo)new Foo()).Frob(1);
((IFoo<object>)new Foo<string>()).Frob();
} }
object result = InvokeTestMethod(typeof(IFoo), "Frob", new Foo(), 42); object result = InvokeTestMethod(typeof(IFoo), "Frob", new Foo(), 42);
if ((string)result != "42") if ((string)result != "42")
throw new Exception(); throw new Exception();
result = InvokeTestMethod(typeof(IFoo<object>), "Frob", new Foo<string>());
if ((string)result != "System.String")
throw new Exception();
} }
} }