[pulse] Fix traces for iterator invalidation errors

Summary: Iterator invalidation traces were based on vector rather than iterator itself.

Reviewed By: ezgicicek

Differential Revision: D21202047

fbshipit-source-id: 62ce8a488
master
Daiva Naudziuniene 5 years ago committed by Facebook GitHub Bot
parent ab79b2966a
commit 247ecb813d

@ -404,25 +404,27 @@ module GenericArrayBackedCollectionIterator = struct
let operator_star ~desc iter ~caller_summary:_ ~callee_procname:_ location ~ret astate = let operator_star ~desc iter ~caller_summary:_ ~callee_procname:_ location ~ret astate =
let event = ValueHistory.Call {f= Model desc; location; in_call= []} in let event = ValueHistory.Call {f= Model desc; location; in_call= []} in
let* astate, iter_index = to_internal_pointer location iter astate in let* astate, (iter_index_addr, iter_index_hist) = to_internal_pointer location iter astate in
let+ astate, (elem_val, elem_hist) = let+ astate, (elem_val, _) =
GenericArrayBackedCollection.element location iter (fst iter_index) astate GenericArrayBackedCollection.element location iter iter_index_addr astate
in in
let astate = PulseOperations.write_id (fst ret) (elem_val, event :: elem_hist) astate in let astate = PulseOperations.write_id (fst ret) (elem_val, event :: iter_index_hist) astate in
[ExecutionDomain.ContinueProgram astate] [ExecutionDomain.ContinueProgram astate]
let operator_plus_plus ~desc iter ~caller_summary:_ ~callee_procname:_ location ~ret:_ astate = let operator_plus_plus ~desc iter ~caller_summary:_ ~callee_procname:_ location ~ret:_ astate =
let event = ValueHistory.Call {f= Model desc; location; in_call= []} in let event = ValueHistory.Call {f= Model desc; location; in_call= []} in
let index_next = AbstractValue.mk_fresh () in let index_next = AbstractValue.mk_fresh () in
let* astate, current_index = to_internal_pointer location iter astate in let* astate, (current_index, current_index_hist) = to_internal_pointer location iter astate in
let* astate, element = let* astate, element =
GenericArrayBackedCollection.element location iter (fst current_index) astate GenericArrayBackedCollection.element location iter current_index astate
in in
(* Iterator is invalid if the value it points to is invalid *) (* Iterator is invalid if the value it points to is invalid *)
let* astate, _ = PulseOperations.eval_access location element Dereference astate in let* astate, _ =
PulseOperations.eval_access location (fst element, current_index_hist) Dereference astate
in
PulseOperations.write_field location ~ref:iter internal_pointer PulseOperations.write_field location ~ref:iter internal_pointer
~obj:(index_next, [event]) ~obj:(index_next, event :: current_index_hist)
astate astate
>>| ExecutionDomain.continue >>| List.return >>| ExecutionDomain.continue >>| List.return
end end
@ -476,16 +478,16 @@ module StdVector = struct
let astate = let astate =
PulseArithmetic.and_eq_int (Immediate {location; history= []}) index_zero IntLit.zero astate PulseArithmetic.and_eq_int (Immediate {location; history= []}) index_zero IntLit.zero astate
in in
let* astate, ((arr_addr, hist) as arr) = let* astate, ((arr_addr, _) as arr) =
GenericArrayBackedCollection.eval location vector astate GenericArrayBackedCollection.eval location vector astate
in in
let* astate, _ = GenericArrayBackedCollection.eval_element location arr index_zero astate in let* astate, _ = GenericArrayBackedCollection.eval_element location arr index_zero astate in
PulseOperations.write_field location ~ref:iter GenericArrayBackedCollection.field PulseOperations.write_field location ~ref:iter GenericArrayBackedCollection.field
~obj:(arr_addr, event :: hist) ~obj:(arr_addr, event :: snd iter)
astate astate
>>= PulseOperations.write_field location ~ref:iter >>= PulseOperations.write_field location ~ref:iter
GenericArrayBackedCollectionIterator.internal_pointer GenericArrayBackedCollectionIterator.internal_pointer
~obj:(index_zero, [event]) ~obj:(index_zero, event :: snd iter)
>>| ExecutionDomain.continue >>| List.return >>| ExecutionDomain.continue >>| List.return

@ -87,7 +87,7 @@ codetoanalyze/cpp/pulse/vector.cpp, insert_bad, 3, VECTOR_INVALIDATION, no_bucke
codetoanalyze/cpp/pulse/vector.cpp, push_back_loop_bad, 6, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,variable `vec` declared here,was potentially invalidated by `std::vector::push_back()`,use-after-lifetime part of the trace starts here,variable `vec` declared here,passed as argument to `std::vector::at()` (modelled),return from call to `std::vector::at()` (modelled),assigned,invalid access occurs here] codetoanalyze/cpp/pulse/vector.cpp, push_back_loop_bad, 6, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,variable `vec` declared here,was potentially invalidated by `std::vector::push_back()`,use-after-lifetime part of the trace starts here,variable `vec` declared here,passed as argument to `std::vector::at()` (modelled),return from call to `std::vector::at()` (modelled),assigned,invalid access occurs here]
codetoanalyze/cpp/pulse/vector.cpp, reserve_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of reserve_bad,was potentially invalidated by `std::vector::reserve()`,use-after-lifetime part of the trace starts here,parameter `vec` of reserve_bad,passed as argument to `std::vector::at()` (modelled),return from call to `std::vector::at()` (modelled),assigned,invalid access occurs here] codetoanalyze/cpp/pulse/vector.cpp, reserve_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of reserve_bad,was potentially invalidated by `std::vector::reserve()`,use-after-lifetime part of the trace starts here,parameter `vec` of reserve_bad,passed as argument to `std::vector::at()` (modelled),return from call to `std::vector::at()` (modelled),assigned,invalid access occurs here]
codetoanalyze/cpp/pulse/vector.cpp, shrink_to_fit_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of shrink_to_fit_bad,was potentially invalidated by `std::vector::shrink_to_fit()`,use-after-lifetime part of the trace starts here,parameter `vec` of shrink_to_fit_bad,passed as argument to `std::vector::at()` (modelled),return from call to `std::vector::at()` (modelled),assigned,invalid access occurs here] codetoanalyze/cpp/pulse/vector.cpp, shrink_to_fit_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of shrink_to_fit_bad,was potentially invalidated by `std::vector::shrink_to_fit()`,use-after-lifetime part of the trace starts here,parameter `vec` of shrink_to_fit_bad,passed as argument to `std::vector::at()` (modelled),return from call to `std::vector::at()` (modelled),assigned,invalid access occurs here]
codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_after_push_back_loop_bad, 9, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,variable `vec` declared here,was potentially invalidated by `std::vector::push_back()`,use-after-lifetime part of the trace starts here,variable `vec` declared here,passed as argument to `iterator operator*` (modelled),return from call to `iterator operator*` (modelled),invalid access occurs here] codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_after_push_back_loop_bad, 9, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,variable `vec` declared here,was potentially invalidated by `std::vector::push_back()`,use-after-lifetime part of the trace starts here,variable `iter_begin` declared here,passed as argument to `std::vector::begin()` (modelled),return from call to `std::vector::begin()` (modelled),passed as argument to `iterator constructor` (modelled),return from call to `iterator constructor` (modelled),passed as argument to `iterator operator*` (modelled),return from call to `iterator operator*` (modelled),invalid access occurs here]
codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_next_after_emplace_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of iterator_next_after_emplace_bad,was potentially invalidated by `std::vector::emplace()`,use-after-lifetime part of the trace starts here,parameter `vec` of iterator_next_after_emplace_bad,invalid access occurs here] codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_next_after_emplace_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of iterator_next_after_emplace_bad,was potentially invalidated by `std::vector::emplace()`,use-after-lifetime part of the trace starts here,variable `iter` declared here,passed as argument to `std::vector::begin()` (modelled),return from call to `std::vector::begin()` (modelled),invalid access occurs here]
codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_next_after_emplace_loop_bad, 2, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of iterator_next_after_emplace_loop_bad,was potentially invalidated by `std::vector::emplace()`,use-after-lifetime part of the trace starts here,parameter `vec` of iterator_next_after_emplace_loop_bad,invalid access occurs here] codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_next_after_emplace_loop_bad, 2, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of iterator_next_after_emplace_loop_bad,was potentially invalidated by `std::vector::emplace()`,use-after-lifetime part of the trace starts here,variable `iter` declared here,passed as argument to `std::vector::begin()` (modelled),return from call to `std::vector::begin()` (modelled),invalid access occurs here]
codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_read_after_emplace_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of iterator_read_after_emplace_bad,was potentially invalidated by `std::vector::emplace()`,use-after-lifetime part of the trace starts here,parameter `vec` of iterator_read_after_emplace_bad,passed as argument to `iterator operator*` (modelled),return from call to `iterator operator*` (modelled),invalid access occurs here] codetoanalyze/cpp/pulse/vector_iterator.cpp, iterator_read_after_emplace_bad, 3, VECTOR_INVALIDATION, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `vec` of iterator_read_after_emplace_bad,was potentially invalidated by `std::vector::emplace()`,use-after-lifetime part of the trace starts here,variable `iter` declared here,passed as argument to `std::vector::begin()` (modelled),return from call to `std::vector::begin()` (modelled),passed as argument to `iterator operator*` (modelled),return from call to `iterator operator*` (modelled),invalid access occurs here]

Loading…
Cancel
Save