From bafd1cf412de089dba17c25f7db4af931a2ce714 Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Thu, 13 Jul 2017 17:04:11 -0700 Subject: [PATCH] [infer][java] Infer should not suggest @Nullable on captured parameters Summary: This just makes the warnings silent for now. We may improve the analysis to check if the null check on the captured fields are consistent with the annotation on the corresponding parameters. Eradicate also has the same issue. I added a test to outline this. The biabduction analysis will also probably fail on the same of annotation lookup. We may want implement the proper fix at the level of `Annotation.field_has_annot`. Reviewed By: sblackshear Differential Revision: D5419243 fbshipit-source-id: 6460de8 --- infer/src/IR/Typ.ml | 23 ++++++++++++------- infer/src/IR/Typ.mli | 3 +++ infer/src/checkers/NullabilitySuggest.ml | 3 +++ .../java/checkers/NullableSuggest.java | 21 +++++++++++++++++ .../java/eradicate/FieldNotNullable.java | 8 +++++++ 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/infer/src/IR/Typ.ml b/infer/src/IR/Typ.ml index 46cbca570..ca044f7b1 100644 --- a/infer/src/IR/Typ.ml +++ b/infer/src/IR/Typ.ml @@ -1092,14 +1092,6 @@ module Fieldname = struct module Set = Caml.Set.Make (T) module Map = Caml.Map.Make (T) - module Clang = struct - let from_class_name class_name field_name = Clang {class_name; field_name} - end - - module Java = struct - let from_string n = Java n - end - (** Convert a fieldname to a string. *) let to_string = function | Hidden @@ -1181,6 +1173,21 @@ module Fieldname = struct (** hidded fieldname constant *) let is_hidden fn = equal fn hidden + + module Clang = struct + let from_class_name class_name field_name = Clang {class_name; field_name} + end + + module Java = struct + let from_string n = Java n + + let is_captured_parameter field_name = + match field_name with + | Java _ + -> String.is_prefix ~prefix:"val$" (to_flat_string field_name) + | Hidden | Clang _ + -> false + end end module Struct = struct diff --git a/infer/src/IR/Typ.mli b/infer/src/IR/Typ.mli index 66c8f47a4..b2d05c537 100644 --- a/infer/src/IR/Typ.mli +++ b/infer/src/IR/Typ.mli @@ -509,6 +509,9 @@ module Fieldname : sig module Java : sig val from_string : string -> t (** Create a java field name from string *) + + val is_captured_parameter : t -> bool + (** Check if field is a captured parameter *) end val to_string : t -> string diff --git a/infer/src/checkers/NullabilitySuggest.ml b/infer/src/checkers/NullabilitySuggest.ml index f9d7d8b30..68bd05c1d 100644 --- a/infer/src/checkers/NullabilitySuggest.ml +++ b/infer/src/checkers/NullabilitySuggest.ml @@ -148,6 +148,9 @@ let checker {Callbacks.summary; proc_desc; tenv} = let report_access_path ap udchain = let issue_kind = Localise.to_issue_id Localise.field_should_be_nullable in match AccessPath.Raw.get_field_and_annotation ap proc_data.tenv with + | Some (field_name, _) when Typ.Fieldname.Java.is_captured_parameter field_name + -> (* Skip reporting when field comes from generated code *) + () | Some (field_name, _) -> ( let message = diff --git a/infer/tests/codetoanalyze/java/checkers/NullableSuggest.java b/infer/tests/codetoanalyze/java/checkers/NullableSuggest.java index 3aa117eec..74bc7b21d 100644 --- a/infer/tests/codetoanalyze/java/checkers/NullableSuggest.java +++ b/infer/tests/codetoanalyze/java/checkers/NullableSuggest.java @@ -105,4 +105,25 @@ public class NullableSuggest { // Pretend that we did something here... } } + + void methodWithCapturedNullableParameterOk(@Nullable Object parameter) { + Object object = new Object() { + void foo() { + if (parameter != null) { + parameter.toString(); + } + } + }; + } + + void methodWithCapturednonNullableParameterBad_FN(Object parameter) { + Object object = new Object() { + void foo() { + if (parameter != null) { + parameter.toString(); + } + } + }; + } + } diff --git a/infer/tests/codetoanalyze/java/eradicate/FieldNotNullable.java b/infer/tests/codetoanalyze/java/eradicate/FieldNotNullable.java index 08b6d8f1c..68135d2c3 100644 --- a/infer/tests/codetoanalyze/java/eradicate/FieldNotNullable.java +++ b/infer/tests/codetoanalyze/java/eradicate/FieldNotNullable.java @@ -350,4 +350,12 @@ class NestedFieldAccess { } } + void methodWithNullableCapturedParameterBad_FN(@Nullable Object parameter) { + Object object = new Object() { + void foo() { + parameter.toString(); + } + }; + } + }