Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'linker/Linker.Steps/MarkStep.cs')
-rw-r--r--linker/Linker.Steps/MarkStep.cs22
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);