@@ -45,6 +45,22 @@ private static bool IsCompilerGenerated(FieldDefinition fieldDefinition)
4545 return fieldDefinition . DeclaringType . CustomAttributes . Any ( ca => ca . AttributeType . FullName == typeof ( CompilerGeneratedAttribute ) . FullName ) ;
4646 }
4747
48+ private static bool IsCompilerGeneratedField ( Instruction instruction , out FieldDefinition field )
49+ {
50+ switch ( instruction . Operand )
51+ {
52+ case FieldDefinition fieldDefinition when IsCompilerGenerated ( fieldDefinition ) :
53+ field = fieldDefinition ;
54+ return true ;
55+ case FieldReference fieldReference when IsCompilerGenerated ( fieldReference . Resolve ( ) ) :
56+ field = fieldReference . Resolve ( ) ;
57+ return true ;
58+ default :
59+ field = null ;
60+ return false ;
61+ }
62+ }
63+
4864 private static bool IsMoveNextInsideAsyncStateMachine ( MethodDefinition methodDefinition )
4965 {
5066 if ( methodDefinition . FullName . EndsWith ( "::MoveNext()" ) && IsCompilerGenerated ( methodDefinition ) )
@@ -537,11 +553,9 @@ static bool CheckForAsyncEnumerator(List<Instruction> instructions, Instruction
537553 ( instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg ||
538554 instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg_0 ) &&
539555 instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
540- (
541- ( instructions [ currentIndex - 1 ] . Operand is FieldDefinition field && IsCompilerGenerated ( field ) && field . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" ) ) ||
542- ( instructions [ currentIndex - 1 ] . Operand is FieldReference fieldRef && IsCompilerGenerated ( fieldRef . Resolve ( ) ) && fieldRef . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" ) )
543- )
544- )
556+ IsCompilerGeneratedField ( instructions [ currentIndex - 1 ] , out FieldDefinition field ) &&
557+ field . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" )
558+ )
545559 {
546560 return true ;
547561 }
@@ -582,10 +596,8 @@ static bool CheckIfExceptionThrown(List<Instruction> instructions, Instruction i
582596 for ( int i = currentIndex - 1 ; i >= minFieldIndex ; -- i )
583597 {
584598 if ( instructions [ i ] . OpCode == OpCodes . Ldfld &&
585- (
586- ( instructions [ i ] . Operand is FieldDefinition field && IsCompilerGenerated ( field ) && field . FieldType . FullName == "System.Object" ) ||
587- ( instructions [ i ] . Operand is FieldReference fieldRef && IsCompilerGenerated ( fieldRef . Resolve ( ) ) && fieldRef . FieldType . FullName == "System.Object" )
588- ) )
599+ IsCompilerGeneratedField ( instructions [ i ] , out FieldDefinition field ) &&
600+ field . FieldType . FullName == "System.Object" )
589601 {
590602 // We expect the call to GetResult() to be no more than four
591603 // instructions before the loading of the field's value.
@@ -708,16 +720,16 @@ static bool CheckForSkipDisposal(List<Instruction> instructions, Instruction ins
708720
709721 bool isFollowedByDisposeAsync = false ;
710722
711- if ( instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
712- instructions [ currentIndex - 1 ] . Operand is FieldDefinition field &&
713- IsCompilerGenerated ( field ) )
723+ if ( instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld )
714724 {
725+ if ( ! IsCompilerGeneratedField ( instructions [ currentIndex - 1 ] , out FieldDefinition field ) ) return false ;
726+
715727 int maxReloadFieldIndex = Math . Min ( currentIndex + 2 , instructions . Count - 2 ) ;
716728
717729 for ( int i = currentIndex + 1 ; i <= maxReloadFieldIndex ; ++ i )
718730 {
719731 if ( instructions [ i ] . OpCode == OpCodes . Ldfld &&
720- instructions [ i ] . Operand is FieldDefinition reloadedField &&
732+ IsCompilerGeneratedField ( instructions [ i ] , out FieldDefinition reloadedField ) &&
721733 field . Equals ( reloadedField ) &&
722734 instructions [ i + 1 ] . OpCode == OpCodes . Callvirt &&
723735 instructions [ i + 1 ] . Operand is MethodReference method &&
@@ -758,8 +770,8 @@ instructions[i].Operand is FieldDefinition reloadedField &&
758770 if ( ( instructions [ i ] . OpCode == OpCodes . Leave ||
759771 instructions [ i ] . OpCode == OpCodes . Leave_S ) &&
760772 instructions [ i - 1 ] . OpCode == OpCodes . Stfld &&
761- instructions [ i - 1 ] . Operand is FieldDefinition storeField &&
762- IsCompilerGenerated ( storeField ) )
773+ IsCompilerGeneratedField ( instructions [ i - 1 ] , out FieldDefinition _ )
774+ )
763775 {
764776 return true ;
765777 }
@@ -811,9 +823,7 @@ static bool CheckForCleanup(List<Instruction> instructions, Instruction instruct
811823
812824 for ( int i = currentIndex - 2 ; i >= minLoadFieldIndex ; -- i )
813825 {
814- if ( instructions [ i ] . OpCode == OpCodes . Ldfld &&
815- instructions [ i ] . Operand is FieldDefinition loadedField &&
816- IsCompilerGenerated ( loadedField ) )
826+ if ( instructions [ i ] . OpCode == OpCodes . Ldfld && IsCompilerGeneratedField ( instructions [ i ] , out FieldDefinition _ ) )
817827 {
818828 int minRethrowIndex = Math . Max ( 0 , i - 4 ) ;
819829
@@ -918,10 +928,8 @@ static bool DisposeCheck(List<Instruction> instructions, Instruction instruction
918928
919929 if ( currentIndex >= 2 &&
920930 instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
921- (
922- ( instructions [ currentIndex - 1 ] . Operand is FieldDefinition field && IsCompilerGenerated ( field ) && field . FullName . EndsWith ( "__disposeMode" ) ) ||
923- ( instructions [ currentIndex - 1 ] . Operand is FieldReference fieldRef && IsCompilerGenerated ( fieldRef . Resolve ( ) ) && fieldRef . FullName . EndsWith ( "__disposeMode" ) )
924- ) &&
931+ IsCompilerGeneratedField ( instructions [ currentIndex - 1 ] , out FieldDefinition field ) &&
932+ field . FullName . EndsWith ( "__disposeMode" ) &&
925933 ( instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg ||
926934 instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg_0 ) )
927935 {
0 commit comments