-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[release/8.0] Implement support for
InlineArray
in the trimmer (#92107
) * Implement support for InlineArray in the trimmer Types annotated with `InlineArray` need to preserve all of their fields, even if otherwise this would not be the case. It's possible to have a struct with `LayoutKind.Auto` and with `InlineArray` - trimmer would normally trim fields on such struct. This leads to corruption since the field is never accessed directly. This changes the marking to preserve all fields on a type with `InlineArray` attribute just like we would for explicit layout struct and similar other types. Adds tests to cover both the explicit usage of `InlineArray` attribute as well as the compiler generate usage via collection literals. * Update src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InlineArrayDataflow.cs Co-authored-by: Sven Boemer <sbomer@gmail.com> --------- Co-authored-by: vitek-karas <10670590+vitek-karas@users.noreply.github.com> Co-authored-by: Sven Boemer <sbomer@gmail.com>
- Loading branch information
1 parent
28e72d2
commit e17d2f5
Showing
11 changed files
with
230 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/InlineArraysTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// 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.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace ILLink.RoslynAnalyzer.Tests | ||
{ | ||
public sealed partial class InlineArraysTests : LinkerTestBase | ||
{ | ||
protected override string TestSuiteName => "InlineArrays"; | ||
|
||
[Fact] | ||
public Task InlineArray () | ||
{ | ||
return RunTest (nameof (InlineArray)); | ||
} | ||
|
||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InlineArrayDataflow.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// 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.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using Mono.Linker.Tests.Cases.Expectations.Assertions; | ||
|
||
namespace Mono.Linker.Tests.Cases.DataFlow | ||
{ | ||
[SkipKeptItemsValidation] | ||
[ExpectedNoWarnings] | ||
public class InlineArrayDataflow | ||
{ | ||
public static void Main() | ||
{ | ||
AccessPrimitiveTypeArray (); | ||
AccessUnannotatedTypeArray (); | ||
AccessAnnotatedTypeArray (); | ||
} | ||
|
||
public int TestProperty { get; set; } | ||
|
||
[InlineArray (5)] | ||
struct PrimitiveTypeArray | ||
{ | ||
public BindingFlags value; | ||
} | ||
|
||
// This case will fallback to not understanding the binding flags and will end up marking all properties | ||
static void AccessPrimitiveTypeArray () | ||
{ | ||
PrimitiveTypeArray a = new PrimitiveTypeArray (); | ||
ref var item = ref a[1]; | ||
item = BindingFlags.Public; | ||
|
||
typeof (InlineArrayDataflow).GetProperty (nameof (TestProperty), a[1]); | ||
} | ||
|
||
[InlineArray (5)] | ||
struct UnannotatedTypeArray | ||
{ | ||
public Type value; | ||
} | ||
|
||
// Analyzer doesn't understand inline arrays currently - so it doesn't produce a warning here | ||
[ExpectedWarning ("IL2065", "GetProperty", ProducedBy = Tool.Trimmer | Tool.NativeAot)] | ||
static void AccessUnannotatedTypeArray () | ||
{ | ||
UnannotatedTypeArray a = new UnannotatedTypeArray (); | ||
ref var item = ref a[2]; | ||
item = typeof (InlineArrayDataflow); | ||
|
||
a[2].GetProperty (nameof (TestProperty)); | ||
} | ||
|
||
[InlineArray (5)] | ||
struct AnnotatedTypeArray | ||
{ | ||
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] | ||
public Type value; | ||
} | ||
|
||
// Currently tracking of annotations on inline array values is not implemented | ||
[ExpectedWarning("IL2065", "GetProperty", ProducedBy = Tool.Trimmer | Tool.NativeAot)] | ||
static void AccessAnnotatedTypeArray () | ||
{ | ||
AnnotatedTypeArray a = new AnnotatedTypeArray (); | ||
ref var item = ref a[3]; | ||
item = typeof (InlineArrayDataflow); | ||
|
||
a[3].GetProperty (nameof (TestProperty)); | ||
} | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
src/tools/illink/test/Mono.Linker.Tests.Cases/InlineArrays/InlineArray.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// 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.Collections.Immutable; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using Mono.Linker.Tests.Cases.Expectations.Assertions; | ||
|
||
namespace Mono.Linker.Tests.Cases.InlineArrays | ||
{ | ||
[ExpectedNoWarnings] | ||
public class InlineArray | ||
{ | ||
public static void Main() | ||
{ | ||
InlineArrayUsage.Test (); | ||
CollectionLiteralsOfArrays.Test (); | ||
} | ||
|
||
[Kept] | ||
class InlineArrayUsage | ||
{ | ||
// NativeAOT will remove most of the struct type information as it's not needed | ||
// in the generated native code. Eventually we might come up with a better test infra to validate this. | ||
[Kept (By = Tool.Trimmer)] | ||
public struct StructWithFixedBuffer | ||
{ | ||
[Kept (By = Tool.Trimmer)] | ||
public FixedBuffer Buffer; | ||
|
||
[Kept (By = Tool.Trimmer)] | ||
[KeptAttributeAttribute (typeof(InlineArrayAttribute), By = Tool.Trimmer)] | ||
[InlineArray (8)] | ||
public partial struct FixedBuffer | ||
{ | ||
[Kept (By = Tool.Trimmer)] | ||
public int e0; | ||
} | ||
} | ||
|
||
[Kept (By = Tool.Trimmer)] | ||
public struct StructWithAutoLayoutBuffer | ||
{ | ||
[Kept (By = Tool.Trimmer)] | ||
public AutoLayoutBuffer Buffer; | ||
|
||
[Kept (By = Tool.Trimmer)] | ||
[KeptAttributeAttribute (typeof (InlineArrayAttribute), By = Tool.Trimmer)] | ||
[InlineArray (8)] | ||
[StructLayout (LayoutKind.Auto)] | ||
public struct AutoLayoutBuffer | ||
{ | ||
[Kept (By = Tool.Trimmer)] | ||
public int e0; | ||
} | ||
} | ||
|
||
[Kept] | ||
public static void Test () | ||
{ | ||
var s = new StructWithFixedBuffer (); | ||
s.Buffer[0] = 5; | ||
|
||
var sa = new StructWithAutoLayoutBuffer (); | ||
_ = sa.Buffer[1]; | ||
} | ||
} | ||
|
||
[Kept] | ||
[KeptMember (".cctor()")] | ||
class CollectionLiteralsOfArrays | ||
{ | ||
[Kept] | ||
public static readonly ImmutableArray<string> ImmutableValues = ["one", "two"]; | ||
[Kept] | ||
public static readonly string[] ArrayValues = ["one", "two"]; | ||
|
||
[Kept] | ||
public static void Test() | ||
{ | ||
_ = CollectionLiteralsOfArrays.ImmutableValues[0]; | ||
_ = CollectionLiteralsOfArrays.ArrayValues[1]; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters