From 761902afad08f8cfc330991746cfc09de072b10b Mon Sep 17 00:00:00 2001 From: jrm Date: Fri, 26 Feb 2016 15:29:56 -0800 Subject: [PATCH] for the @PerformanceCritical checker, skip allocations reports on subtypes of java.lang.Throwable instead of only java.lang.Exceptions Summary:public Skip allocations reports on subtypes of java.lang.Throwable instead of only java.lang.Exceptions Reviewed By: cristianoc Differential Revision: D2983690 fb-gh-sync-id: b135a15 shipit-source-id: b135a15 --- infer/src/checkers/performanceCritical.ml | 10 ++++++---- infer/src/harness/androidFramework.ml | 19 +++++++++++-------- infer/src/harness/androidFramework.mli | 8 ++++++-- .../java/checkers/NoAllocationExample.java | 5 +++++ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/infer/src/checkers/performanceCritical.ml b/infer/src/checkers/performanceCritical.ml index f66df05db..7ce9ad6ac 100644 --- a/infer/src/checkers/performanceCritical.ml +++ b/infer/src/checkers/performanceCritical.ml @@ -126,22 +126,24 @@ let method_calls_expensive tenv pname = let is_allocator tenv pname = - let is_exception () = + let is_throwable () = let class_name = Typename.Java.from_string (Procname.java_get_class pname) in - AndroidFramework.is_exception tenv class_name in + AndroidFramework.is_throwable tenv class_name in Procname.is_constructor pname && not (SymExec.function_is_builtin pname) - && not (is_exception ()) + && not (is_throwable ()) let method_allocates tenv pname = + let annotated_ignore_allocation = + check_method Annotations.ia_is_ignore_allocations pname in let allocates () = match lookup_call_summary pname with | Some { Specs.allocations } -> allocations <> [] | None -> false in - not (check_method Annotations.ia_is_ignore_allocations pname) + not annotated_ignore_allocation && (is_allocator tenv pname || allocates ()) diff --git a/infer/src/harness/androidFramework.ml b/infer/src/harness/androidFramework.ml index 7b5006dae..a598e1d3f 100644 --- a/infer/src/harness/androidFramework.ml +++ b/infer/src/harness/androidFramework.ml @@ -373,9 +373,11 @@ let get_lifecycle_for_framework_typ_opt lifecycle_typ lifecycle_proc_strs tenv = let get_lifecycles = android_lifecycles -let is_subclass tenv cn1 cn2 = +let is_subclass tenv cn1 classname_str = + let typename = + Typename.Java.from_string classname_str in let lookup = Sil.tenv_lookup tenv in - match lookup cn1, lookup cn2 with + match lookup cn1, lookup typename with | Some typ1, Some typ2 -> is_subtype typ1 typ2 tenv | _ -> false @@ -383,16 +385,17 @@ let is_subclass tenv cn1 cn2 = (** Checks if the exception is an uncheched exception *) let is_runtime_exception tenv typename = - let runtime_exception_typename = - Typename.Java.from_string "java.lang.RuntimeException" in - is_subclass tenv typename runtime_exception_typename + is_subclass tenv typename "java.lang.RuntimeException" (** Checks if the class name is a Java exception *) let is_exception tenv typename = - let exception_typename = - Typename.Java.from_string "java.lang.Exception" in - is_subclass tenv typename exception_typename + is_subclass tenv typename "java.lang.Exception" + + +(** Checks if the class name is a Java exception *) +let is_throwable tenv typename = + is_subclass tenv typename "java.lang.Throwable" let non_stub_android_jar () = diff --git a/infer/src/harness/androidFramework.mli b/infer/src/harness/androidFramework.mli index 827764d13..8bf78cce0 100644 --- a/infer/src/harness/androidFramework.mli +++ b/infer/src/harness/androidFramework.mli @@ -52,8 +52,12 @@ val is_android_lib_class : Typename.t -> bool (** Path to the android.jar file containing real code, not just the method stubs as in the SDK *) val non_stub_android_jar : unit -> string -(** [is_exception tenv class_name] checks if class_name is a Java exception *) +(** [is_exception tenv class_name] checks if class_name is of type java.lang.Exception *) val is_exception : Sil.tenv -> Typename.t -> bool -(** [is_runtime_exception tenv exn] checks if exn is an unchecked exception *) +(** [is_throwable tenv class_name] checks if class_name is of type java.lang.Throwable *) +val is_throwable : Sil.tenv -> Typename.t -> bool + +(** [is_runtime_exception tenv class_name] checks if classname is + of type java.lang.RuntimeException *) val is_runtime_exception : Sil.tenv -> Typename.t -> bool diff --git a/infer/tests/codetoanalyze/java/checkers/NoAllocationExample.java b/infer/tests/codetoanalyze/java/checkers/NoAllocationExample.java index 967b132bf..b178a1d01 100644 --- a/infer/tests/codetoanalyze/java/checkers/NoAllocationExample.java +++ b/infer/tests/codetoanalyze/java/checkers/NoAllocationExample.java @@ -51,6 +51,11 @@ public class NoAllocationExample { throwsException(); } + @NoAllocation + void thowingAThrowableIsFine() { + throw new AssertionError(); + } + @IgnoreAllocations void acceptableAllocation() { new Object();