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
1 change: 1 addition & 0 deletions src/coreclr/tools/ILTrim.Tests/ILTrimExpectedFailures.txt
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ Substitutions.EmbeddedMethodSubstitutionsInReferencedAssembly
Substitutions.EmbeddedSubstitutions
Substitutions.EmbeddedSubstitutionsKept
Substitutions.EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutionsAndRemoved
Substitutions.EnumSubstitutions
Substitutions.FeatureGuardSubstitutions
Substitutions.FeatureGuardSubstitutionsDisabled
Substitutions.RemoveBody
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.IO;
using System.Reflection.Metadata;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
using System.Xml;
using System.Xml.XPath;
using System.Globalization;
Expand Down Expand Up @@ -163,6 +164,26 @@ private static MethodDesc FindMethod(TypeDesc type, string signature)

private static object TryCreateSubstitution(TypeDesc type, string value)
{
if (type.IsEnum && type.UnderlyingType.Category == TypeFlags.Int32)
{
foreach (FieldDesc field in type.GetFields())
{
if (field.IsStatic &&
field.Name.StringEquals(value) &&
field is EcmaField ecmaField)
{
MetadataReader reader = ecmaField.MetadataReader;
ConstantHandle constantHandle = reader.GetFieldDefinition(ecmaField.Handle).GetDefaultValue();
if (!constantHandle.IsNil)
{
Constant constant = reader.GetConstant(constantHandle);
if (constant.TypeCode == ConstantTypeCode.Int32)
return reader.GetBlobReader(constant.Value).ReadInt32();
}
}
}
}

switch (type.UnderlyingType.Category)
{
case TypeFlags.Int32:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public void Substitutions(string t)
{
switch (t)
{
case "EnumSubstitutions":
case "FeatureGuardSubstitutions":
Run(t);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,10 @@ public bool TryConvertValue(string value, TypeReference target, out object? resu
result = Convert.ToInt32(enumField.Constant);
return true;
}

var underlyingType = typeDefinition.GetEnumUnderlyingType();
if (underlyingType.MetadataType == MetadataType.Int32)
return TryConvertValue(value, underlyingType, out result);
Comment thread
jtschuster marked this conversation as resolved.
}

break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// 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.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;

namespace Mono.Linker.Tests.Cases.Substitutions
{
[ExpectedNoWarnings]
[SetupLinkerSubstitutionFile("EnumSubstitutions.xml")]
[IgnoreSubstitutions(false)]
[SkipKeptItemsValidation(By = Tool.NativeAot)]
public class EnumSubstitutions
{
[Kept]
[KeptMember("value__")]
[KeptBaseType(typeof(Enum))]
private enum SubstitutionValue
{
[Kept]
Initial,

[Kept]
ByName,

[Kept]
ByNumber,
}

[Kept]
private static readonly SubstitutionValue FieldByName = SubstitutionValue.Initial;

[Kept]
private static readonly SubstitutionValue FieldByNumber = SubstitutionValue.Initial;

public static void Main()
{
VerifyFieldByNameSubstitution();
VerifyFieldByNumberSubstitution();
MethodByName();
MethodByNumber();
}

[Kept]
[ExpectedInstructionSequence(new[] {
"nop",
"ldsfld Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions/SubstitutionValue Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions::FieldByName",
"ldc.i4.1",
"ceq",
"ldc.i4.0",
"ceq",
"stloc.0",
"ldloc.0",
"brfalse.s il_10",
"ret",
})]
private static void VerifyFieldByNameSubstitution()
{
if (FieldByName != SubstitutionValue.ByName)
ReachableOnUnexpectedFieldByNameValue();
}

private static void ReachableOnUnexpectedFieldByNameValue()
{
}

[Kept]
[ExpectedInstructionSequence(new[] {
"nop",
"ldsfld Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions/SubstitutionValue Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions::FieldByNumber",
"ldc.i4.2",
"ceq",
"ldc.i4.0",
"ceq",
"stloc.0",
"ldloc.0",
"brfalse.s il_10",
"ret",
})]
private static void VerifyFieldByNumberSubstitution()
{
if (FieldByNumber != SubstitutionValue.ByNumber)
ReachableOnUnexpectedFieldByNumberValue();
}

private static void ReachableOnUnexpectedFieldByNumberValue()
{
}

[Kept]
[ExpectedInstructionSequence(new[] {
"ldc.i4 0x1",
"ret",
})]
[ExpectedLocalsSequence(new string[0])]
[MethodImpl(MethodImplOptions.NoInlining)]
private static SubstitutionValue MethodByName()
{
return SubstitutionValue.Initial;
}

[Kept]
[ExpectedInstructionSequence(new[] {
"ldc.i4 0x2",
"ret",
})]
[ExpectedLocalsSequence(new string[0])]
[MethodImpl(MethodImplOptions.NoInlining)]
private static SubstitutionValue MethodByNumber()
{
return SubstitutionValue.Initial;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<linker>
<assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<type fullname="Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions">
<field name="FieldByName" value="ByName" />
<field name="FieldByNumber" value="2" />
<method signature="Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions/SubstitutionValue MethodByName()" body="stub" value="ByName" />
<method signature="Mono.Linker.Tests.Cases.Substitutions.EnumSubstitutions/SubstitutionValue MethodByNumber()" body="stub" value="2" />
</type>
</assembly>
</linker>