From 48183632f69c4ac2a2ea8b741272240d1ba2a3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 19 Jan 2018 13:31:59 +0100 Subject: [PATCH] Make reflection tracking work with unnormalized VirtualMethodUse --- .../ReflectableMethodNode.cs | 4 +++- .../VirtualMethodUseNode.cs | 4 +++- tests/src/Simple/Reflection/Reflection.cs | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectableMethodNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectableMethodNode.cs index 2664308a8..78d27ef41 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectableMethodNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectableMethodNode.cs @@ -22,6 +22,8 @@ namespace ILCompiler.DependencyAnalysis public ReflectableMethodNode(MethodDesc method) { Debug.Assert(method.IsAbstract || method.IsPInvoke); + Debug.Assert(!method.IsCanonicalMethod(CanonicalFormKind.Any) || + method.GetCanonMethodTarget(CanonicalFormKind.Specific) == method); _method = method; } @@ -45,4 +47,4 @@ namespace ILCompiler.DependencyAnalysis public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } -} \ No newline at end of file +} diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VirtualMethodUseNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VirtualMethodUseNode.cs index 7d4f17df7..aec52ca2d 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VirtualMethodUseNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VirtualMethodUseNode.cs @@ -68,7 +68,9 @@ namespace ILCompiler.DependencyAnalysis 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.Frob(). + if (!_decl.IsCanonicalMethod(CanonicalFormKind.Any) || canonDecl == _decl) + factory.MetadataManager.GetDependenciesDueToVirtualMethodReflectability(ref dependencies, factory, _decl); return dependencies; } diff --git a/tests/src/Simple/Reflection/Reflection.cs b/tests/src/Simple/Reflection/Reflection.cs index 4454e9415..322650a2c 100644 --- a/tests/src/Simple/Reflection/Reflection.cs +++ b/tests/src/Simple/Reflection/Reflection.cs @@ -423,6 +423,21 @@ internal class ReflectionTest } } + class Gen { } + + interface IFoo + { + string Frob(); + } + + class Foo : IFoo> + { + public string Frob() + { + return typeof(T).ToString(); + } + } + public static void Run() { Console.WriteLine(nameof(TestInterfaceMethod)); @@ -431,11 +446,16 @@ internal class ReflectionTest if (string.Empty.Length > 0) { ((IFoo)new Foo()).Frob(1); + ((IFoo)new Foo()).Frob(); } object result = InvokeTestMethod(typeof(IFoo), "Frob", new Foo(), 42); if ((string)result != "42") throw new Exception(); + + result = InvokeTestMethod(typeof(IFoo), "Frob", new Foo()); + if ((string)result != "System.String") + throw new Exception(); } }