CLASSPH(invo:I,heap:H) MEMBERPH(invo:I,type:T,heap:H) MEMBERPHARRAY(invo:I,array:H) NEWINSTANCECAST(invo:I,cast Type:T) GETCAST(invo:I,castType:T) HIERARCHYTYPE(castType:T,type:T) ARRAYPOINTSTo(arr:H,heap:H) Fig.7.Input and output relations for handling target inference We leverage the type cast information in target inference.The NEwINSTANCE- CAsr and GErCAsT relations correlate each downcast with their post-dominated invocation sites newInstance()and get(),respectively.HIERARCHYTYPE(type, castType)records all the types such that either AssIGNABLE(cast Type,type)or ASSIGNABLE(type,castType)holds.Finally,the output relation ARRAYPOINTSTo records the heap objects stored in an array heap object arr. Below we describe the target inference rules for the four scenarios above. Note that once a missing target name or a target class or both are inferred, some target propagation rules that could not be applied earlier may be fired. Scenario I1:Class clzl Class.forName(?);Aa =(A)clz2.newInstance(). If the string argument strHeap marked by?'in Class.forName(?)is not con- stant (i.e.,if STRINGToCLAss does not hold),then clzl points to a placeholder object phHeap,indicating a Class object of an unknown type.Such pointer in- formation is computed together with the pointer analysis used.If clz2 points to a placeholder object,then a can be inferred to have a type type that is assignable to the post-dominating cast cast Type,i.e.,A.As type may not be initialized else- where,a call to its"<clinit>()"is conservatively assumed.After this,the second rule in Scenario P2 can be applied to the clz2.newInstance()call. Scenario I1:Class clzI Class.forName(?);Aa =(A)clz2.newInstance(); VARPOINTSTo(clz1,phHeap) FoRNAME(invo),ACTUALARG(invo,1,arg),VARPOINTSTo(arg,strHeap), -STRINCToCLASS(strHeap,_),CLASSPH(invo,phHeap).ACTUALRETURN(invo,clz1). CALLGRAPH(invo,clinit),VARPOINTSTo(cl22,clzHeap) NEWINSTANCE(invo,clz2),VARPOINTSTo(clz2,phHeap),CLASSPH(,phHeap) NEWINSTANCECAST(invo,cast Type),ASSIGNABLE(cast Type,type), TYPE-CLASSHEAP(type,clzHeap),MTDSTRING(clinit,type.toString()+".<clinit>()"). Unlike |8],ELF does not use the cast (A)to further constrain the Class ob- jects that are created for clal and later passed to clz2,because the cast operation may not necessarily post-dominate the corresponding forName()call. Scenario I2:Field[]fsl=clz.getDeclaredFields();f2=fs2 i];a=(A)fl.get(obj). Let us first consider a real case in Figure 8.In line 1683,factoryField is ob- tained as a Field object from an array of Field objects created in line 1653 for all the fields in URLConnection.In line 1687,the object returned from get()is cast to java.net.ContentHandlerFactory.By using the cast information,we know that the call to get()may only access the static fields of URLConnection with the type java.net.ContentHandlerFactory,its supertypes or its sub- types.Otherwise,all the static fields in URLConnection must be assumed.The reason why both the supertypes and subtypes must be considered was explained in Section 3.2.These type relations are captured by HIERARCHYTYPE.ClassPh(invo:I, heap:H ) MemberPh(invo:I, type:T, heap:H ) MemberPhArray(invo:I, array:H ) NewInstanceCast(invo:I, castType:T) GetCast(invo:I, castType:T) HierarchyType(castType:T, type:T) ArrayPointsTo(arr:H, heap:H ) Fig. 7. Input and output relations for handling target inference. We leverage the type cast information in target inference. The NewInstanceCast and GetCast relations correlate each downcast with their post-dominated invocation sites newInstance() and get(), respectively. HierarchyType(type, castType) records all the types such that either Assignable(castType, type) or Assignable(type, castType) holds. Finally, the output relation ArrayPointsTo records the heap objects stored in an array heap object arr. Below we describe the target inference rules for the four scenarios above. Note that once a missing target name or a target class or both are inferred, some target propagation rules that could not be applied earlier may be fired. Scenario I1: Class clz1 = Class.forName(?); A a = (A) clz2.newInstance(). If the string argument strHeap marked by ‘?’ in Class.forName(?) is not constant (i.e., if StringToClass does not hold), then clz1 points to a placeholder object phHeap, indicating a Class object of an unknown type. Such pointer information is computed together with the pointer analysis used. If clz2 points to a placeholder object, then a can be inferred to have a type type that is assignable to the post-dominating cast castType, i.e., A. As type may not be initialized elsewhere, a call to its “<clinit>()” is conservatively assumed. After this, the second rule in Scenario P2 can be applied to the clz2.newInstance() call. Scenario I1: Class clz1 = Class.forName(?); A a = (A) clz2.newInstance(); VarPointsTo(clz1, phHeap) ← ForName(invo), ActualArg(invo, 1, arg), VarPointsTo(arg, strHeap), ¬StringToClass(strHeap, _), ClassPh(invo, phHeap), ActualReturn(invo, clz1). CallGraph(invo, clinit), VarPointsTo(clz2, clzHeap) ← NewInstance(invo, clz2), VarPointsTo(clz2, phHeap), ClassPh(_, phHeap), NewInstanceCast(invo, castType), Assignable(castType, type), Type-ClassHeap(type, clzHeap), MtdString(clinit, type.toString()+“.<clinit>()”). Unlike [8], Elf does not use the cast (A) to further constrain the Class objects that are created for clz1 and later passed to clz2, because the cast operation may not necessarily post-dominate the corresponding forName() call. Scenario I2: Field[] fs1=clz.getDeclaredFields(); f2=fs2[i]; a=(A) f1.get(obj). Let us first consider a real case in Figure 8. In line 1683, factoryField is obtained as a Field object from an array of Field objects created in line 1653 for all the fields in URLConnection. In line 1687, the object returned from get() is cast to java.net.ContentHandlerFactory. By using the cast information, we know that the call to get() may only access the static fields of URLConnection with the type java.net.ContentHandlerFactory, its supertypes or its subtypes. Otherwise, all the static fields in URLConnection must be assumed. The reason why both the supertypes and subtypes must be considered was explained in Section 3.2. These type relations are captured by HierarchyType