No longer report context leak on private methods

Summary: public
The context leaks were reported multiple times. If a leaks was found on method `f()` and `g()` calls `f()`, then the same leak was report both in `f()` and in `g()`.

Reviewed By: sblackshear

Differential Revision: D2598110

fb-gh-sync-id: ca90b57
master
jrm 9 years ago committed by facebook-github-bot-7
parent 513eee3059
commit 859b816e95

@ -460,6 +460,10 @@ module Node = struct
let proc_desc_get_captured proc_desc = let proc_desc_get_captured proc_desc =
proc_desc.pd_attributes.ProcAttributes.captured proc_desc.pd_attributes.ProcAttributes.captured
(** Return the visibility attribute *)
let proc_desc_get_access proc_desc =
proc_desc.pd_attributes.ProcAttributes.access
let proc_desc_get_nodes proc_desc = let proc_desc_get_nodes proc_desc =
proc_desc.pd_nodes proc_desc.pd_nodes
@ -645,6 +649,7 @@ module Procdesc = struct
let get_loc = Node.proc_desc_get_loc let get_loc = Node.proc_desc_get_loc
let get_locals = Node.proc_desc_get_locals let get_locals = Node.proc_desc_get_locals
let get_captured = Node.proc_desc_get_captured let get_captured = Node.proc_desc_get_captured
let get_access = Node.proc_desc_get_access
let get_nodes = Node.proc_desc_get_nodes let get_nodes = Node.proc_desc_get_nodes
let get_slope = Node.proc_desc_get_slope let get_slope = Node.proc_desc_get_slope
let get_sliced_slope = Node.proc_desc_get_sliced_slope let get_sliced_slope = Node.proc_desc_get_sliced_slope

@ -71,6 +71,9 @@ module Procdesc : sig
(** Return name and type of block's captured variables *) (** Return name and type of block's captured variables *)
val get_captured : t -> (Mangled.t * Sil.typ) list val get_captured : t -> (Mangled.t * Sil.typ) list
(** Return the visibility attribute *)
val get_access : t -> Sil.access
val get_nodes : t -> node list val get_nodes : t -> node list
(** Get the procedure's nodes up until the first branching *) (** Get the procedure's nodes up until the first branching *)

@ -702,7 +702,7 @@ let extract_specs tenv pdesc pathset : Prop.normal Specs.spec list =
(* let () = L.out "@.AFTER abs:@.$%a@." (Prop.pp_prop Utils.pe_text) prop'' in *) (* let () = L.out "@.AFTER abs:@.$%a@." (Prop.pp_prop Utils.pe_text) prop'' in *)
let pre, post = Prop.extract_spec prop'' in let pre, post = Prop.extract_spec prop'' in
let pre' = Prop.normalize (Prop.prop_sub sub pre) in let pre' = Prop.normalize (Prop.prop_sub sub pre) in
if !Config.curr_language = Config.Java then if !Config.curr_language = Config.Java && Cfg.Procdesc.get_access pdesc <> Sil.Private then
report_context_leaks pname (Prop.get_sigma post) tenv; report_context_leaks pname (Prop.get_sigma post) tenv;
let post' = let post' =
if Prover.check_inconsistency_base prop then None if Prover.check_inconsistency_base prop then None

@ -28,7 +28,7 @@
}, },
{ {
"type": "CONTEXT_LEAK", "type": "CONTEXT_LEAK",
"procedure": "void ContextLeaks.handlerLeak()", "procedure": "void ContextLeaks.indirectHandlerLeak()",
"file": "codetoanalyze/java/infer/ContextLeaks.java" "file": "codetoanalyze/java/infer/ContextLeaks.java"
}, },
{ {

@ -26,7 +26,7 @@
}, },
{ {
"type": "CONTEXT_LEAK", "type": "CONTEXT_LEAK",
"procedure": "void ContextLeaks.handlerLeak()", "procedure": "void ContextLeaks.indirectHandlerLeak()",
"file": "infer/tests/codetoanalyze/java/infer/ContextLeaks.java" "file": "infer/tests/codetoanalyze/java/infer/ContextLeaks.java"
}, },
{ {

@ -16,100 +16,105 @@ import android.os.Handler;
public class ContextLeaks extends Activity { public class ContextLeaks extends Activity {
static Object sFld; static Object sFld;
public void directLeak() { void directLeak() {
sFld = this; sFld = this;
} }
public void leakThenFix() { public void leakThenFix() {
sFld = this; sFld = this;
sFld = null; sFld = null;
} }
public void nonActivityNoLeak() { public void nonActivityNoLeak() {
sFld = new Object(); sFld = new Object();
} }
static class Obj { static class Obj {
public Object f; public Object f;
} }
public void indirectLeak() { public void indirectLeak() {
Obj o = new Obj(); Obj o = new Obj();
o.f = this; o.f = this;
sFld = o; sFld = o;
} }
public void indirectLeakThenFix() { public void indirectLeakThenFix() {
Obj o = new Obj(); Obj o = new Obj();
o.f = this; o.f = this;
sFld = o; sFld = o;
o.f = null; o.f = null;
} }
class NonStaticInner {} class NonStaticInner {
}
public void nonStaticInnerClassLeak() { public void nonStaticInnerClassLeak() {
sFld = new NonStaticInner(); sFld = new NonStaticInner();
} }
public void nonStaticInnerClassLeakThenFix() { public void nonStaticInnerClassLeakThenFix() {
sFld = new NonStaticInner(); sFld = new NonStaticInner();
sFld = null; sFld = null;
} }
private Object o; private Object o;
public void leakAfterInstanceFieldWrite() { public void leakAfterInstanceFieldWrite() {
this.o = new Object(); this.o = new Object();
sFld = this; sFld = this;
} }
public static class Singleton { public static class Singleton {
private static Singleton instance;
private Context context;
private Singleton(Context context) {
this.context = context;
}
public static Singleton getInstance(Context context) {
if(instance == null) {
instance = new Singleton(context);
}
return instance;
}
}
Singleton singletonLeak() {
return Singleton.getInstance(this);
}
Singleton singletonNoLeak() {
return Singleton.getInstance(this.getApplicationContext());
}
private Handler handler = new Handler(); private static Singleton instance;
private Context context;
public void handlerLeak() { private Singleton(Context context) {
Runnable r = this.context = context;
new Runnable() {
public void run() {
}
};
handler.postDelayed(r, 10000);
} }
public void handlerNoLeak() { public static Singleton getInstance(Context context) {
Runnable r = if (instance == null) {
new Runnable() { instance = new Singleton(context);
public void run() { }
} return instance;
};
handler.postDelayed(r, 10000);
handler.removeCallbacks(r);
} }
}
public Singleton singletonLeak() {
return Singleton.getInstance(this);
}
public Singleton singletonNoLeak() {
return Singleton.getInstance(this.getApplicationContext());
}
private Handler handler = new Handler();
public void indirectHandlerLeak() {
handlerLeak();
}
private void handlerLeak() {
Runnable r =
new Runnable() {
public void run() {
}
};
handler.postDelayed(r, 10000);
}
public void handlerNoLeak() {
Runnable r =
new Runnable() {
public void run() {
}
};
handler.postDelayed(r, 10000);
handler.removeCallbacks(r);
}
} }

@ -45,7 +45,7 @@ public class ContextLeaksTest {
"nonStaticInnerClassLeak", "nonStaticInnerClassLeak",
"leakAfterInstanceFieldWrite", "leakAfterInstanceFieldWrite",
"singletonLeak", "singletonLeak",
"handlerLeak" "indirectHandlerLeak"
}; };
assertThat( assertThat(
"Results should contain " + CONTEXT_LEAK, "Results should contain " + CONTEXT_LEAK,

Loading…
Cancel
Save