@@ -279,14 +279,8 @@ static bool TryRewriteTryFinally(TryCatch tryCatch, TryCatchHandler handler, Blo
279279 return false ;
280280
281281 // Pre-try: somewhere among the instructions preceding the TryCatch we expect
282- // an `stloc obj(ldnull)`. Other (unrelated) stores may be interleaved. After
283- // SplitVariables, when the try body always throws the pre-init's local is a separate
284- // ILVariable from the in-handler store, so match by slot/kind/type rather than identity.
285- var flagInitStore = FindFlagInitStore ( parentBlock , tryCatch ,
286- s => s . Variable . Index == objectVariable . Index
287- && s . Variable . Kind == objectVariable . Kind
288- && s . Variable . Type . IsKnownType ( KnownTypeCode . Object )
289- && s . Value . MatchLdNull ( ) ) ;
282+ // an `stloc obj(ldnull)`. Other (unrelated) stores may be interleaved.
283+ var flagInitStore = FindFlagInitStore ( parentBlock , tryCatch , objectVariable , v => v . MatchLdNull ( ) ) ;
290284 if ( flagInitStore == null )
291285 return false ;
292286
@@ -383,18 +377,26 @@ static bool TryRewriteTryFinally(TryCatch tryCatch, TryCatchHandler handler, Blo
383377 return true ;
384378 }
385379
386- // Scan instructions before `tryCatch` for the runtime-async flag-init store that matches
387- // `predicate`. The lowering inserts an `stloc obj(ldnull)` (try-finally) or
388- // `stloc num(ldc.i4 0)` (try-catch) before the try region; the catch handler overwrites it,
389- // the continuation reads it to decide whether an exception occurred (and which case).
390- // Returns null when no matching store is found.
391- static StLoc FindFlagInitStore ( Block parentBlock , TryCatch tryCatch , Predicate < StLoc > predicate )
380+ // Scan instructions before `tryCatch` for the runtime-async flag-init store. The lowering
381+ // inserts an `stloc obj(ldnull)` (try-finally) or `stloc num(ldc.i4 0)` (try-catch) before
382+ // the try region; the catch handler overwrites it, and the continuation reads it to decide
383+ // whether an exception occurred (and which case). Match by `referenceVar`'s slot/kind/type
384+ // rather than identity — after SplitVariables, the pre-init's ILVariable may differ from
385+ // the in-handler one. Returns null when no matching store is found.
386+ static StLoc FindFlagInitStore ( Block parentBlock , TryCatch tryCatch , ILVariable referenceVar , Predicate < ILInstruction > matchInitValue )
392387 {
393388 int tryIndex = tryCatch . ChildIndex ;
394389 for ( int i = 0 ; i < tryIndex ; i ++ )
395390 {
396- if ( parentBlock . Instructions [ i ] is StLoc s && predicate ( s ) )
397- return s ;
391+ if ( parentBlock . Instructions [ i ] is not StLoc s )
392+ continue ;
393+ if ( s . Variable . Index != referenceVar . Index || s . Variable . Kind != referenceVar . Kind )
394+ continue ;
395+ if ( ! s . Variable . Type . Equals ( referenceVar . Type ) )
396+ continue ;
397+ if ( ! matchInitValue ( s . Value ) )
398+ continue ;
399+ return s ;
398400 }
399401 return null ;
400402 }
@@ -640,15 +642,8 @@ static bool TryRewriteTryCatch(TryCatch tryCatch, TryCatchHandler handler, Block
640642 if ( prefixCount != 0 )
641643 return false ;
642644
643- // Pre-try: somewhere before the TryCatch we expect `stloc num(ldc.i4 0)`. After
644- // SplitVariables the pre-init's local may be a separate ILVariable, so match the slot
645- // and type rather than the ILVariable identity (same workaround as the multi-handler
646- // matcher).
647- var flagInitStore = FindFlagInitStore ( parentBlock , tryCatch ,
648- s => s . Variable . Index == numVariable . Index
649- && s . Variable . Kind == numVariable . Kind
650- && s . Variable . Type . IsKnownType ( KnownTypeCode . Int32 )
651- && s . Value . MatchLdcI4 ( 0 ) ) ;
645+ // Pre-try: somewhere before the TryCatch we expect `stloc num(ldc.i4 0)`.
646+ var flagInitStore = FindFlagInitStore ( parentBlock , tryCatch , numVariable , v => v . MatchLdcI4 ( 0 ) ) ;
652647 if ( flagInitStore == null )
653648 return false ;
654649
@@ -789,14 +784,8 @@ static bool TryRewriteMultiHandlerTryCatch(TryCatch tryCatch, Block parentBlock,
789784 handlerInfos . Add ( ( handler , k , bodyObj , bodyTmp ) ) ;
790785 }
791786
792- // Pre-try: stloc num(ldc.i4 0). After SplitVariables the pre-init's local may be a
793- // separate ILVariable (the in-handler stores form a disjoint use that gets split off),
794- // so match the slot and type rather than the ILVariable identity.
795- var flagInitStore = FindFlagInitStore ( parentBlock , tryCatch ,
796- s => s . Variable . Index == numVariable . Index
797- && s . Variable . Kind == numVariable . Kind
798- && s . Variable . Type . IsKnownType ( KnownTypeCode . Int32 )
799- && s . Value . MatchLdcI4 ( 0 ) ) ;
787+ // Pre-try: stloc num(ldc.i4 0).
788+ var flagInitStore = FindFlagInitStore ( parentBlock , tryCatch , numVariable , v => v . MatchLdcI4 ( 0 ) ) ;
800789 if ( flagInitStore == null )
801790 return false ;
802791 // Block continuation { switch (ldloc num) { case K: br case_K ... ; default: leave outer } }
0 commit comments