Skip to content

Commit

Permalink
Check the correct interface list in IsInterfaceImplementationMarkedRe…
Browse files Browse the repository at this point in the history
…cursively (#1429)

`IsInterfaceImplementationMarkedRecursively` was incorrectly rewritten from a global prepass to a local interface walk in #1186.

The new code was looking at the wrong interface list (looking at `IBar`'s interface list instead of `Bar`). We need to keep looking at the same interface list that we started with.

Fixes #1421.
  • Loading branch information
MichalStrehovsky committed Aug 12, 2020
1 parent 3e97f1b commit fc5e4aa
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 7 deletions.
25 changes: 18 additions & 7 deletions src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,23 +500,34 @@ bool IsInterfaceOverrideThatDoesNotNeedMarked (OverrideInformation overrideInfor
return false;
}

bool IsInterfaceImplementationMarked (TypeDefinition type, TypeDefinition interfaceType)
bool IsInterfaceImplementationMarkedRecursively (TypeDefinition type, TypeDefinition interfaceType)
{
return type.HasInterface (@interfaceType, out InterfaceImplementation implementation) && Annotations.IsMarked (implementation);
if (type.HasInterfaces) {
foreach (var intf in type.Interfaces) {
TypeDefinition resolvedInterface = intf.InterfaceType.Resolve ();
if (resolvedInterface == null)
continue;

if (Annotations.IsMarked (intf) && RequiresInterfaceRecursively (resolvedInterface, interfaceType))
return true;
}
}

return false;
}

bool IsInterfaceImplementationMarkedRecursively (TypeDefinition type, TypeDefinition interfaceType)
bool RequiresInterfaceRecursively (TypeDefinition typeToExamine, TypeDefinition interfaceType)
{
if (IsInterfaceImplementationMarked (type, interfaceType))
if (typeToExamine == interfaceType)
return true;

if (type.HasInterfaces) {
foreach (var iface in type.Interfaces) {
if (typeToExamine.HasInterfaces) {
foreach (var iface in typeToExamine.Interfaces) {
var resolved = iface.InterfaceType.Resolve ();
if (resolved == null)
continue;

if (IsInterfaceImplementationMarkedRecursively (resolved, interfaceType))
if (RequiresInterfaceRecursively (resolved, interfaceType))
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Text;
using Mono.Linker.Tests.Cases.Expectations.Assertions;

namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType
{
class InterfaceNeededOnUnrelatedInterfaceList
{
[Kept]
static Foo s_foo;

static void Main ()
{
object ob = new Bar ();
((IBar) ob).Frob ();
s_foo = null;
}

[Kept]
interface IFoo
{
[Kept]
void Frob ();
}

[Kept]
[KeptInterface (typeof (IFoo))]
interface IBar : IFoo
{
}

[Kept]
class Foo : IBar
{
void IFoo.Frob ()
{
}
}

[Kept]
[KeptInterface (typeof (IBar))]
[KeptInterface (typeof (IFoo))]
class Bar : IBar
{
[Kept]
public Bar () { }

[Kept]
void IFoo.Frob ()
{
}
}
}
}

0 comments on commit fc5e4aa

Please sign in to comment.