Reduce TLS accesses. (#11487)
[mono-project.git] / mono / tests / sizeof-empty-structs.cs
blobff222c859965c15d6a6e8ef6a42d9fb03048bbc6
1 using System;
2 using System.Runtime.InteropServices;
3 using System.Reflection;
4 using System.Linq;
6 public struct EmptyStruct {
9 [StructLayout(LayoutKind.Sequential)]
10 public struct EmptySequentialStruct {
13 [StructLayout(LayoutKind.Explicit)]
14 public struct EmptyExplicitStruct {
17 [StructLayout(LayoutKind.Sequential, Pack = 4)]
18 public struct EmptySequentialPackStruct {
21 [StructLayout(LayoutKind.Explicit, Pack = 4)]
22 public struct EmptyExplicitPackStruct {
25 [StructLayout(LayoutKind.Explicit, Size = 0)]
26 public struct EmptyExplicitSize0Struct {
29 [StructLayout(LayoutKind.Explicit, Size = 1)]
30 public struct EmptyExplicitSize1Struct {
33 [StructLayout(LayoutKind.Sequential, Pack = 1)]
34 public struct TestOffsets {
35 public int A;
36 public EmptyStruct B;
37 public int C;
38 public EmptyExplicitSize0Struct D;
39 public int E;
40 public EmptySequentialStruct F;
41 public int G;
44 class Program {
45 private static unsafe void CheckSize<T> (int expected, ref int exitCode) {
46 var t = typeof(T);
47 var actualSize = Marshal.SizeOf(t);
49 Console.WriteLine($"Marshal.SizeOf({t.Name}) == {actualSize}, expected {expected}");
51 if (actualSize != expected)
52 exitCode += 1;
55 // https://bugzilla.xamarin.com/show_bug.cgi?id=18941
56 // Marshal.SizeOf should never report 0, even for empty structs or structs with Size=0 attribute
57 public static int Main () {
58 int exitCode = 0;
60 CheckSize<EmptyStruct>(1, ref exitCode);
61 CheckSize<EmptySequentialStruct>(1, ref exitCode);
62 CheckSize<EmptyExplicitStruct>(1, ref exitCode);
63 CheckSize<EmptySequentialPackStruct>(1, ref exitCode);
64 CheckSize<EmptyExplicitPackStruct>(1, ref exitCode);
65 CheckSize<EmptyExplicitSize0Struct>(1, ref exitCode);
66 CheckSize<EmptyExplicitSize1Struct>(1, ref exitCode);
67 CheckSize<TestOffsets>(19, ref exitCode);
69 Console.WriteLine("--");
71 var t = typeof(TestOffsets);
72 var actualOffsets = (
73 from f in t.GetFields()
74 select (name: f.Name, offset: Marshal.OffsetOf(t, f.Name).ToInt32())
75 ).ToList();
77 var expectedOffsets = new [] {
78 (name: "A", offset: 0),
79 (name: "B", offset: 4),
80 (name: "C", offset: 5),
81 (name: "D", offset: 9),
82 (name: "E", offset: 10),
83 (name: "F", offset: 14),
84 (name: "G", offset: 15)
87 if (!actualOffsets.SequenceEqual(expectedOffsets)) {
88 Console.WriteLine("Field offset mismatch:");
90 for (int i = 0; i < expectedOffsets.Length; i++) {
91 var expected = expectedOffsets[i];
92 var actual = actualOffsets[i];
93 Console.WriteLine($"OffsetOf({t.Name}.{actual.name}) == {actual.offset}, expected OffsetOf({expected.name}) == {expected.offset}.");
97 return exitCode;