Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/linker/Linker.Steps/MarkStep.cs11
-rw-r--r--test/Mono.Linker.Tests.Cases/Attributes.StructLayout/SequentialClass.cs18
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;
+ }
}
}
}