diff options
-rw-r--r-- | src/linker/Linker.Steps/MarkStep.cs | 11 | ||||
-rw-r--r-- | test/Mono.Linker.Tests.Cases/Attributes.StructLayout/SequentialClass.cs | 18 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index f06e7ccff..ed7f2c121 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -1249,6 +1249,17 @@ namespace Mono.Linker.Steps MarkMarshalSpec (field, new DependencyInfo (DependencyKind.FieldMarshalSpec, field), field); DoAdditionalFieldProcessing (field); + // If we accessed a field on a type and the type has explicit/sequential layout, make sure to keep + // all the other fields. + // + // We normally do this when the type is seen as instantiated, but one can get into a situation + // where the type is not seen as instantiated and the offsets still matter (usually when type safety + // is violated with Unsafe.As). + // + // This won't do too much work because classes are rarely tagged for explicit/sequential layout. + if (!field.DeclaringType.IsValueType) + MarkImplicitlyUsedFields (field.DeclaringType); + var parent = field.DeclaringType; if (!Annotations.HasPreservedStaticCtor (parent)) { var cctorReason = reason.Kind switch diff --git a/test/Mono.Linker.Tests.Cases/Attributes.StructLayout/SequentialClass.cs b/test/Mono.Linker.Tests.Cases/Attributes.StructLayout/SequentialClass.cs index fd92a3b6b..f0a4c0072 100644 --- a/test/Mono.Linker.Tests.Cases/Attributes.StructLayout/SequentialClass.cs +++ b/test/Mono.Linker.Tests.Cases/Attributes.StructLayout/SequentialClass.cs @@ -29,11 +29,25 @@ namespace Mono.Linker.Tests.Cases.Attributes.StructLayout public int never_used; } + [Kept] + [StructLayout (LayoutKind.Sequential)] + class UnallocatedButWithSingleFieldUsedSequentialClassData + { + [Kept] + public int never_used; + + [Kept] + public int used; + } + public class SequentialClass { [Kept] static UnallocatedSequentialClassData _field; + [Kept] + static UnallocatedButWithSingleFieldUsedSequentialClassData _otherField; + public static void Main () { var c = new SequentialClassData (); @@ -44,6 +58,10 @@ namespace Mono.Linker.Tests.Cases.Attributes.StructLayout _field = null; typeof (UnallocatedButReferencedWithReflectionSequentialClassData).ToString (); + + if (string.Empty.Length > 0) { + _otherField.used = 123; + } } } } |