Skip to content

Commit

Permalink
Add marking of boxed/converted custom attributes arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
marek-safar committed Sep 11, 2019
1 parent 034164c commit 0fd66c9
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 11 deletions.
35 changes: 24 additions & 11 deletions src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ protected void MarkCustomAttributeProperty (CustomAttributeNamedArgument namedAr
if (property != null)
MarkMethod (property.SetMethod);

MarkIfType (namedArgument.Argument);
MarkCustomAttributeArgument (namedArgument.Argument);
Tracer.Pop ();
}

Expand Down Expand Up @@ -711,7 +711,7 @@ protected void MarkCustomAttributeField (CustomAttributeNamedArgument namedArgum
if (field != null)
MarkField (field);

MarkIfType (namedArgument.Argument);
MarkCustomAttributeArgument (namedArgument.Argument);
}

FieldDefinition GetField (TypeDefinition type, string fieldname)
Expand Down Expand Up @@ -746,26 +746,39 @@ void MarkCustomAttributeArguments (CustomAttribute ca)
return;

foreach (var argument in ca.ConstructorArguments)
MarkIfType (argument);
MarkCustomAttributeArgument (argument);
}

void MarkIfType (CustomAttributeArgument argument)
void MarkCustomAttributeArgument (CustomAttributeArgument argument)
{
var at = argument.Type;

if (at.IsArray) {
var et = at.GetElementType ();
if (et.Namespace != "System" || et.Name != "Type")
return;

MarkType (et);
if (argument.Value == null)
return;

foreach (var cac in (CustomAttributeArgument[]) argument.Value)
MarkWithResolvedScope ((TypeReference) cac.Value);
} else if (at.Namespace == "System" && at.Name == "Type") {
MarkType (argument.Type);
MarkWithResolvedScope ((TypeReference) argument.Value);
foreach (var caa in (CustomAttributeArgument [])argument.Value)
MarkCustomAttributeArgument (caa);

return;
}

if (at.Namespace == "System") {
switch (at.Name) {
case "Type":
MarkType (argument.Type);
MarkWithResolvedScope ((TypeReference)argument.Value);
return;

case "Object":
var boxed_value = (CustomAttributeArgument)argument.Value;
MarkType (boxed_value.Type);
MarkCustomAttributeArgument (boxed_value);
return;
}
}
}

Expand Down
105 changes: 105 additions & 0 deletions test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using Mono.Linker.Tests.Cases.Expectations.Assertions;

namespace Mono.Linker.Tests.Cases.Attributes {
public class BoxedValues {
// mcs bug
// [TestAttribute ((object)typeof (Enum_2))]
// [Kept]
// [KeptAttributeAttribute (typeof (TestAttribute))]
// public void Test_1 ()
// {
// }

[TestAttribute (TestProperty = Enum_2.B)]
[Kept]
[KeptAttributeAttribute (typeof (TestAttribute))]
public void Test_2 ()
{
}

[TestAttribute (TestField = Enum_3.C)]
[Kept]
[KeptAttributeAttribute (typeof (TestAttribute))]
public void Test_3 ()
{
}

[TestAttribute (TestProperty = new object [] { Enum_4.B, null, typeof (Enum_5) })]
[Kept]
[KeptAttributeAttribute (typeof (TestAttribute))]
public void Test_4 ()
{
}

static void Main ()
{
typeof (BoxedValues).GetMethod ("Test_1").GetCustomAttributes (false);
typeof (BoxedValues).GetMethod ("Test_2").GetCustomAttributes (false);
typeof (BoxedValues).GetMethod ("Test_3").GetCustomAttributes (false);
typeof (BoxedValues).GetMethod ("Test_4").GetCustomAttributes (false);
}
}

[KeptBaseType (typeof (System.Attribute))]
public class TestAttribute : Attribute {
[Kept]
public TestAttribute ()
{
}

//[Kept]
public TestAttribute (object arg)
{
}

[KeptBackingField]
[Kept]
public object TestProperty { get; [Kept] set; }

[Kept]
public object TestField;
}

public enum Enum_1 {
A = 1,
B,
C
}

[Kept]
[KeptMember ("value__")]
[KeptBaseType (typeof (Enum))]
public enum Enum_2 {
[Kept]
A = 1,
[Kept]
B,
[Kept]
C
}

[Kept]
[KeptMember ("value__")]
[KeptBaseType (typeof (Enum))]
public enum Enum_3 {
[Kept]
C
}

[Kept]
[KeptMember ("value__")]
[KeptBaseType (typeof (Enum))]
public enum Enum_4 {
[Kept]
B
}

[Kept]
[KeptMember ("value__")]
[KeptBaseType (typeof (Enum))]
public enum Enum_5 {
[Kept]
B
}
}

0 comments on commit 0fd66c9

Please sign in to comment.