Skip to content

Commit

Permalink
Small updates to help with linker->aot port (#2873)
Browse files Browse the repository at this point in the history
* Move GetDiagnosticCategory into shared code
* Describe the intent around usage of DiagnosticContext in a comment
* Minor fix in MessageOrigin GetHasCode
* Add tests for patterns which NativeAOT had trouble with

Linker changes made for dotnet/runtime#71485
  • Loading branch information
vitek-karas authored Jul 1, 2022
1 parent bc46e44 commit e4d8575
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 37 deletions.
28 changes: 4 additions & 24 deletions src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// 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 ILLink.Shared;
using Microsoft.CodeAnalysis;

Expand All @@ -15,7 +14,7 @@ public static DiagnosticDescriptor GetDiagnosticDescriptor (DiagnosticId diagnos
return new DiagnosticDescriptor (diagnosticId.AsString (),
diagnosticString.GetTitleFormat (),
diagnosticString.GetMessageFormat (),
GetDiagnosticCategory (diagnosticId),
diagnosticId.GetDiagnosticCategory (),
DiagnosticSeverity.Warning,
true);
}
Expand All @@ -24,7 +23,7 @@ public static DiagnosticDescriptor GetDiagnosticDescriptor (DiagnosticId diagnos
=> new DiagnosticDescriptor (diagnosticId.AsString (),
diagnosticString.GetTitle (),
diagnosticString.GetMessage (),
GetDiagnosticCategory (diagnosticId),
diagnosticId.GetDiagnosticCategory (),
DiagnosticSeverity.Warning,
true);

Expand All @@ -41,7 +40,7 @@ public static DiagnosticDescriptor GetDiagnosticDescriptor (DiagnosticId diagnos
return new DiagnosticDescriptor (diagnosticId.AsString (),
diagnosticString.GetTitleFormat (),
diagnosticString.GetMessageFormat (),
diagnosticCategory ?? GetDiagnosticCategory (diagnosticId),
diagnosticCategory ?? diagnosticId.GetDiagnosticCategory (),
diagnosticSeverity,
isEnabledByDefault,
helpLinkUri);
Expand All @@ -50,29 +49,10 @@ public static DiagnosticDescriptor GetDiagnosticDescriptor (DiagnosticId diagnos
return new DiagnosticDescriptor (diagnosticId.AsString (),
lrsTitle!,
lrsMessage!,
diagnosticCategory ?? GetDiagnosticCategory (diagnosticId),
diagnosticCategory ?? diagnosticId.GetDiagnosticCategory (),
diagnosticSeverity,
isEnabledByDefault,
helpLinkUri);
}

static string GetDiagnosticCategory (DiagnosticId diagnosticId)
{
switch ((int) diagnosticId) {
case > 2000 and < 3000:
return DiagnosticCategory.Trimming;

case >= 3000 and < 3050:
return DiagnosticCategory.SingleFile;

case >= 3050 and <= 6000:
return DiagnosticCategory.AOT;

default:
break;
}

throw new ArgumentException ($"The provided diagnostic id '{diagnosticId}' does not fall into the range of supported warning codes 2001 to 6000 (inclusive).");
}
}
}
10 changes: 10 additions & 0 deletions src/ILLink.Shared/DiagnosticId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// This is needed due to NativeAOT which doesn't enable nullable globally yet
#nullable enable

using System;

namespace ILLink.Shared
{
public enum DiagnosticId
Expand Down Expand Up @@ -224,5 +226,13 @@ public static string GetDiagnosticSubcategory (this DiagnosticId diagnosticId) =
>= 3054 and <= 3055 => MessageSubCategory.AotAnalysis,
_ => MessageSubCategory.None,
};

public static string GetDiagnosticCategory (this DiagnosticId diagnosticId) =>
(int) diagnosticId switch {
> 2000 and < 3000 => DiagnosticCategory.Trimming,
>= 3000 and < 3050 => DiagnosticCategory.SingleFile,
>= 3050 and <= 6000 => DiagnosticCategory.AOT,
_ => throw new ArgumentException ($"The provided diagnostic id '{diagnosticId}' does not fall into the range of supported warning codes 2001 to 6000 (inclusive).")
};
}
}
11 changes: 11 additions & 0 deletions src/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ namespace ILLink.Shared.TrimAnalysis
{
readonly partial struct DiagnosticContext
{
/// <summary>
/// The diagnostic context may be entirely disabled or some kinds of warnings may be suppressed.
/// The suppressions are determined based on the <paramref name="id"/>.
/// Typically the suppressions will be based on diagnostic category <see cref="DiagnosticCategory"/>:
/// - Trimmer warnings (suppressed by RequiresUnreferencedCodeAttribute)
/// - AOT warnings (suppressed by RequiresDynamicCodeAttribute)
/// - Single-file warnings (suppressed by RequiresAssemblyFilesAttribute)
/// Note that not all categories are used/supported by all tools, for example the ILLink only handles trimmer warnings and ignores the rest.
/// </summary>
/// <param name="id">The diagnostic ID, this will be used to determine the category of diagnostic (trimmer, AOT, single-file)</param>
/// <param name="args">The arguments for diagnostic message.</param>
public partial void AddDiagnostic (DiagnosticId id, params string[] args);
}
}
2 changes: 0 additions & 2 deletions src/linker/Linker/CompilerGeneratedState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ public static bool TryGetStateMachineType (MethodDefinition method, [NotNullWhen
/// </summary>
TypeDefinition? PopulateCacheForType (TypeDefinition type)
{
var originalType = type;

// Look in the declaring type if this is a compiler-generated type (state machine or display class).
// State machines can be emitted into display classes, so we may also need to go one more level up.
// To avoid depending on implementation details, we go up until we see a non-compiler-generated type.
Expand Down
2 changes: 1 addition & 1 deletion src/linker/Linker/MessageOrigin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public bool Equals (MessageOrigin other) =>
(FileName, Provider, SourceLine, SourceColumn, ILOffset) == (other.FileName, other.Provider, other.SourceLine, other.SourceColumn, other.ILOffset);

public override bool Equals (object? obj) => obj is MessageOrigin messageOrigin && Equals (messageOrigin);
public override int GetHashCode () => (FileName, Provider, SourceLine, SourceColumn).GetHashCode ();
public override int GetHashCode () => (FileName, Provider, SourceLine, SourceColumn, ILOffset).GetHashCode ();
public static bool operator == (MessageOrigin lhs, MessageOrigin rhs) => lhs.Equals (rhs);
public static bool operator != (MessageOrigin lhs, MessageOrigin rhs) => !lhs.Equals (rhs);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ class AttributeConstructorDataflow
{
[KeptAttributeAttribute (typeof (KeepsPublicConstructorAttribute))]
[KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))]
[KeptAttributeAttribute (typeof (TypeArrayAttribute))]
[KeepsPublicConstructor (typeof (ClassWithKeptPublicConstructor))]
[KeepsPublicMethods ("Mono.Linker.Tests.Cases.DataFlow.AttributeConstructorDataflow+ClassWithKeptPublicMethods")]
[TypeArray (new Type[] { typeof (AttributeConstructorDataflow) })]
// Trimmer only for now - https://github.com/dotnet/linker/issues/2273
[ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = ProducedBy.Trimmer)]
public static void Main ()
Expand Down Expand Up @@ -109,5 +111,15 @@ public void Method () { }
public int Field;
}
}

[Kept]
[KeptBaseType (typeof (Attribute))]
class TypeArrayAttribute : Attribute
{
[Kept]
public TypeArrayAttribute (Type[] types) // This should not trigger data flow analysis of the parameter
{
}
}
}
}
27 changes: 22 additions & 5 deletions test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ class AttributeFieldDataflow
{
[KeptAttributeAttribute (typeof (KeepsPublicConstructorsAttribute))]
[KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))]
[KeptAttributeAttribute (typeof (TypeArrayAttribute))]
[KeepsPublicConstructors (Type = typeof (ClassWithKeptPublicConstructor))]
[KeepsPublicMethods ("Mono.Linker.Tests.Cases.DataFlow.AttributeFieldDataflow+ClassWithKeptPublicMethods")]
[KeepsPublicMethods (Type = "Mono.Linker.Tests.Cases.DataFlow.AttributeFieldDataflow+ClassWithKeptPublicMethods")]
[TypeArray (Types = new Type[] { typeof (AttributeFieldDataflow) })]
// Trimmer only for now - https://github.com/dotnet/linker/issues/2273
[ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = ProducedBy.Trimmer)]
public static void Main ()
Expand Down Expand Up @@ -46,12 +48,14 @@ public KeepsPublicConstructorsAttribute ()
class KeepsPublicMethodsAttribute : Attribute
{
[Kept]
public KeepsPublicMethodsAttribute (
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
string type)
public KeepsPublicMethodsAttribute ()
{
}

[Kept]
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
public string Type;
}

[Kept]
Expand All @@ -74,5 +78,18 @@ class ClassWithKeptPublicMethods
public static void KeptMethod () { }
static void Method () { }
}

[Kept]
[KeptBaseType (typeof (Attribute))]
class TypeArrayAttribute : Attribute
{
[Kept]
public TypeArrayAttribute ()
{
}

[Kept]
public Type[] Types;
}
}
}
29 changes: 24 additions & 5 deletions test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ class AttributePropertyDataflow
{
[KeptAttributeAttribute (typeof (KeepsPublicConstructorsAttribute))]
[KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))]
[KeptAttributeAttribute (typeof (TypeArrayAttribute))]
[KeepsPublicConstructors (Type = typeof (ClassWithKeptPublicConstructor))]
[KeepsPublicMethods ("Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+ClassWithKeptPublicMethods")]
[KeepsPublicMethods (Type = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+ClassWithKeptPublicMethods")]
[TypeArray (Types = new Type[] { typeof (AttributePropertyDataflow) })]
// Trimmer only for now - https://github.com/dotnet/linker/issues/2273
[ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = ProducedBy.Trimmer)]
public static void Main ()
Expand Down Expand Up @@ -47,12 +49,15 @@ public KeepsPublicConstructorsAttribute ()
class KeepsPublicMethodsAttribute : Attribute
{
[Kept]
public KeepsPublicMethodsAttribute (
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
string type)
public KeepsPublicMethodsAttribute ()
{
}

[field: Kept]
[Kept]
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
public string Type { get; [Kept] set; }
}

[Kept]
Expand All @@ -75,5 +80,19 @@ class ClassWithKeptPublicMethods
public static void KeptMethod () { }
static void Method () { }
}

[Kept]
[KeptBaseType (typeof (Attribute))]
class TypeArrayAttribute : Attribute
{
[Kept]
public TypeArrayAttribute ()
{
}

[field: Kept]
[Kept]
public Type[] Types { get; [Kept] set; }
}
}
}
18 changes: 18 additions & 0 deletions test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,29 @@ static unsafe void IntPtrDeref ()
[RequiresUnreferencedCode ("")]
static IntPtr GetDangerous () { return IntPtr.Zero; }

[Kept]
[ExpectedWarning ("IL2070")]
static unsafe void LocalStackAllocDeref (Type t)
{
// Code pattern from CoreLib which caused problems in AOT port
// so making sure we handle this correctly (that is without failing)
int buffSize = 256;
byte* stackSpace = stackalloc byte[buffSize];
byte* buffer = stackSpace;

byte* toFree = buffer;
buffer = null;

// IL2070 - this is to make sure that DataFlow ran on the method's body
t.GetProperties ();
}

[Kept]
[ExpectedWarning ("IL2026")]
public static void Test ()
{
IntPtrDeref ();
LocalStackAllocDeref (null);
}
}
}
Expand Down

0 comments on commit e4d8575

Please sign in to comment.