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
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,13 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)

PropertyPseudoDesc property = new PropertyPseudoDesc(ecmaType, propertyHandle);

if (CompilerGeneratedNames.IsExtensionType(ecmaType.Name))
{
// Annotations on extension properties are not supported.
_logger.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnExtensionProperties, property.GetDisplayName());
continue;
}

if (!IsTypeInterestingForDataflow(property.Signature.ReturnType))
{
_logger.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings, property.GetDisplayName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class ILCompilerOptions
public List<string> InitAssemblies = new List<string>();
public List<string> TrimAssemblies = new List<string>();
public List<string> AdditionalRootAssemblies = new List<string>();
public List<string> RootEntireAssemblies = new List<string>();
public Dictionary<string, bool> FeatureSwitches = new Dictionary<string, bool>();
public List<string> Descriptors = new List<string>();
public bool FrameworkCompilation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal static class NameUtils
MethodDesc method => TrimAssemblyNamePrefix(method.GetDisplayName()),
FieldDesc field => TrimAssemblyNamePrefix(field.ToString()),
ModuleDesc module => module.Assembly.GetName().Name,
PropertyPseudoDesc property => TrimAssemblyNamePrefix(property.GetDisplayName()),
_ => null
};

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ public class TestCaseLinkerOptions
public List<string> Substitutions = new List<string>();

public List<string> LinkAttributes = new List<string>();

public List<string> RootEntireAssemblies = new List<string>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ public virtual TestCaseLinkerOptions GetLinkerOptions(NPath inputPath)
tclo.AdditionalArguments.Add(new KeyValuePair<string, string[]>((string)ca[0].Value, values));
}

foreach (var rootEntire in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupRootEntireAssemblyAttribute)))
{
var ca = rootEntire.ConstructorArguments;
var assemblyName = (string)ca[0].Value;
tclo.RootEntireAssemblies.Add(assemblyName);
}

return tclo;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ public virtual void ProcessOptions(TestCaseLinkerOptions options)
foreach (var additionalArgument in options.AdditionalArguments)
AddAdditionalArgument(additionalArgument.Key, additionalArgument.Value);

if (options.RootEntireAssemblies?.Count > 0)
{
foreach (var asm in options.RootEntireAssemblies)
Options.RootEntireAssemblies.Add(asm);
}

if (options.IlcFrameworkCompilation)
Options.FrameworkCompilation = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public ILScanResults Trim(ILCompilerOptions options, TrimmingCustomizations? cus
options: default,
logger: logger,
featureSwitchValues: options.FeatureSwitches,
rootEntireAssembliesModules: Array.Empty<string>(),
rootEntireAssembliesModules: options.RootEntireAssemblies,
additionalRootedAssemblies: options.AdditionalRootAssemblies.ToArray(),
trimmedAssemblies: options.TrimAssemblies.ToArray(),
satelliteAssemblyFilePaths: Array.Empty<string>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using ILCompiler;
using ILCompiler.Logging;
Expand All @@ -24,9 +25,9 @@ public TrimmingTestLogger()

public TextWriter Writer => _infoWriter;

public List<MessageContainer> GetLoggedMessages()
public ImmutableArray<MessageContainer> GetLoggedMessages()
{
return _messageContainers;
return _messageContainers.ToImmutableArray();
}

public void WriteError(MessageContainer error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ private static ImmutableArray<RequiresAnalyzerBase> GetRequiresAnalyzers() =>

public static ImmutableArray<DiagnosticDescriptor> GetSupportedDiagnostics()
{
var diagDescriptorsArrayBuilder = ImmutableArray.CreateBuilder<DiagnosticDescriptor>(26);
var diagDescriptorsArrayBuilder = ImmutableArray.CreateBuilder<DiagnosticDescriptor>(27);
diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnreferencedCode));
diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnMethods));
diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnExtensionProperties));
AddRange(DiagnosticId.MethodParameterCannotBeStaticallyDetermined, DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter);
AddRange(DiagnosticId.DynamicallyAccessedMembersOnFieldCanOnlyApplyToTypesOrStrings, DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings);
diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersOnMethodReturnValueCanOnlyApplyToTypesOrStrings));
Expand Down Expand Up @@ -188,9 +189,12 @@ private static void VerifyMemberOnlyApplyToTypesOrStrings(SymbolAnalysisContext
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersOnMethodParameterCanOnlyApplyToTypesOrStrings), location, parameter.GetDisplayName(), member.GetDisplayName()));
}
}
else if (member is IPropertySymbol property && property.GetDynamicallyAccessedMemberTypes() != DynamicallyAccessedMemberTypes.None && !property.Type.IsTypeInterestingForDataflow(isByRef: property.ReturnsByRef))
else if (member is IPropertySymbol property)
{
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings), location, member.GetDisplayName()));
if (property.GetDynamicallyAccessedMemberTypes() != DynamicallyAccessedMemberTypes.None && !property.Type.IsTypeInterestingForDataflow(isByRef: property.ReturnsByRef))
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings), location, member.GetDisplayName()));
if (property.GetDynamicallyAccessedMemberTypes() != DynamicallyAccessedMemberTypes.None && property.ContainingType.ExtensionParameter != null)
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnExtensionProperties), location, member.GetDisplayName()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,10 @@ internal static bool IsLocalFunction(string methodName)
// Ignore the method ordinal/generation and local function ordinal/generation.
return methodName.Length > i + 1 && methodName[i + 1] == 'g';
}

internal static bool IsExtensionType(string typeName)
{
return typeName.StartsWith("<G>");
}
}
}
1 change: 1 addition & 0 deletions src/tools/illink/src/ILLink.Shared/DiagnosticId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ public enum DiagnosticId
TypeMapGroupTypeCannotBeStaticallyDetermined = 2124,
ReferenceNotMarkedIsTrimmable = 2125,
DataflowAnalysisDidNotConverge = 2126,
DynamicallyAccessedMembersIsNotAllowedOnExtensionProperties = 2127,
_EndTrimAnalysisWarningsSentinel,

// Single-file diagnostic ids.
Expand Down
6 changes: 6 additions & 0 deletions src/tools/illink/src/ILLink.Shared/SharedStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,12 @@
<data name="DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessorMessage" xml:space="preserve">
<value>'DynamicallyAccessedMembersAttribute' on property '{0}' conflicts with the same attribute on its accessor '{1}'.</value>
</data>
<data name="DynamicallyAccessedMembersIsNotAllowedOnExtensionPropertiesTitle" xml:space="preserve">
<value>'DynamicallyAccessedMembersAttribute' on extension property is ignored</value>
</data>
<data name="DynamicallyAccessedMembersIsNotAllowedOnExtensionPropertiesMessage" xml:space="preserve">
<value>'DynamicallyAccessedMembersAttribute' on extension property '{0}' is not supported and has no effect. Apply the attribute to the accessor return value or value parameter instead.</value>
</data>
<data name="XmlCouldNotFindAnyTypeInNamespaceTitle" xml:space="preserve">
<value>The XML descriptor specifies a namespace but there are no types found in such namespace.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,13 @@ TypeAnnotations BuildTypeAnnotations(TypeDefinition type)
if (annotation == DynamicallyAccessedMemberTypes.None)
continue;

if (CompilerGeneratedNames.IsExtensionType(type.Name))
{
// Annotations on extension properties are not supported.
_context.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnExtensionProperties, property.GetDisplayName());
continue;
}

if (!IsTypeInterestingForDataflow(property.PropertyType))
{
_context.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings, property.GetDisplayName());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Mono.Linker.Tests.Cases.Expectations.Metadata
{
/// <summary>
/// Request that the specified assembly's entire contents be kept.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class SetupRootEntireAssemblyAttribute : BaseMetadataAttribute
{
public SetupRootEntireAssemblyAttribute(string assembly)
{
if (string.IsNullOrEmpty(assembly))
throw new ArgumentNullException(nameof(assembly));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class AttributesOnProperty
[Kept]
[KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))]
[ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")]
[UnexpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[KeepsPublicMethods(Type = typeof(ClassWithKeptPublicMethods))]
public static bool Property { [Kept] get; [Kept] set; }

Expand Down Expand Up @@ -174,6 +175,7 @@ class AttributesOnEvent
[KeptEventRemoveMethod]
[KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))]
[ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")]
[UnexpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[KeepsPublicMethods(Type = typeof(ClassWithKeptPublicMethods))]
public static event EventHandler Event_FieldSyntax;

Expand All @@ -183,6 +185,7 @@ class AttributesOnEvent
[KeptEventRemoveMethod]
[KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))]
[ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")]
[UnexpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[KeepsPublicMethods(Type = typeof(ClassWithKeptPublicMethods))]
public static event EventHandler Event_PropertySyntax
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
namespace Mono.Linker.Tests.Cases.DataFlow
{
[SkipKeptItemsValidation]
[IgnoreTestCase("NativeAOT sometimes emits duplicate IL2041: https://github.com/dotnet/runtime/issues/119155", IgnoredBy = Tool.NativeAot)]
// [IgnoreTestCase("NativeAOT sometimes emits duplicate IL2041: https://github.com/dotnet/runtime/issues/119155", IgnoredBy = Tool.NativeAot)]
// Root the entire assembly to ensure that ILLink/ILC analyze extension properties which are otherwise unused in IL.
[SetupRootEntireAssembly("test")]
[ExpectedNoWarnings]
public class ExtensionMembersDataFlow
{
Expand Down Expand Up @@ -188,6 +190,7 @@ public void ExtensionMembersMethodWithParamsMismatch([DynamicallyAccessedMembers
public static void ExtensionMembersStaticMethodRequires() { }

[ExpectedWarning("IL2041")]
[ExpectedWarning("IL2041", Tool.Trimmer | Tool.NativeAot, "Analyzer doesn't see generated extension metadata type", CompilerGeneratedCode = true)]
[ExpectedWarning("IL2067", nameof(DataFlowTypeExtensions.RequiresPublicMethods))]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
public void ExtensionMembersMethodAnnotation()
Expand All @@ -197,13 +200,13 @@ public void ExtensionMembersMethodAnnotation()
}

[ExpectedWarning("IL2041")]
[ExpectedWarning("IL2041", Tool.Trimmer | Tool.NativeAot, "Analyzer doesn't see generated extension metadata type", CompilerGeneratedCode = true)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
public static void ExtensionMembersStaticMethodAnnotation()
{
}

// Annotations on extension properties have no effect:
// https://github.com/dotnet/runtime/issues/119113
[ExpectedWarning("IL2127", CompilerGeneratedCode = true)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
public Type ExtensionMembersProperty
{
Expand All @@ -213,8 +216,7 @@ public Type ExtensionMembersProperty
set => value.RequiresPublicMethods();
}

// Annotations on extension properties have no effect:
// https://github.com/dotnet/runtime/issues/119113
[ExpectedWarning("IL2127", CompilerGeneratedCode = true)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
public Type ExtensionMembersPropertyMismatch
{
Expand Down Expand Up @@ -249,8 +251,7 @@ public Type ExtensionMembersPropertyRequires
get => null;
}

// Annotations on extension properties have no effect:
// https://github.com/dotnet/runtime/issues/119113
[ExpectedWarning("IL2127", CompilerGeneratedCode = true)]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
public Type ExtensionMembersPropertyConflict
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Mono.Linker.Tests.Cases.Metadata
{
[VerifyMetadataNames]
[SetupLinkerArgument("-a", "test.exe", "all")]
[SetupRootEntireAssembly("test")]
[KeptMember(".ctor()")]
public class RootAllAssemblyNamesAreKept
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

namespace Mono.Linker.Tests.Cases.RequiresCapability
{
[IgnoreTestCase("NativeAOT test infrastructure doesn't implement rooting behavior the same way", IgnoredBy = Tool.NativeAot)]
[SetupLinkerArgument("-a", "test.exe", "all")]

[SetupRootEntireAssembly("test")]
[SkipKeptItemsValidation]
[ExpectedNoWarnings]
public class RequiresInRootAllAssembly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,17 @@ static void MethodWithAttributeWhichRequires () { }
static int _fieldWithAttributeWhichRequires;

[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
[UnexpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")]
[UnexpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")]
[UnexpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")]
[UnexpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")]
[UnexpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")]
[UnexpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/120004")]
[AttributeWhichRequires]
[AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)]
static bool PropertyWithAttributeWhichRequires { get; set; }
Expand Down
Loading
Loading