[thread-safety] model DI via Provider.get as acquiring ownership

Reviewed By: jeremydubreil

Differential Revision: D4537327

fbshipit-source-id: 02cb3a6
master
Sam Blackshear 8 years ago committed by Facebook Github Bot
parent 5cdee51ed5
commit e15121c928

@ -221,10 +221,25 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
is_annotated_functional pn || is_modeled_functional pn in
proc_is_functional pname || PatternMatch.override_exists proc_is_functional tenv pname
let exec_instr (astate : Domain.astate) { ProcData.pdesc; tenv; extras; } _ =
let acquires_ownership pname tenv =
let is_allocation pn =
Procname.equal pn BuiltinDecl.__new ||
Procname.equal pn BuiltinDecl.__new_array in
Procname.equal pn BuiltinDecl.__new || Procname.equal pn BuiltinDecl.__new_array in
(* in dependency injection, the allocation happens behind the scenes. so we model it. *)
let is_dependency_injection_provider = function
| Procname.Java java_pname ->
begin
match Procname.java_get_class_name java_pname,
Procname.java_get_method java_pname with
| "javax.inject.Provider", "get" -> true
| _ -> false
end
| _ ->
false in
is_allocation pname ||
is_dependency_injection_provider pname ||
PatternMatch.override_exists is_dependency_injection_provider tenv pname
let exec_instr (astate : Domain.astate) { ProcData.pdesc; tenv; extras; } _ =
let is_container_write pn tenv = match pn with
| Procname.Java java_pname ->
let typename = Typename.Java.from_string (Procname.java_get_class_name java_pname) in
@ -299,7 +314,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let open Domain in
function
| Sil.Call (Some (lhs_id, lhs_typ), Const (Cfun pn), _, _, _) when is_allocation pn ->
| Sil.Call (Some (lhs_id, lhs_typ), Const (Cfun pn), _, _, _) when acquires_ownership pn tenv ->
begin
match AccessPath.of_lhs_exp (Exp.Var lhs_id) lhs_typ ~f_resolve_id with
| Some lhs_access_path ->

@ -10,12 +10,20 @@
package codetoanalyze.java.checkers;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import javax.inject.Provider;
class Obj {
Object f;
Obj g;
}
interface CustomProvider<T> extends Provider<T> {
@Override
public T get();
}
@ThreadSafe
public class Ownership {
@ -25,6 +33,18 @@ public class Ownership {
field = o;
}
// understand that ownership can be acquired via DI
@Inject Ownership(Provider<Obj> objProvider) {
Obj owned = objProvider.get();
owned.f = new Object(); // should not report
}
@Inject Ownership(CustomProvider<Obj> objProvider) {
Obj owned = objProvider.get();
owned.f = new Object(); // should not report
}
native void leakToAnotherThread(Object o);
public void escapeViaConstructorBad() {

Loading…
Cancel
Save