Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 1 addition & 2 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<PreReleaseVersionLabel>1</PreReleaseVersionLabel>
</PropertyGroup>
<PropertyGroup>
<UsingToolMicrosoftNetCompilers>true</UsingToolMicrosoftNetCompilers>
<!-- ilasm -->
<MicrosoftNETSdkILPackageVersion>7.0.0-rc.1.22374.4</MicrosoftNETSdkILPackageVersion>
<!-- see https://github.com/dotnet/runtime/issues/1338 -->
Expand All @@ -21,7 +20,7 @@
<MicrosoftDotNetApiCompatVersion>7.0.0-beta.22372.1</MicrosoftDotNetApiCompatVersion>
<MicrosoftDotNetCodeAnalysisVersion>6.0.0-beta.21271.1</MicrosoftDotNetCodeAnalysisVersion>
<MicrosoftCodeAnalysisCSharpCodeStyleVersion>3.10.0-2.final</MicrosoftCodeAnalysisCSharpCodeStyleVersion>
<MicrosoftCodeAnalysisVersion>4.3.0-2.final</MicrosoftCodeAnalysisVersion>
<MicrosoftCodeAnalysisVersion>4.4.0-2.22379.3</MicrosoftCodeAnalysisVersion>
<MicrosoftCodeAnalysisCSharpAnalyzerTestingXunitVersion>1.0.1-beta1.*</MicrosoftCodeAnalysisCSharpAnalyzerTestingXunitVersion>
<MicrosoftCodeAnalysisBannedApiAnalyzersVersion>3.3.2</MicrosoftCodeAnalysisBannedApiAnalyzersVersion>
<!-- This controls the version of the cecil package, or the version of cecil in the project graph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public Task InterfaceMethodImplementedOnBaseClassDoesNotGetStripped ()
return RunTest (allowMissingWarnings: true);
}

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

[Fact]
public Task MultiLevelNestedClassesAllRemovedWhenNonUsed ()
{
Expand Down
119 changes: 119 additions & 0 deletions test/Mono.Linker.Tests.Cases/Basic/LinkerHandlesRefFields.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// 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.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Mono.Linker.Tests.Cases.Expectations.Assertions;

namespace Mono.Linker.Tests.Cases.Basic
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Add a comment describing what the test is trying to validate - mainly that it's only meant to validate that linker doesn't crash or do other weird things on ref fields. And that it's not meant as full validation of all functionality around ref fields.

[ExpectedNoWarnings]
[SkipKeptItemsValidation]
class LinkerHandlesRefFields
{
ref struct RS
{
public ref int i;
public ref double d;
public RS2 rs2;
public ref string str;
public ref object obj;
public ref Type t;
public void MoveThis ()
{
this = new RS ();
}
}

ref struct RS2
{
public ref int i;
public ref double d;
public ref string str;
public ref object obj;
public ref Type t;
public void MoveThis ()
{
this = new RS2 ();
}
}

delegate RS2 RsParamRs2Return (RS rs);
delegate ref RS2 RefRSParamRefRs2Return (ref RS rs);
delegate ref int RsParamRefIntReturn (RS rs);

public static void Main (string[] args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually don't know if some of these are valid, but still:

  • ref struct in a generic parameter
  • ref return and parameter on a virtual method?
  • Put annotations (DAM/RUC on type) on the ref field - don't care if it works correctly, but should not crash

Copy link
Member Author

@jtschuster jtschuster Aug 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ref struct in a generic parameter

Ref structs will generate CS0306 if used as a type parameter.

ref return and parameter on a virtual method?

Added IRS interface and Base and Derived classes with virtual methods with ref structs as return, ref return, parameter, and ref parameter.

Put annotations (DAM/RUC on type) on the ref field

RUC can't be placed on structs and ref structs can't implement interfaces, so I don't think there's a way that they could be annotated with DAM. I've added DAM on a field and DAM and RUC on a method return and parameter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot!

{
scoped RS rs = new RS ();
scoped RS2 rs2 = new RS2 ();

// Assign by value
rs.i = rs2.i;
rs2.d = rs2.d;
rs.obj = rs2.obj;
rs2.t = rs.t;

// Assign by ref
rs.i = ref rs2.i;
rs2.d = ref rs2.d;
rs.obj = ref rs2.obj;
rs2.t = ref rs.t;

// Assign in different basic blocks
if (args[0] == "") {
rs.i = ref rs2.i;
rs.d = rs2.d;
rs.obj = ref rs2.obj;
rs.t = rs2.t;
} else {
rs2.i = rs.i;
rs2.d = ref rs.d;
rs2.obj = rs.obj;
rs2.t = ref rs.t;
}

// Cast fields
rs.t = (Type) rs.obj;
rs.i = (int) rs.d;
rs2.i = (int) rs.d;

// In Lambdas
RsParamRs2Return f = (RS rs) => rs.rs2;
rs.rs2 = f (rs);
RefRSParamRefRs2Return h = (ref RS rs) => ref rs.rs2;
rs.rs2 = h (ref rs);
RsParamRefIntReturn g = (RS rs) => ref f (rs).i;
rs.i = g (rs);

// As parameters and returns for local functions
RS LocalMethod (RS2 rs)
{
rs.d = 0.2;
return new RS ();
}
rs = LocalMethod (rs.rs2);

ref RS LocalMethodRef (ref RS rs)
{
return ref rs;
}
ref RS refRs = ref LocalMethodRef (ref rs);
refRs = LocalMethodRef (ref rs);

ref int ReturnRefInt (ref int i)
{
return ref i;
}
rs.i = ReturnRefInt (ref rs2.i);

// Call methods with this
rs.MoveThis ();
rs2.MoveThis ();
}
}
}
18 changes: 18 additions & 0 deletions test/Mono.Linker.Tests.Cases/Basic/UnusedFieldsOfStructsAreKept.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.Expectations.Assertions;

namespace Mono.Linker.Tests.Cases.Basic
Expand All @@ -8,6 +10,7 @@ public static void Main ()
{
A a = new A ();
PreventCompilerOptimization (a);
R r = new R ();
}

[Kept]
Expand All @@ -27,5 +30,20 @@ public void UnusedMethod ()
{
}
}

[KeptAttributeAttribute (typeof (IsByRefLikeAttribute))]
[KeptAttributeAttribute (typeof (CompilerFeatureRequiredAttribute))]
[KeptAttributeAttribute (typeof (ObsoleteAttribute))]
ref struct R
{
[Kept]
public ref int UnusedRefField;

[Kept]
int UnusedField;

[Kept]
int UsedField;
}
}
}