From 9a3ab413719bd9742938d80434385bc8cc58626d Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Tue, 5 Sep 2017 12:48:01 -0700 Subject: [PATCH] [infer][java] the translation was no adding the fields from the implemented interfaces Summary: The list of fields of a Java object in SIL is the list of fields declared in the class plus all the fields declared in the the super classes. It turns out that we were missing the fields declared in the implemented interfaces. Reviewed By: sblackshear Differential Revision: D5720386 fbshipit-source-id: d65c9de --- infer/src/java/jTransType.ml | 11 ++++++++++- infer/tests/build_systems/ant/issues.exp | 1 + .../java/infer/NullPointerExceptions.java | 12 ++++++++++++ infer/tests/codetoanalyze/java/infer/issues.exp | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/infer/src/java/jTransType.ml b/infer/src/java/jTransType.ml index 079e0445a..29f123c54 100644 --- a/infer/src/java/jTransType.ml +++ b/infer/src/java/jTransType.ml @@ -301,13 +301,22 @@ let rec get_all_fields program tenv cn = let trans_fields classname = match JClasspath.lookup_node classname program with | Some Javalib.JClass jclass - -> let super_fields = + -> let superclass_fields = match jclass.Javalib.c_super_class with | None -> ([], []) | Some super_classname -> extract_class_fields super_classname in + let super_fields = + let rev_pair (l1, l2) = (List.rev l1, List.rev l2) in + List.fold + ~f:(fun (statics, fields) interface_name -> + let interface_statics, interface_fields = extract_class_fields interface_name in + (interface_statics @ statics, interface_fields @ fields)) + ~init:(rev_pair superclass_fields) jclass.Javalib.c_interfaces + |> rev_pair + in Javalib.cf_fold (collect_class_field classname) (Javalib.JClass jclass) super_fields | Some Javalib.JInterface jinterface -> let interface_fields = diff --git a/infer/tests/build_systems/ant/issues.exp b/infer/tests/build_systems/ant/issues.exp index 26376233c..e83fbc0af 100644 --- a/infer/tests/build_systems/ant/issues.exp +++ b/infer/tests/build_systems/ant/issues.exp @@ -92,6 +92,7 @@ codetoanalyze/java/infer/NullPointerExceptions.java, int NullPointerExceptions.n codetoanalyze/java/infer/NullPointerExceptions.java, int NullPointerExceptions.nullPointerExceptionInterProc(), 2, NULL_DEREFERENCE, [start of procedure nullPointerExceptionInterProc(),start of procedure canReturnNullObject(...),start of procedure NullPointerExceptions$A(...),return from a call to NullPointerExceptions$A.(NullPointerExceptions),Taking false branch,return from a call to NullPointerExceptions$A NullPointerExceptions.canReturnNullObject(boolean)] codetoanalyze/java/infer/NullPointerExceptions.java, int NullPointerExceptions.nullPointerExceptionWithExceptionHandling(boolean), 5, NULL_DEREFERENCE, [start of procedure nullPointerExceptionWithExceptionHandling(...),exception java.lang.Exception,Switch condition is true. Entering switch case] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions$$$Class$Name$With$Dollars.npeWithDollars(), 2, NULL_DEREFERENCE, [start of procedure npeWithDollars()] +codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions$E.dereferenceNullableInterfaceFieldBad(), 1, NULL_DEREFERENCE, [start of procedure dereferenceNullableInterfaceFieldBad()] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions.badCheckShouldCauseNPE(), 1, NULL_DEREFERENCE, [start of procedure badCheckShouldCauseNPE(),start of procedure getBool(),Taking true branch,return from a call to Boolean NullPointerExceptions.getBool(),Taking true branch,start of procedure getObj(),Taking false branch,return from a call to Object NullPointerExceptions.getObj()] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions.cursorFromContentResolverNPE(String), 9, NULL_DEREFERENCE, [start of procedure cursorFromContentResolverNPE(...)] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions.derefNull(), 2, NULL_DEREFERENCE, [start of procedure derefNull(),start of procedure derefUndefinedCallee(),start of procedure retUndefined(),return from a call to Object NullPointerExceptions.retUndefined(),Skipping toString(): function or method not found,return from a call to Object NullPointerExceptions.derefUndefinedCallee()] diff --git a/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java b/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java index b06b6adbe..2fe1d1e14 100644 --- a/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java +++ b/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java @@ -617,4 +617,16 @@ public class NullPointerExceptions { return Assertions.assertNotNull(object).toString(); } + interface I { + @Nullable Object mObject = null; + } + + class E implements I { + + void dereferenceNullableInterfaceFieldBad() { + mObject.toString(); + } + + } + } diff --git a/infer/tests/codetoanalyze/java/infer/issues.exp b/infer/tests/codetoanalyze/java/infer/issues.exp index 0f79ec5c3..92d0bb8df 100644 --- a/infer/tests/codetoanalyze/java/infer/issues.exp +++ b/infer/tests/codetoanalyze/java/infer/issues.exp @@ -119,6 +119,7 @@ codetoanalyze/java/infer/NullPointerExceptions.java, int NullPointerExceptions.n codetoanalyze/java/infer/NullPointerExceptions.java, int NullPointerExceptions.nullPointerExceptionWithExceptionHandling(boolean), 5, NULL_DEREFERENCE, [start of procedure nullPointerExceptionWithExceptionHandling(...),exception java.lang.Exception,Switch condition is true. Entering switch case] codetoanalyze/java/infer/NullPointerExceptions.java, int NullPointerExceptions.preconditionCheckStateTest(NullPointerExceptions$D), 1, PRECONDITION_NOT_MET, [start of procedure preconditionCheckStateTest(...),Taking false branch] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions$$$Class$Name$With$Dollars.npeWithDollars(), 2, NULL_DEREFERENCE, [start of procedure npeWithDollars()] +codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions$E.dereferenceNullableInterfaceFieldBad(), 1, NULL_DEREFERENCE, [start of procedure dereferenceNullableInterfaceFieldBad()] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions.badCheckShouldCauseNPE(), 1, NULL_DEREFERENCE, [start of procedure badCheckShouldCauseNPE(),start of procedure getBool(),Taking true branch,return from a call to Boolean NullPointerExceptions.getBool(),Taking true branch,start of procedure getObj(),Taking false branch,return from a call to Object NullPointerExceptions.getObj()] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions.cursorFromContentResolverNPE(String), 9, NULL_DEREFERENCE, [start of procedure cursorFromContentResolverNPE(...)] codetoanalyze/java/infer/NullPointerExceptions.java, void NullPointerExceptions.derefNull(), 2, NULL_DEREFERENCE, [start of procedure derefNull(),start of procedure derefUndefinedCallee(),start of procedure retUndefined(),return from a call to Object NullPointerExceptions.retUndefined(),Skipping toString(): function or method not found,return from a call to Object NullPointerExceptions.derefUndefinedCallee()]