diff options
Diffstat (limited to 'linker/Linker.Steps/MarkStep.cs')
-rw-r--r-- | linker/Linker.Steps/MarkStep.cs | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/linker/Linker.Steps/MarkStep.cs b/linker/Linker.Steps/MarkStep.cs index fb06bc70c..a42c5facd 100644 --- a/linker/Linker.Steps/MarkStep.cs +++ b/linker/Linker.Steps/MarkStep.cs @@ -266,7 +266,7 @@ namespace Mono.Linker.Steps { // We don't need to mark overrides until it is possible that the type could be instantiated // Note : The base type is interface check should be removed once we have base type sweeping - if (!isInstantiated && @base.DeclaringType.IsInterface) + if (@base.DeclaringType.IsInterface && !isInstantiated && !IsInterfaceImplementationMarked (method.DeclaringType, @base.DeclaringType)) return; if (!isInstantiated && !@base.IsAbstract) @@ -276,6 +276,11 @@ namespace Mono.Linker.Steps { ProcessVirtualMethod (method); } + bool IsInterfaceImplementationMarked (TypeDefinition type, TypeDefinition interfaceType) + { + return type.HasInterface (@interfaceType, out InterfaceImplementation implementation) && Annotations.IsMarked (implementation); + } + void MarkMarshalSpec (IMarshalInfoProvider spec) { if (!spec.HasMarshalInfo) @@ -2004,6 +2009,8 @@ namespace Mono.Linker.Steps { foreach (Instruction instruction in body.Instructions) MarkInstruction (instruction); + MarkInterfacesNeededByBodyStack (body); + MarkThingsUsedViaReflection (body); PostMarkMethodBody (body); @@ -2011,6 +2018,19 @@ namespace Mono.Linker.Steps { partial void PostMarkMethodBody (MethodBody body); + void MarkInterfacesNeededByBodyStack (MethodBody body) + { + // If a type could be on the stack in the body and an interface it implements could be on the stack on the body + // then we need to mark that interface implementation. When this occurs it is not safe to remove the interface implementation from the type + // even if the type is never instantiated + var implementations = MethodBodyScanner.GetReferencedInterfaces (_context.Annotations, body); + if (implementations == null) + return; + + foreach (var implementation in implementations) + MarkInterfaceImplementation (implementation); + } + protected virtual void MarkThingsUsedViaReflection (MethodBody body) { MarkSomethingUsedViaReflection ("GetConstructor", MarkConstructorsUsedViaReflection, body.Instructions); |