diff options
author | Vitek Karas <vitek.karas@microsoft.com> | 2020-11-26 12:56:39 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-26 12:56:39 +0300 |
commit | 01f8592b4dcbc5a5e5e395cc2dba31260e3d3114 (patch) | |
tree | 7874312a72e8d73ccbb4998c5b8c741fbf64197f /test/Mono.Linker.Tests.Cases/DataFlow | |
parent | 93a76d90e751850e67357aa0f86ee0a9a7ce25d9 (diff) |
Fix linker crash on unresolved types in generic and attribute data flow handling (#1645)
Unresolved types should be handled as "unknown" value nodes. This is already the case when they appear in a method body. But when they're used either as generic arguments or in attribute instantiations linker doesn't handle this case correctly.
For generics linker would fail with an exception. For attributes linker would ignore the type.
Both cases are wrong since linker needs to make sure to issue a warning if it can't guarantee to meet the requirements posed by the data flow annotations. So ignoring unresolved types is also wrong.
The change fixes these behaviors to treat the value as "unknown" which leads into warnings when used somewhere with data flow requirements.
There's also a small change in where the attribute related warnings are reported - now they should consistently report the warning in the place where the attribute is used (and not on the attribute definition) and also correctly report which members are involved (it used to report the `this` for ctor arguments for example).
Added a new test infra capability to remove an assembly from linker input - to be able to emulate unresolved assembly.
Diffstat (limited to 'test/Mono.Linker.Tests.Cases/DataFlow')
-rw-r--r-- | test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/UnresolvedLibrary.cs | 17 | ||||
-rw-r--r-- | test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs | 130 |
2 files changed, 147 insertions, 0 deletions
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/UnresolvedLibrary.cs b/test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/UnresolvedLibrary.cs new file mode 100644 index 000000000..1ea25e791 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/Dependencies/UnresolvedLibrary.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Mono.Linker.Tests.Cases.DataFlow.Dependencies +{ + public class UnresolvedType + { + public static void Method () { } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs b/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs new file mode 100644 index 000000000..4bffba3f6 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs @@ -0,0 +1,130 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipPeVerify] + [SetupLinkerArgument ("--skip-unresolved", "true")] + [SetupCompileBefore ("UnresolvedLibrary.dll", new[] { "Dependencies/UnresolvedLibrary.cs" }, removeFromLinkerInput: true)] + class UnresolvedMembers + { + public static void Main () + { + UnresolvedGenericArgument (); + UnresolvedAttributeArgument (); + UnresolvedAttributePropertyValue (); + UnresolvedAttributeFieldValue (); + UnresolvedObjectGetType (); + UnresolvedMethodParameter (); + } + + [Kept] + [KeptMember (".ctor()")] + class TypeWithUnresolvedGenericArgument< + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> + { + } + + [Kept] + static void MethodWithUnresolvedGenericArgument< + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () + { } + + [Kept] + [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument")] + [ExpectedWarning ("IL2066", nameof (MethodWithUnresolvedGenericArgument))] + static void UnresolvedGenericArgument () + { + var a = new TypeWithUnresolvedGenericArgument<Dependencies.UnresolvedType> (); + MethodWithUnresolvedGenericArgument<Dependencies.UnresolvedType> (); + } + + [Kept] + [KeptBaseType (typeof (Attribute))] + class AttributeWithRequirements : Attribute + { + [Kept] + public AttributeWithRequirements ( + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { } + + [Kept] + [KeptBackingField] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public Type PropertyWithRequirements { get; [Kept] set; } + + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public Type FieldWithRequirements; + } + + [Kept] + [ExpectedWarning ("IL2062", nameof (AttributeWithRequirements))] + [KeptAttributeAttribute (typeof (AttributeWithRequirements))] + [AttributeWithRequirements (typeof (Dependencies.UnresolvedType))] + static void UnresolvedAttributeArgument () + { + } + + [Kept] + [ExpectedWarning ("IL2062", nameof (AttributeWithRequirements.PropertyWithRequirements))] + [KeptAttributeAttribute (typeof (AttributeWithRequirements))] + [AttributeWithRequirements (typeof (EmptyType), PropertyWithRequirements = typeof (Dependencies.UnresolvedType))] + static void UnresolvedAttributePropertyValue () + { + } + + [Kept] + [ExpectedWarning ("IL2064", nameof (AttributeWithRequirements.FieldWithRequirements))] + [KeptAttributeAttribute (typeof (AttributeWithRequirements))] + [AttributeWithRequirements (typeof (EmptyType), FieldWithRequirements = typeof (Dependencies.UnresolvedType))] + static void UnresolvedAttributeFieldValue () + { + } + + [Kept] + static Dependencies.UnresolvedType _unresolvedField; + + [Kept] + [ExpectedWarning ("IL2072", nameof (Object.GetType))] + static void UnresolvedObjectGetType () + { + RequirePublicMethods (_unresolvedField.GetType ()); + } + + [Kept] + [ExpectedWarning ("IL2072", nameof (Object.GetType))] + static void UnresolvedMethodParameter () + { + RequirePublicMethods (typeof (Dependencies.UnresolvedType)); + } + + [Kept] + class EmptyType + { + } + + [Kept] + static void RequirePublicMethods ( + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + Type t) + { + } + } +} |