[inferbo] Find method of interface or abstract class

Summary: The heuristics is to find a method in non-abstract sub-classes. See D20647101.

Reviewed By: jvillard

Differential Revision: D20491461

fbshipit-source-id: 759713ef4
master
Sungkeun Cho 5 years ago committed by Facebook GitHub Bot
parent f0f91b21c6
commit 2eae5ff88c

@ -398,11 +398,14 @@ module TransferFunctions = struct
let {BoUtils.ReplaceCallee.pname= callee_pname; params; is_params_ref} = let {BoUtils.ReplaceCallee.pname= callee_pname; params; is_params_ref} =
BoUtils.ReplaceCallee.replace_make_shared tenv get_formals callee_pname params BoUtils.ReplaceCallee.replace_make_shared tenv get_formals callee_pname params
in in
match (get_summary callee_pname, get_formals callee_pname) with match
| Some callee_exit_mem, Some callee_formals -> (callee_pname, Tenv.get_summary_formals tenv ~get_summary ~get_formals callee_pname)
with
| callee_pname, `Found (callee_exit_mem, callee_formals)
| _, `FoundFromSubclass (callee_pname, callee_exit_mem, callee_formals) ->
instantiate_mem ~is_params_ref integer_type_widths ret callee_formals callee_pname instantiate_mem ~is_params_ref integer_type_widths ret callee_formals callee_pname
params mem callee_exit_mem location params mem callee_exit_mem location
| _, _ -> | _, `NotFound ->
(* This may happen for procedures with a biabduction model too. *) (* This may happen for procedures with a biabduction model too. *)
L.d_printfln_escaped "/!\\ Unknown call to %a" Procname.pp callee_pname ; L.d_printfln_escaped "/!\\ Unknown call to %a" Procname.pp callee_pname ;
Dom.Mem.add_unknown_from ret ~callee_pname ~location mem ) ) Dom.Mem.add_unknown_from ret ~callee_pname ~location mem ) )

@ -0,0 +1,56 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class InheritanceTest {
interface MyInterface {
public int foo();
}
class UniqueImpl implements MyInterface {
public int foo() {
return 5;
}
}
public void call_interface_method_Good(MyInterface x) {
int a[] = new int[10];
a[x.foo()] = 0;
}
public void call_interface_method_Bad(MyInterface x) {
int a[] = new int[5];
a[x.foo()] = 0;
}
interface MyInterface2 {
public int foo();
}
abstract class AbsImpl implements MyInterface2 {
public abstract int foo();
}
class Impl1 extends AbsImpl {
@Override
public int foo() {
return 10;
}
}
class Impl2 extends AbsImpl {
@Override
public int foo() {
return 5;
}
}
/* By heuristics, [Impl1.foo] is selected. It is hard to say good or bad. */
public void call_interface_method2(MyInterface2 x) {
int a[] = new int[10];
a[x.foo()] = 0;
}
}

@ -28,6 +28,8 @@ codetoanalyze/java/bufferoverrun/ArrayListTest.java, ArrayListTest.remove_in_loo
codetoanalyze/java/bufferoverrun/ArrayMember.java, codetoanalyze.java.bufferoverrun.ArrayMember.load_array_member_Bad():void, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Parameter `this.buf[*]`,Assignment,<Length trace>,Array declaration,Array access: Offset: [max(10, this.buf[*].lb), min(10, this.buf[*].ub)] Size: 10] codetoanalyze/java/bufferoverrun/ArrayMember.java, codetoanalyze.java.bufferoverrun.ArrayMember.load_array_member_Bad():void, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Parameter `this.buf[*]`,Assignment,<Length trace>,Array declaration,Array access: Offset: [max(10, this.buf[*].lb), min(10, this.buf[*].ub)] Size: 10]
codetoanalyze/java/bufferoverrun/CompressedData.java, codetoanalyze.java.bufferoverrun.CompressedData.decompressData(codetoanalyze.java.bufferoverrun.CompressedData$D):int, 9, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Parameter `this.yy`,<RHS trace>,Parameter `d.cci[*].s`,Assignment,Binary operation: ([0, this.yy - 1] × d.cci[*].s):signed32] codetoanalyze/java/bufferoverrun/CompressedData.java, codetoanalyze.java.bufferoverrun.CompressedData.decompressData(codetoanalyze.java.bufferoverrun.CompressedData$D):int, 9, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Parameter `this.yy`,<RHS trace>,Parameter `d.cci[*].s`,Assignment,Binary operation: ([0, this.yy - 1] × d.cci[*].s):signed32]
codetoanalyze/java/bufferoverrun/External.java, External.external_function_Bad(external.library.SomeExternalClass):void, 1, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Assignment,Binary operation: ([-oo, +oo] + [-oo, +oo]):signed32] codetoanalyze/java/bufferoverrun/External.java, External.external_function_Bad(external.library.SomeExternalClass):void, 1, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Assignment,Binary operation: ([-oo, +oo] + [-oo, +oo]):signed32]
codetoanalyze/java/bufferoverrun/InheritanceTest.java, InheritanceTest.call_interface_method2(InheritanceTest$MyInterface2):void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Call,Assignment,Assignment,<Length trace>,Array declaration,Array access: Offset: 10 Size: 10]
codetoanalyze/java/bufferoverrun/InheritanceTest.java, InheritanceTest.call_interface_method_Bad(InheritanceTest$MyInterface):void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Call,Assignment,Assignment,<Length trace>,Array declaration,Array access: Offset: 5 Size: 5]
codetoanalyze/java/bufferoverrun/StringTest.java, StringTest.constant_Bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 5 Size: 5] codetoanalyze/java/bufferoverrun/StringTest.java, StringTest.constant_Bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 5 Size: 5]
codetoanalyze/java/bufferoverrun/StringTest.java, StringTest.constant_explicit_constructor_Bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 5 Size: 5] codetoanalyze/java/bufferoverrun/StringTest.java, StringTest.constant_explicit_constructor_Bad():void, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 5 Size: 5]
codetoanalyze/java/bufferoverrun/StringTest.java, StringTest.copy_constructor_Bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 5 Size: 5] codetoanalyze/java/bufferoverrun/StringTest.java, StringTest.copy_constructor_Bad():void, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 5 Size: 5]

Loading…
Cancel
Save