The following IL:
.method assembly hidebysig static void SectionListFromPage(class MS.Internal.PtsHost.PtsContext ptsContext, native int page, valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS& pageDetails, [out] valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION[]& arraySectionDesc) cil managed
{
.custom instance void [mscorlib]System.Security.SecurityCriticalAttribute::.ctor()
.maxstack 5
.locals init (
[0] int32 num,
[1] valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION& pinned fssectiondescriptionRef,
[2] valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION[] fssectiondescriptionArray)
L_0000: ldarg.3
L_0001: ldarg.2
L_0002: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS::u
L_0007: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u::complex
L_000c: ldfld int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX::cSections
L_0011: newarr MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION
L_0016: stind.ref
L_0017: ldarg.3
L_0018: ldind.ref
L_0019: dup
L_001a: stloc.2
L_001b: brfalse.s L_0022
L_001d: ldloc.2
L_001e: ldlen
L_001f: conv.i4
L_0020: brtrue.s L_0027
L_0022: ldc.i4.0
L_0023: conv.u
L_0024: stloc.1
L_0025: br.s L_002f
L_0027: ldloc.2
L_0028: ldc.i4.0
L_0029: ldelema MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION
L_002e: stloc.1
L_002f: ldarg.0
L_0030: callvirt instance native int MS.Internal.PtsHost.PtsContext::get_Context()
L_0035: ldarg.1
L_0036: ldarg.2
L_0037: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS::u
L_003c: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u::complex
L_0041: ldfld int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX::cSections
L_0046: ldloc.1
L_0047: conv.i
L_0048: ldloca.s num
L_004a: call int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS::FsQueryPageSectionList(native int, native int, int32, valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION*, int32&)
L_004f: call void MS.Internal.PtsHost.UnsafeNativeMethods.PTS::Validate(int32)
L_0054: ldc.i4.0
L_0055: conv.u
L_0056: stloc.1
L_0057: ldarg.2
L_0058: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS::u
L_005d: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u::complex
L_0062: ldfld int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX::cSections
L_0067: ldloc.0
L_0068: ceq
L_006a: ldsfld string MS.Internal.PtsHost.ErrorHandler::PTSObjectsCountMismatch
L_006f: call void MS.Internal.PtsHost.ErrorHandler::Assert(bool, string)
L_0074: ret
}
decompiles to:
[SecurityCritical]
internal static unsafe void SectionListFromPage(PtsContext ptsContext, IntPtr page, ref PTS.FSPAGEDETAILS pageDetails, out PTS.FSSECTIONDESCRIPTION[] arraySectionDesc)
{
int num;
PTS.FSSECTIONDESCRIPTION[] fssectiondescriptionArray;
arraySectionDesc = new PTS.FSSECTIONDESCRIPTION[pageDetails.u.complex.cSections];
if (((fssectiondescriptionArray = arraySectionDesc) != null) && (fssectiondescriptionArray.Length != 0))
{
goto Label_0027;
}
fixed (PTS.FSSECTIONDESCRIPTION* fssectiondescriptionRef = null)
{
goto Label_002F;
Label_0027:
fssectiondescriptionRef = fssectiondescriptionArray;
Label_002F:
PTS.Validate(PTS.FsQueryPageSectionList(ptsContext.Context, page, pageDetails.u.complex.cSections, fssectiondescriptionRef, out num));
}
ErrorHandler.Assert(pageDetails.u.complex.cSections == num, ErrorHandler.PTSObjectsCountMismatch);
}
instead I'd expect the code to decompile without the goto statements, generated guard statement and the fixed statement having a real assignment like so:
[SecurityCritical]
internal static unsafe void SectionListFromPage(PtsContext ptsContext, IntPtr page, ref PTS.FSPAGEDETAILS pageDetails, out PTS.FSSECTIONDESCRIPTION[] arraySectionDesc)
{
int num;
PTS.FSSECTIONDESCRIPTION[] fssectiondescriptionArray = arraySectionDesc = new PTS.FSSECTIONDESCRIPTION[pageDetails.u.complex.cSections];
fixed (PTS.FSSECTIONDESCRIPTION* fssectiondescriptionRef = fssectiondescriptionArray)
{
PTS.Validate(PTS.FsQueryPageSectionList(ptsContext.Context, page, pageDetails.u.complex.cSections, fssectiondescriptionRef, out num));
}
ErrorHandler.Assert(pageDetails.u.complex.cSections == num, ErrorHandler.PTSObjectsCountMismatch);
}
.method assembly hidebysig static void SectionListFromPage(class MS.Internal.PtsHost.PtsContext ptsContext, native int page, valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS& pageDetails, [out] valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION[]& arraySectionDesc) cil managed { .custom instance void [mscorlib]System.Security.SecurityCriticalAttribute::.ctor() .maxstack 5 .locals init ( [0] int32 num, [1] valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION& pinned fssectiondescriptionRef, [2] valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION[] fssectiondescriptionArray) L_0000: ldarg.3 L_0001: ldarg.2 L_0002: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS::u L_0007: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u::complex L_000c: ldfld int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX::cSections L_0011: newarr MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION L_0016: stind.ref L_0017: ldarg.3 L_0018: ldind.ref L_0019: dup L_001a: stloc.2 L_001b: brfalse.s L_0022 L_001d: ldloc.2 L_001e: ldlen L_001f: conv.i4 L_0020: brtrue.s L_0027 L_0022: ldc.i4.0 L_0023: conv.u L_0024: stloc.1 L_0025: br.s L_002f L_0027: ldloc.2 L_0028: ldc.i4.0 L_0029: ldelema MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION L_002e: stloc.1 L_002f: ldarg.0 L_0030: callvirt instance native int MS.Internal.PtsHost.PtsContext::get_Context() L_0035: ldarg.1 L_0036: ldarg.2 L_0037: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS::u L_003c: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u::complex L_0041: ldfld int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX::cSections L_0046: ldloc.1 L_0047: conv.i L_0048: ldloca.s num L_004a: call int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS::FsQueryPageSectionList(native int, native int, int32, valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSSECTIONDESCRIPTION*, int32&) L_004f: call void MS.Internal.PtsHost.UnsafeNativeMethods.PTS::Validate(int32) L_0054: ldc.i4.0 L_0055: conv.u L_0056: stloc.1 L_0057: ldarg.2 L_0058: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS::u L_005d: ldflda valuetype MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILS/nested_u::complex L_0062: ldfld int32 MS.Internal.PtsHost.UnsafeNativeMethods.PTS/FSPAGEDETAILSCOMPLEX::cSections L_0067: ldloc.0 L_0068: ceq L_006a: ldsfld string MS.Internal.PtsHost.ErrorHandler::PTSObjectsCountMismatch L_006f: call void MS.Internal.PtsHost.ErrorHandler::Assert(bool, string) L_0074: ret }decompiles to:
[SecurityCritical] internal static unsafe void SectionListFromPage(PtsContext ptsContext, IntPtr page, ref PTS.FSPAGEDETAILS pageDetails, out PTS.FSSECTIONDESCRIPTION[] arraySectionDesc) { int num; PTS.FSSECTIONDESCRIPTION[] fssectiondescriptionArray; arraySectionDesc = new PTS.FSSECTIONDESCRIPTION[pageDetails.u.complex.cSections]; if (((fssectiondescriptionArray = arraySectionDesc) != null) && (fssectiondescriptionArray.Length != 0)) { goto Label_0027; } fixed (PTS.FSSECTIONDESCRIPTION* fssectiondescriptionRef = null) { goto Label_002F; Label_0027: fssectiondescriptionRef = fssectiondescriptionArray; Label_002F: PTS.Validate(PTS.FsQueryPageSectionList(ptsContext.Context, page, pageDetails.u.complex.cSections, fssectiondescriptionRef, out num)); } ErrorHandler.Assert(pageDetails.u.complex.cSections == num, ErrorHandler.PTSObjectsCountMismatch); }instead I'd expect the code to decompile without the goto statements, generated guard statement and the fixed statement having a real assignment like so:
[SecurityCritical] internal static unsafe void SectionListFromPage(PtsContext ptsContext, IntPtr page, ref PTS.FSPAGEDETAILS pageDetails, out PTS.FSSECTIONDESCRIPTION[] arraySectionDesc) { int num; PTS.FSSECTIONDESCRIPTION[] fssectiondescriptionArray = arraySectionDesc = new PTS.FSSECTIONDESCRIPTION[pageDetails.u.complex.cSections]; fixed (PTS.FSSECTIONDESCRIPTION* fssectiondescriptionRef = fssectiondescriptionArray) { PTS.Validate(PTS.FsQueryPageSectionList(ptsContext.Context, page, pageDetails.u.complex.cSections, fssectiondescriptionRef, out num)); } ErrorHandler.Assert(pageDetails.u.complex.cSections == num, ErrorHandler.PTSObjectsCountMismatch); }