@@ -885,6 +885,7 @@ private BlockContainer ConvertBody(BlockContainer oldBody, StateRangeAnalysis ra
885885 else
886886 {
887887 newBlock . Instructions . Add ( new InvalidExpression ( "Assigned non-constant to iterator.state field" ) . WithILRange ( oldInst ) ) ;
888+ ReportError ( newBlock . Instructions . Last ( ) ) ;
888889 continue ; // don't copy over this instruction, but continue with the basic block
889890 }
890891 }
@@ -993,6 +994,7 @@ void ConvertBranchAfterYieldReturn(Block newBlock, Block oldBlock, int pos)
993994 else
994995 {
995996 newBlock . Instructions . Add ( new InvalidBranch ( "Unable to find new state assignment for yield return" ) ) ;
997+ ReportError ( newBlock . Instructions . Last ( ) ) ;
996998 return ;
997999 }
9981000 // Mono may have 'br setSkipFinallyBodies' here, so follow the branch
@@ -1009,6 +1011,7 @@ void ConvertBranchAfterYieldReturn(Block newBlock, Block oldBlock, int pos)
10091011 ExpectedResultType = StackType . Void ,
10101012 Message = "Unexpected assignment to skipFinallyBodies"
10111013 } ) ;
1014+ ReportError ( newBlock . Instructions . Last ( ) ) ;
10121015 }
10131016 pos ++ ;
10141017 }
@@ -1022,6 +1025,7 @@ void ConvertBranchAfterYieldReturn(Block newBlock, Block oldBlock, int pos)
10221025 ExpectedResultType = StackType . Void ,
10231026 Message = "Unexpected assignment to doFinallyBodies"
10241027 } ) ;
1028+ ReportError ( newBlock . Instructions . Last ( ) ) ;
10251029 }
10261030 pos ++ ;
10271031 }
@@ -1038,6 +1042,7 @@ void ConvertBranchAfterYieldReturn(Block newBlock, Block oldBlock, int pos)
10381042 else
10391043 {
10401044 newBlock . Instructions . Add ( new InvalidBranch ( "Unable to find 'return true' for yield return" ) ) ;
1045+ ReportError ( newBlock . Instructions . Last ( ) ) ;
10411046 return ;
10421047 }
10431048 newBlock . Instructions . Add ( MakeGoTo ( newState ) ) ;
@@ -1068,7 +1073,9 @@ ILInstruction MakeGoTo(int v)
10681073 }
10691074 else
10701075 {
1071- return new InvalidBranch ( "Could not find block for state " + v ) ;
1076+ var err = new InvalidBranch ( "Could not find block for state " + v ) ;
1077+ ReportError ( err ) ;
1078+ return err ;
10721079 }
10731080 }
10741081
@@ -1100,6 +1107,8 @@ void UpdateBranchTargets(ILInstruction inst)
11001107 }
11011108 else
11021109 {
1110+ // don't treat this as an error, it might just be unreachable code that will be removed soon
1111+ // (occurs with mcs yield return)
11031112 leave . ReplaceWith ( new InvalidBranch ( "Unexpected return in MoveNext()" ) . WithILRange ( leave ) ) ;
11041113 }
11051114 }
@@ -1117,6 +1126,21 @@ void UpdateBranchTargets(ILInstruction inst)
11171126 UpdateBranchTargets ( child ) ;
11181127 }
11191128 }
1129+
1130+ void ReportError ( ILInstruction inst )
1131+ {
1132+ // ConvertBody is still called within the try-catch, so we can throw SymbolicAnalysisFailedException
1133+ // to suppress conversion of the state machine altogether.
1134+ // We still initially create an instruction before converting a to an exception,
1135+ // so that the body of this function can be commented out for testing purposes.
1136+ // (this allows seeing where exactly the error occurs in the converted body output)
1137+ string message = "ConvertBody error" ;
1138+ if ( inst is InvalidBranch invalidBranch )
1139+ message = invalidBranch . Message ;
1140+ else if ( inst is InvalidExpression invalidExpr )
1141+ message = invalidExpr . Message ;
1142+ throw new SymbolicAnalysisFailedException ( message ) ;
1143+ }
11201144 }
11211145 #endregion
11221146
0 commit comments