diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index 4d45c2737c18..e0fdfb266075 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -679,7 +679,7 @@ protected void MarkCustomAttributeProperty (CustomAttributeNamedArgument namedAr if (property != null) MarkMethod (property.SetMethod); - MarkIfType (namedArgument.Argument); + MarkCustomAttributeArgument (namedArgument.Argument); Tracer.Pop (); } @@ -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) @@ -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; + } } } diff --git a/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs b/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs new file mode 100644 index 000000000000..0d4448ccba2c --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs @@ -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 + } +} \ No newline at end of file