@@ -360,9 +360,17 @@ extension ValueDefUseWalker {
360
360
return unmatchedPath ( value: operand, path: path)
361
361
}
362
362
case is BeginBorrowInst , is CopyValueInst , is MoveValueInst ,
363
- is UpcastInst , is UncheckedRefCastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
363
+ is UpcastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
364
364
is RefToBridgeObjectInst , is BridgeObjectToRefInst , is MarkUnresolvedNonCopyableValueInst :
365
365
return walkDownUses ( ofValue: ( instruction as! SingleValueInstruction ) , path: path)
366
+ case let urc as UncheckedRefCastInst :
367
+ if urc. type. isClassExistential || urc. fromInstance. type. isClassExistential {
368
+ // Sometimes `unchecked_ref_cast` is misused to cast between AnyObject and a class (instead of
369
+ // init_existential_ref and open_existential_ref).
370
+ // We need to ignore this because otherwise the path wouldn't contain the right `existential` field kind.
371
+ return leafUse ( value: operand, path: path)
372
+ }
373
+ return walkDownUses ( ofValue: urc, path: path)
366
374
case let beginDealloc as BeginDeallocRefInst :
367
375
if operand. index == 0 {
368
376
return walkDownUses ( ofValue: beginDealloc, path: path)
@@ -680,10 +688,18 @@ extension ValueUseDefWalker {
680
688
case let oer as OpenExistentialRefInst :
681
689
return walkUp ( value: oer. existential, path: path. push ( . existential, index: 0 ) )
682
690
case is BeginBorrowInst , is CopyValueInst , is MoveValueInst ,
683
- is UpcastInst , is UncheckedRefCastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
691
+ is UpcastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
684
692
is BeginDeallocRefInst ,
685
693
is RefToBridgeObjectInst , is BridgeObjectToRefInst , is MarkUnresolvedNonCopyableValueInst :
686
694
return walkUp ( value: ( def as! Instruction ) . operands [ 0 ] . value, path: path)
695
+ case let urc as UncheckedRefCastInst :
696
+ if urc. type. isClassExistential || urc. fromInstance. type. isClassExistential {
697
+ // Sometimes `unchecked_ref_cast` is misused to cast between AnyObject and a class (instead of
698
+ // init_existential_ref and open_existential_ref).
699
+ // We need to ignore this because otherwise the path wouldn't contain the right `existential` field kind.
700
+ return rootDef ( value: urc, path: path)
701
+ }
702
+ return walkUp ( value: urc. fromInstance, path: path)
687
703
case let arg as Argument :
688
704
if let phi = Phi ( arg) {
689
705
for incoming in phi. incomingValues {
0 commit comments