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:
-rw-r--r--src/linker/Linker.Steps/SweepStep.cs8
-rw-r--r--test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceVariants.cs49
2 files changed, 44 insertions, 13 deletions
diff --git a/src/linker/Linker.Steps/SweepStep.cs b/src/linker/Linker.Steps/SweepStep.cs
index 60506e466..8e8b09cd8 100644
--- a/src/linker/Linker.Steps/SweepStep.cs
+++ b/src/linker/Linker.Steps/SweepStep.cs
@@ -472,7 +472,13 @@ namespace Mono.Linker.Steps
void SweepOverrides (MethodDefinition method)
{
for (int i = 0; i < method.Overrides.Count;) {
- if (Context.Resolve (method.Overrides[i]) is MethodDefinition ov && ShouldRemove (ov) && !IgnoreScope (ov.DeclaringType.Scope))
+ // We can't rely on the context resolution cache anymore, since it may remember methods which are already removed
+ // So call the direct Resolve here and avoid the cache.
+ // It can still happen that the Resolve will return a removed method (this happens if the Overrides collection stores actual
+ // MethodDefinition and not MethodReference, in which case the Resolve is just "return this" and doesn't check the existence of the method
+ // in any way). In such case the Declaring type of the method is null. And since it has been removed the override pointing
+ // to it should be removed as well.
+ if (method.Overrides[i].Resolve () is MethodDefinition ov && ShouldRemove (ov) && (ov.DeclaringType == null || !IgnoreScope (ov.DeclaringType.Scope)))
method.Overrides.RemoveAt (i);
else
i++;
diff --git a/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceVariants.cs b/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceVariants.cs
index 9b766b42a..de7f5a537 100644
--- a/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceVariants.cs
+++ b/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceVariants.cs
@@ -20,9 +20,8 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces
t = typeof (UninstantiatedClassWithImplicitlyImplementedInterface);
t = typeof (UninstantiatedPublicClassWithPrivateInterface);
t = typeof (ImplementsUsedStaticInterface.InterfaceMethodUnused);
- t = typeof (ImplementsUnusedStaticInterface.InterfaceMethodUnused);
- ImplementsUnusedStaticInterface.InterfaceMethodUsedThroughImplementation.InternalStaticInterfaceMethodUsedThroughImplementation ();
+ ImplementsUnusedStaticInterface.Test (); ;
GenericMethodThatCallsInternalStaticInterfaceMethod
<ImplementsUsedStaticInterface.InterfaceMethodUsedThroughInterface> ();
// Use all public interfaces - they're marked as public only to denote them as "used"
@@ -66,21 +65,53 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces
}
}
+
[Kept]
internal class ImplementsUnusedStaticInterface
{
[Kept]
- internal class InterfaceMethodUsedThroughImplementation : IStaticInterfaceUnused
+ // The interface methods themselves are not used, but the implementation of these methods is
+ internal interface IStaticInterfaceMethodUnused
+ {
+ static abstract void InterfaceUsedMethodNot ();
+ }
+
+ // The interface methods themselves are not used, but the implementation of these methods is
+ internal interface IStaticInterfaceUnused
+ {
+ static abstract void InterfaceAndMethodNoUsed ();
+ }
+
+ [Kept]
+ internal class InterfaceMethodUsedThroughImplementation : IStaticInterfaceMethodUnused, IStaticInterfaceUnused
{
[Kept]
+ [RemovedOverride (typeof (IStaticInterfaceMethodUnused))]
+ public static void InterfaceUsedMethodNot () { }
+
+ [Kept]
[RemovedOverride (typeof (IStaticInterfaceUnused))]
- public static void InternalStaticInterfaceMethodUsedThroughImplementation () { }
+ public static void InterfaceAndMethodNoUsed () { }
}
[Kept]
- internal class InterfaceMethodUnused : IStaticInterfaceUnused
+ [KeptInterface (typeof (IStaticInterfaceMethodUnused))]
+ internal class InterfaceMethodUnused : IStaticInterfaceMethodUnused, IStaticInterfaceUnused
{
- public static void InternalStaticInterfaceMethodUsedThroughImplementation () { }
+ public static void InterfaceUsedMethodNot () { }
+
+ public static void InterfaceAndMethodNoUsed () { }
+ }
+
+ [Kept]
+ public static void Test ()
+ {
+ InterfaceMethodUsedThroughImplementation.InterfaceUsedMethodNot ();
+ InterfaceMethodUsedThroughImplementation.InterfaceAndMethodNoUsed ();
+
+ Type t;
+ t = typeof (IStaticInterfaceMethodUnused);
+ t = typeof (InterfaceMethodUnused);
}
}
@@ -270,12 +301,6 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces
static abstract void ExplicitImplementationInternalStaticInterfaceMethod ();
}
- // The interface methods themselves are not used, but the implementation of these methods is
- internal interface IStaticInterfaceUnused
- {
- static abstract void InternalStaticInterfaceMethodUsedThroughImplementation ();
- }
-
// The interface methods themselves are used through the interface
[Kept]
internal interface IStaticInterfaceUsed