dotnet / dotnet/linker

Field stripping alters layout of type with [StructLayout (LayoutKind.Sequential)]

Open
#1,555 4 comments 0 reactions 0 assignees View on GitHub
area-Linker: Steps regression
Dominant language
C#
Stars
392
Forks
128
Avg merge
2d 10h
Merged PRs (30d)
2

Description

Here is the test case

```
public class SequentialClass2
{
public static void Main ()
{
var d = new AllocatedSequentialClassWithSequentialFields ();
}
}

[Kept]
[KeptMember (".ctor()")]
[StructLayout (LayoutKind.Sequential)]
class AllocatedSequentialClassWithSequentialFields
{
[Kept]
public UnallocatedFieldOfAllocated never_used2;
}

[Kept]
[StructLayout (LayoutKind.Sequential)]
class UnallocatedFieldOfAllocated
{
public OneUIntStruct never_used_s;
}

[StructLayout(LayoutKind.Sequential)]
public struct OneUIntStruct
{
public uint field1;
}
```

If you were to add `Console.WriteLine(Marshal.SizeOf ());` into the `Main()` and run the input & output assemblies produced by running the test you can see that in the input assembly the size is `4` while in the output assembly the size is `1`.

The change that introduced this problem was https://github.com/mono/linker/commit/da2cc0fcd6c3a8e8e5d1b5d4a655f3653baa8980. There was a later change to patch up a problem https://github.com/mono/linker/commit/baeeb1f11dd66c9b97bd0a5e49a01b97e75d496b but that didn't cover this case.

Couple other thoughts.

* When a `Pack` size is defined, could that led to size changes if fields are stripped?

* It would be cool if the linker test framework could check sizes before & after. That would make writing tests and verifying the linker behavior is acceptable a lot easier. I don't know an easy way to compute the Marshal.SizeOf from the TypeDefinition which is what the test framework would need. Maybe the test framework could load the input & output assemblies into an AssemblyLoadContext and check the size that way? Another option that doesn't seem ideal, but is an option, our test framework has a `[CheckOutput]` attribute that tells the test framework to run the input & output assemblies and compare their stdout. It's slow so we only do it for a few tests, but that + Console.WriteLine the size would give marshaling size coverage.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.