Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2733,22 +2733,16 @@ void MarkGenericArguments (IGenericInstance instance, MessageOrigin origin)
{
var arguments = instance.GenericArguments;

var generic_element = GetGenericProviderFromInstance (instance);
if (generic_element == null)
return;

var parameters = generic_element.GenericParameters;

if (arguments.Count != parameters.Count)
return;
IGenericParameterProvider? generic_element = GetGenericProviderFromInstance (instance);
Collection<GenericParameter>? parameters = generic_element?.GenericParameters;

for (int i = 0; i < arguments.Count; i++) {
var argument = arguments[i];
var parameter = parameters[i];
var parameter = parameters?[i];

var argumentTypeDef = MarkType (argument, new DependencyInfo (DependencyKind.GenericArgumentType, instance), origin);

if (Annotations.FlowAnnotations.RequiresGenericArgumentDataFlowAnalysis (parameter)) {
if (parameter is not null && Annotations.FlowAnnotations.RequiresGenericArgumentDataFlowAnalysis (parameter)) {
// The only two implementations of IGenericInstance both derive from MemberReference
Debug.Assert (instance is MemberReference);

Expand All @@ -2762,7 +2756,7 @@ void MarkGenericArguments (IGenericInstance instance, MessageOrigin origin)

_dependencyGraph.AddRoot (_nodeFactory.GetTypeIsRelevantToVariantCastingNode (argumentTypeDef), "Generic Argument");

if (parameter.HasDefaultConstructorConstraint)
if (parameter?.HasDefaultConstructorConstraint == true)
MarkDefaultConstructor (argumentTypeDef, new DependencyInfo (DependencyKind.DefaultCtorForNewConstrainedGenericArgument, instance), origin);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public Task OverrideWithAnotherVirtualMethodOfSameNameWithDifferentParameterType
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnresolvedGenerics ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedOverloadedGenericMethodInGenericClassIsNotStripped ()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Diagnostics.CodeAnalysis;

namespace Mono.Linker.Tests.Cases.Generics.Dependencies
{
public class UnresolvedGenericsLibrary
{
public class GenericClass<T> { }

public static void GenericMethod<T> () { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;

using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.Generics.Dependencies;

namespace Mono.Linker.Tests.Cases.Generics
{
[IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/103843", IgnoredBy = Tool.NativeAot)]
[KeptAttributeAttribute (typeof (IgnoreTestCaseAttribute), By = Tool.Trimmer)]
[SetupCompileBefore ("UnresolvedGenericsLibrary.dll", new[] { "Dependencies/UnresolvedGenericsLibrary.cs" },
removeFromLinkerInput: true)]
class UnresolvedGenerics
{
static void Main ()
{
UnresolvedGenericType ();
UnresolvedGenericBaseType ();
UnresolvedGenericMethod ();
}

[Kept]
class GenericTypeArgument { }

[Kept]
static void UnresolvedGenericType ()
{
new UnresolvedGenericsLibrary.GenericClass<GenericTypeArgument> ();
}

[Kept]
class BaseTypeGenericArgument { }

[Kept]
[KeptMember (".ctor()")]
[KeptBaseType (typeof (UnresolvedGenericsLibrary.GenericClass<BaseTypeGenericArgument>))]
class HasBaseType : UnresolvedGenericsLibrary.GenericClass<BaseTypeGenericArgument> { }

[Kept]
static void UnresolvedGenericBaseType ()
{
new HasBaseType ();
}

[Kept]
class GenericMethodArgument { }

[Kept]
static void UnresolvedGenericMethod ()
{
UnresolvedGenericsLibrary.GenericMethod<GenericMethodArgument> ();
}
}
}