@@ -360,9 +360,17 @@ extension ValueDefUseWalker {
360360 return unmatchedPath ( value: operand, path: path)
361361 }
362362 case is BeginBorrowInst , is CopyValueInst , is MoveValueInst ,
363- is UpcastInst , is UncheckedRefCastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
363+ is UpcastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
364364 is RefToBridgeObjectInst , is BridgeObjectToRefInst , is MarkUnresolvedNonCopyableValueInst :
365365 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)
366374 case let beginDealloc as BeginDeallocRefInst :
367375 if operand. index == 0 {
368376 return walkDownUses ( ofValue: beginDealloc, path: path)
@@ -680,10 +688,18 @@ extension ValueUseDefWalker {
680688 case let oer as OpenExistentialRefInst :
681689 return walkUp ( value: oer. existential, path: path. push ( . existential, index: 0 ) )
682690 case is BeginBorrowInst , is CopyValueInst , is MoveValueInst ,
683- is UpcastInst , is UncheckedRefCastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
691+ is UpcastInst , is EndCOWMutationInst , is EndInitLetRefInst ,
684692 is BeginDeallocRefInst ,
685693 is RefToBridgeObjectInst , is BridgeObjectToRefInst , is MarkUnresolvedNonCopyableValueInst :
686694 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)
687703 case let arg as Argument :
688704 if let phi = Phi ( arg) {
689705 for incoming in phi. incomingValues {
0 commit comments