diff --git a/infer/src/pulse/PulseDiagnostic.ml b/infer/src/pulse/PulseDiagnostic.ml index 36b443b2c..925fd7b0c 100644 --- a/infer/src/pulse/PulseDiagnostic.ml +++ b/infer/src/pulse/PulseDiagnostic.ml @@ -209,10 +209,9 @@ let get_message diagnostic = pulse_start_msg pp_var variable -let add_errlog_header ~title location errlog = - let depth = 0 in +let add_errlog_header ~nesting ~title location errlog = let tags = [] in - Errlog.make_trace_element depth location title tags :: errlog + Errlog.make_trace_element nesting location title tags :: errlog let get_trace_calling_context calling_context errlog = @@ -220,57 +219,75 @@ let get_trace_calling_context calling_context errlog = | [] -> errlog | (_, first_call_loc) :: _ -> - add_errlog_header ~title:"calling context starts here" first_call_loc - @@ ( List.fold calling_context ~init:(errlog, 0) ~f:(fun (errlog, depth) (call, loc) -> + add_errlog_header ~nesting:0 ~title:"calling context starts here" first_call_loc + @@ ( (* errlog is built in the reverse order so reverse everything first *) + List.fold (List.rev calling_context) + ~init:(errlog, List.length calling_context - 1) + ~f:(fun (errlog, depth) (call, loc) -> ( Errlog.make_trace_element depth loc (F.asprintf "in call to %a" CallEvent.pp call) [] :: errlog - , depth + 1 ) ) + , depth - 1 ) ) |> fst ) -let add_invalidation_trace (invalidation : Invalidation.t) invalidation_trace access_trace errlog = - let start_title, access_title = - match invalidation with - | ConstantDereference i when IntLit.equal i IntLit.zero -> - ( "source of the null value part of the trace starts here" - , "null pointer dereference part of the trace starts here" ) - | ConstantDereference _ -> - ( "source of the constant value part of the trace starts here" - , "constant value dereference part of the trace starts here" ) - | CFree - | CppDelete - | EndIterator - | GoneOutOfScope _ - | OptionalEmpty - | StdVector _ - | JavaIterator _ -> - ( "invalidation part of the trace starts here" - , "use-after-lifetime part of the trace starts here" ) - in +let invalidation_titles (invalidation : Invalidation.t) = + match invalidation with + | ConstantDereference i when IntLit.equal i IntLit.zero -> + ( "source of the null value part of the trace starts here" + , "null pointer dereference part of the trace starts here" ) + | ConstantDereference _ -> + ( "source of the constant value part of the trace starts here" + , "constant value dereference part of the trace starts here" ) + | CFree + | CppDelete + | EndIterator + | GoneOutOfScope _ + | OptionalEmpty + | StdVector _ + | JavaIterator _ -> + ( "invalidation part of the trace starts here" + , "use-after-lifetime part of the trace starts here" ) + + +let add_invalidation_trace ~nesting invalidation invalidation_trace errlog = + let start_title = invalidation_titles invalidation |> fst in let start_location = Trace.get_start_location invalidation_trace in - add_errlog_header ~title:start_title start_location - @@ Trace.add_to_errlog ~nesting:1 + add_errlog_header ~nesting ~title:start_title start_location + @@ Trace.add_to_errlog ~nesting:(nesting + 1) ~pp_immediate:(fun fmt -> F.fprintf fmt "%a" Invalidation.describe invalidation) invalidation_trace - @@ + @@ errlog + + +let add_access_trace ~include_title ~nesting invalidation access_trace errlog = let access_start_location = Trace.get_start_location access_trace in - add_errlog_header ~title:access_title access_start_location @@ errlog + let access_title = invalidation_titles invalidation |> snd in + ( if include_title then add_errlog_header ~nesting ~title:access_title access_start_location + else Fn.id ) + @@ Trace.add_to_errlog ~nesting:(nesting + 1) + ~pp_immediate:(fun fmt -> F.pp_print_string fmt "invalid access occurs here") + access_trace + @@ errlog let get_trace = function | AccessToInvalidAddress {calling_context; invalidation; invalidation_trace; access_trace} -> + let in_context_nesting = List.length calling_context in + let should_print_invalidation_trace = not (trace_contains_invalidation access_trace) in get_trace_calling_context calling_context - @@ ( if trace_contains_invalidation access_trace then Fn.id - else add_invalidation_trace invalidation invalidation_trace access_trace ) - @@ Trace.add_to_errlog ~nesting:1 - ~pp_immediate:(fun fmt -> F.pp_print_string fmt "invalid access occurs here") - access_trace + @@ ( if should_print_invalidation_trace then + add_invalidation_trace ~nesting:in_context_nesting invalidation invalidation_trace + else Fn.id ) + @@ add_access_trace + ~include_title:(should_print_invalidation_trace || not (List.is_empty calling_context)) + ~nesting:in_context_nesting invalidation access_trace @@ [] | MemoryLeak {location; allocation_trace} -> let access_start_location = Trace.get_start_location allocation_trace in - add_errlog_header ~title:"allocation part of the trace starts here" access_start_location + add_errlog_header ~nesting:0 ~title:"allocation part of the trace starts here" + access_start_location @@ Trace.add_to_errlog ~nesting:1 ~pp_immediate:(fun fmt -> F.pp_print_string fmt "allocation part of the trace ends here") allocation_trace diff --git a/infer/src/pulse/PulseDiagnostic.mli b/infer/src/pulse/PulseDiagnostic.mli index 86e4146ed..f624b575e 100644 --- a/infer/src/pulse/PulseDiagnostic.mli +++ b/infer/src/pulse/PulseDiagnostic.mli @@ -13,8 +13,9 @@ module ValueHistory = PulseValueHistory type access_to_invalid_address = { calling_context: (CallEvent.t * Location.t) list - (** the list of function calls leading to the issue being realised, which is an additional - common prefix to the traces in the record *) + (** the list of function calls leading to the issue being realised, in + outermost-to-innermost order, which is an additional common prefix to the traces in the + record *) ; invalidation: Invalidation.t ; invalidation_trace: Trace.t (** assuming we are in the calling context, the trace leads to [invalidation] without diff --git a/infer/tests/codetoanalyze/c/pulse/interprocedural.c b/infer/tests/codetoanalyze/c/pulse/interprocedural.c index 0c40c84ce..0882c2d74 100644 --- a/infer/tests/codetoanalyze/c/pulse/interprocedural.c +++ b/infer/tests/codetoanalyze/c/pulse/interprocedural.c @@ -30,3 +30,21 @@ void test_modified_value_then_error_bad(int* x) { *p = 42; } } + +// below is a test that the calling context appears in the correct order in the +// trace + +void latent(int a) { + if (a == 4) { + int* p = NULL; + *p = 42; + } +} + +void propagate_latent_1_latent(int a1) { latent(a1); } + +void propagate_latent_2_latent(int a2) { propagate_latent_1_latent(a2); } + +void propagate_latent_3_latent(int a3) { propagate_latent_2_latent(a3); } + +void make_latent_manifest() { propagate_latent_3_latent(4); } diff --git a/infer/tests/codetoanalyze/c/pulse/issues.exp b/infer/tests/codetoanalyze/c/pulse/issues.exp index d8075f9fc..515ba771a 100644 --- a/infer/tests/codetoanalyze/c/pulse/issues.exp +++ b/infer/tests/codetoanalyze/c/pulse/issues.exp @@ -1,8 +1,10 @@ codetoanalyze/c/pulse/frontend.c, assign_implicit_cast_bad, 8, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/frontend.c, assign_paren_bad, 8, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] -codetoanalyze/c/pulse/interprocedural.c, call_if_freed_invalid2_bad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `call_if_freed_invalid_latent`,is the null pointer,when calling `if_freed_invalid_latent` here,parameter `y` of if_freed_invalid_latent,invalid access occurs here] +codetoanalyze/c/pulse/interprocedural.c, call_if_freed_invalid2_bad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `call_if_freed_invalid_latent`,null pointer dereference part of the trace starts here,is the null pointer,when calling `if_freed_invalid_latent` here,parameter `y` of if_freed_invalid_latent,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, call_if_freed_invalid_latent, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,is the null pointer,when calling `if_freed_invalid_latent` here,parameter `y` of if_freed_invalid_latent,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, if_freed_invalid_latent, 3, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,parameter `y` of if_freed_invalid_latent,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `y` of if_freed_invalid_latent,invalid access occurs here] +codetoanalyze/c/pulse/interprocedural.c, latent, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,is the null pointer,assigned,invalid access occurs here] +codetoanalyze/c/pulse/interprocedural.c, make_latent_manifest, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `propagate_latent_3_latent`,in call to `propagate_latent_2_latent`,in call to `propagate_latent_1_latent`,in call to `latent`,null pointer dereference part of the trace starts here,is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, test_modified_value_then_error_bad, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/latent.c, FN_nonlatent_use_after_free_bad, 6, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,parameter `x` of FN_nonlatent_use_after_free_bad,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of FN_nonlatent_use_after_free_bad,invalid access occurs here] codetoanalyze/c/pulse/latent.c, latent_use_after_free, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,source of the null value part of the trace starts here,is the null pointer,null pointer dereference part of the trace starts here,parameter `x` of latent_use_after_free,invalid access occurs here] @@ -28,7 +30,7 @@ codetoanalyze/c/pulse/nullptr.c, null_alias_bad, 4, MEMORY_LEAK, no_bucket, ERRO codetoanalyze/c/pulse/nullptr.c, nullptr_deref_young_bad, 5, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, access_null_deref_bad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, access_use_after_free_bad, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `l` of access_use_after_free_bad,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `l` of access_use_after_free_bad,invalid access occurs here] -codetoanalyze/c/pulse/traces.c, call_makes_null_deref_manifest_bad, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `something_about_strings_latent`,allocated by call to `malloc` (modelled),is the null pointer,assigned,invalid access occurs here] +codetoanalyze/c/pulse/traces.c, call_makes_null_deref_manifest_bad, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `something_about_strings_latent`,null pointer dereference part of the trace starts here,allocated by call to `malloc` (modelled),is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, simple_deref, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, simple_deref_via_alias, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, something_about_strings_latent, 12, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,allocated by call to `malloc` (modelled),is the null pointer,assigned,invalid access occurs here] diff --git a/infer/tests/codetoanalyze/c/pulse/issues.exp-isl b/infer/tests/codetoanalyze/c/pulse/issues.exp-isl index f216c2c09..0919aedbd 100644 --- a/infer/tests/codetoanalyze/c/pulse/issues.exp-isl +++ b/infer/tests/codetoanalyze/c/pulse/issues.exp-isl @@ -1,8 +1,10 @@ codetoanalyze/c/pulse/frontend.c, assign_implicit_cast_bad, 8, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/frontend.c, assign_paren_bad, 8, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] -codetoanalyze/c/pulse/interprocedural.c, call_if_freed_invalid2_bad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `call_if_freed_invalid_latent`,is the null pointer,when calling `if_freed_invalid_latent` here,invalid access occurs here] +codetoanalyze/c/pulse/interprocedural.c, call_if_freed_invalid2_bad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `call_if_freed_invalid_latent`,null pointer dereference part of the trace starts here,is the null pointer,when calling `if_freed_invalid_latent` here,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, call_if_freed_invalid_latent, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,is the null pointer,when calling `if_freed_invalid_latent` here,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, if_freed_invalid_latent, 3, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,invalid access occurs here] +codetoanalyze/c/pulse/interprocedural.c, latent, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,is the null pointer,assigned,invalid access occurs here] +codetoanalyze/c/pulse/interprocedural.c, make_latent_manifest, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `propagate_latent_3_latent`,in call to `propagate_latent_2_latent`,in call to `propagate_latent_1_latent`,in call to `latent`,null pointer dereference part of the trace starts here,is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/interprocedural.c, test_modified_value_then_error_bad, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/latent.c, FN_nonlatent_use_after_free_bad, 6, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,invalid access occurs here] codetoanalyze/c/pulse/latent.c, latent_use_after_free, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,source of the null value part of the trace starts here,is the null pointer,null pointer dereference part of the trace starts here,invalid access occurs here] @@ -27,7 +29,7 @@ codetoanalyze/c/pulse/nullptr.c, null_alias_bad, 4, MEMORY_LEAK, no_bucket, ERRO codetoanalyze/c/pulse/nullptr.c, nullptr_deref_young_bad, 5, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, access_null_deref_bad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, access_use_after_free_bad, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,invalid access occurs here] -codetoanalyze/c/pulse/traces.c, call_makes_null_deref_manifest_bad, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `something_about_strings_latent`,allocated by call to `malloc` (modelled),is the null pointer,assigned,invalid access occurs here] +codetoanalyze/c/pulse/traces.c, call_makes_null_deref_manifest_bad, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `something_about_strings_latent`,null pointer dereference part of the trace starts here,allocated by call to `malloc` (modelled),is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, simple_deref, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, simple_deref_via_alias, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,assigned,invalid access occurs here] codetoanalyze/c/pulse/traces.c, something_about_strings_latent, 12, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,allocated by call to `malloc` (modelled),is the null pointer,assigned,invalid access occurs here] diff --git a/infer/tests/codetoanalyze/java/pulse/issues.exp b/infer/tests/codetoanalyze/java/pulse/issues.exp index 27e4aa30b..c9857ab3f 100644 --- a/infer/tests/codetoanalyze/java/pulse/issues.exp +++ b/infer/tests/codetoanalyze/java/pulse/issues.exp @@ -18,7 +18,7 @@ codetoanalyze/java/pulse/HashMapExample.java, codetoanalyze.java.infer.HashMapEx codetoanalyze/java/pulse/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getAfterRemovingTheKeyBad():void, 5, NULLPTR_DEREFERENCE, no_bucket, ERROR, [passed as argument to `Map.get()` (modelled),return from call to `Map.get()` (modelled),is the null pointer,assigned,invalid access occurs here] codetoanalyze/java/pulse/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getOneIntegerWithoutCheckBad():int, 6, NULLPTR_DEREFERENCE, no_bucket, ERROR, [passed as argument to `Map.get()` (modelled),return from call to `Map.get()` (modelled),is the null pointer,assigned,passed as argument to `cast` (modelled),return from call to `cast` (modelled),assigned,invalid access occurs here] codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.checkInstanceArray(java.lang.Object):void, 7, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,is the null pointer,assigned,invalid access occurs here] -codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfBooleanArrayBad():void, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `void InstanceOfExample.checkInstanceArray(Object)`,is the null pointer,assigned,invalid access occurs here] +codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfBooleanArrayBad():void, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `void InstanceOfExample.checkInstanceArray(Object)`,null pointer dereference part of the trace starts here,is the null pointer,assigned,invalid access occurs here] codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfNullIntraBad():void, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfObjProfessorBad():void, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [source of the null value part of the trace starts here,when calling `InstanceOfExample$Person InstanceOfExample.updatePerson(InstanceOfExample$Person)` here,assigned,is the null pointer,null pointer dereference part of the trace starts here,passed as argument to `InstanceOfExample$Person InstanceOfExample.updatePerson(InstanceOfExample$Person)`,return from call to `InstanceOfExample$Person InstanceOfExample.updatePerson(InstanceOfExample$Person)`,assigned,invalid access occurs here] codetoanalyze/java/pulse/IntegerExample.java, codetoanalyze.java.infer.IntegerExample.FP_testIntegerBuiltInEqualOperatorCachedValuesOk():void, 19, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] diff --git a/infer/tests/codetoanalyze/java/pulse/issues.exp-isl b/infer/tests/codetoanalyze/java/pulse/issues.exp-isl index 0d1ec1bea..46a9b4f81 100644 --- a/infer/tests/codetoanalyze/java/pulse/issues.exp-isl +++ b/infer/tests/codetoanalyze/java/pulse/issues.exp-isl @@ -17,7 +17,7 @@ codetoanalyze/java/pulse/HashMapExample.java, codetoanalyze.java.infer.HashMapEx codetoanalyze/java/pulse/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getAfterRemovingTheKeyBad():void, 5, NULLPTR_DEREFERENCE, no_bucket, ERROR, [passed as argument to `Map.get()` (modelled),return from call to `Map.get()` (modelled),is the null pointer,assigned,invalid access occurs here] codetoanalyze/java/pulse/HashMapExample.java, codetoanalyze.java.infer.HashMapExample.getOneIntegerWithoutCheckBad():int, 6, NULLPTR_DEREFERENCE, no_bucket, ERROR, [passed as argument to `Map.get()` (modelled),return from call to `Map.get()` (modelled),is the null pointer,assigned,passed as argument to `cast` (modelled),return from call to `cast` (modelled),assigned,invalid access occurs here] codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.checkInstanceArray(java.lang.Object):void, 7, NULLPTR_DEREFERENCE, no_bucket, ERROR, [*** LATENT ***,is the null pointer,assigned,invalid access occurs here] -codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfBooleanArrayBad():void, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `void InstanceOfExample.checkInstanceArray(Object)`,is the null pointer,assigned,invalid access occurs here] +codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfBooleanArrayBad():void, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [calling context starts here,in call to `void InstanceOfExample.checkInstanceArray(Object)`,null pointer dereference part of the trace starts here,is the null pointer,assigned,invalid access occurs here] codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfNullIntraBad():void, 4, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/java/pulse/InstanceOfExample.java, InstanceOfExample.testInstanceOfObjProfessorBad():void, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [source of the null value part of the trace starts here,when calling `InstanceOfExample$Person InstanceOfExample.updatePerson(InstanceOfExample$Person)` here,assigned,is the null pointer,null pointer dereference part of the trace starts here,passed as argument to `InstanceOfExample$Person InstanceOfExample.updatePerson(InstanceOfExample$Person)`,return from call to `InstanceOfExample$Person InstanceOfExample.updatePerson(InstanceOfExample$Person)`,assigned,invalid access occurs here] codetoanalyze/java/pulse/IntegerExample.java, codetoanalyze.java.infer.IntegerExample.FP_testIntegerBuiltInEqualOperatorCachedValuesOk():void, 19, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] diff --git a/infer/tests/codetoanalyze/objcpp/pulse/issues.exp b/infer/tests/codetoanalyze/objcpp/pulse/issues.exp index 12e913773..3a6889ef2 100644 --- a/infer/tests/codetoanalyze/objcpp/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objcpp/pulse/issues.exp @@ -12,7 +12,7 @@ codetoanalyze/objcpp/pulse/NPEBasic.mm, replaceNilInArrayBad, 1, NIL_INSERTION_I codetoanalyze/objcpp/pulse/NPEBasic.mm, testAccessPropertyAccessorBad, 2, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [is the null pointer,assigned,when calling `SomeObject.ptr` here,parameter `self` of SomeObject.ptr,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODBad, 2, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,parameter `self` of SomeObject.returnsnonPOD,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODLatent, 7, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [*** LATENT ***,is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,parameter `self` of SomeObject.returnsnonPOD,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODLatentBad, 1, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `testCallMethodReturnsnonPODLatent`,is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,parameter `self` of SomeObject.returnsnonPOD,invalid access occurs here] +codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODLatentBad, 1, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `testCallMethodReturnsnonPODLatent`,null pointer dereference part of the trace starts here,is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,parameter `self` of SomeObject.returnsnonPOD,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testNilMessagingForModelNilNilOK_FP, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInDict` here,parameter `value` of addObjectInDict,passed as argument to `NSMutableDictionary.setObject:forKey:` (modelled),return from call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testNilMessagingForModelNotNilDictBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInDict` here,parameter `value` of addObjectInDict,passed as argument to `NSMutableDictionary.setObject:forKey:` (modelled),return from call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testNonPODTraceBad, 2, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [source of the null value part of the trace starts here,when calling `SomeObject.returnsNil` here,assigned,is the null pointer,null pointer dereference part of the trace starts here,passed as argument to `SomeObject.returnsNil`,return from call to `SomeObject.returnsNil`,passed as argument to `SomeObject.get`,return from call to `SomeObject.get`,assigned,when calling `SomeObject.returnsnonPOD` here,parameter `self` of SomeObject.returnsnonPOD,invalid access occurs here]