diff --git a/infer/tests/codetoanalyze/cpp/pulse/issues.exp b/infer/tests/codetoanalyze/cpp/pulse/issues.exp index 084e06b9a..26078a187 100644 --- a/infer/tests/codetoanalyze/cpp/pulse/issues.exp +++ b/infer/tests/codetoanalyze/cpp/pulse/issues.exp @@ -1,6 +1,8 @@ codetoanalyze/cpp/pulse/basics.cpp, multiple_invalidations_branch_bad, 6, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete ptr` at line 58, column 5 here,accessed `*(ptr)` here] codetoanalyze/cpp/pulse/basics.cpp, multiple_invalidations_loop_bad, 3, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete ptr` at line 68, column 7 here,accessed `ptr` here] -codetoanalyze/cpp/pulse/join.cpp, invalidate_node_alias_bad, 12, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete result` at line 21, column 5 here,accessed `*(result)` here] +codetoanalyze/cpp/pulse/join.cpp, FP_cond_inside_loop_ok, 7, USE_AFTER_DESTRUCTOR, no_bucket, ERROR, [invalidated by destructor call `BasicStruct_~BasicStruct(x)` at line 74, column 3 here,accessed `&(x)` here] +codetoanalyze/cpp/pulse/join.cpp, FP_list_delete_ok, 6, USE_AFTER_FREE, no_bucket, ERROR, [invalidated by call to `free(tmp->foo)` at line 42, column 7 here,accessed `tmp->foo` here] +codetoanalyze/cpp/pulse/join.cpp, invalidate_node_alias_bad, 12, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete result` at line 25, column 5 here,accessed `*(result)` here] codetoanalyze/cpp/pulse/returns.cpp, returns::return_deleted_bad, 4, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete x` at line 112, column 3 here,accessed `x` here] codetoanalyze/cpp/pulse/use_after_delete.cpp, delete_in_branch_bad, 5, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete s` at line 57, column 5 here,accessed `s` here] codetoanalyze/cpp/pulse/use_after_delete.cpp, delete_in_loop_bad, 3, USE_AFTER_DELETE, no_bucket, ERROR, [invalidated by call to `delete s` at line 82, column 5 here,accessed `s` here] diff --git a/infer/tests/codetoanalyze/cpp/pulse/join.cpp b/infer/tests/codetoanalyze/cpp/pulse/join.cpp index 3e71dc216..4d5a26235 100644 --- a/infer/tests/codetoanalyze/cpp/pulse/join.cpp +++ b/infer/tests/codetoanalyze/cpp/pulse/join.cpp @@ -4,6 +4,10 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ + +#include +#include + struct foo { int* val; }; @@ -28,9 +32,23 @@ int invalidate_node_alias_bad(struct list* head, int cond) { return *result; } +void FP_list_delete_ok(struct list** l) { + auto head = *l; + *l = nullptr; + while (head) { + auto tmp = head; + head = head->next; + if (tmp->foo) { + free(tmp->foo); + tmp->foo = nullptr; + } + } +} + struct BasicStruct { - // force destructor calls to be injected - virtual void some_method() {} + void some_method() {} + BasicStruct(); + ~BasicStruct(); }; int nested_loops_ok() { @@ -41,3 +59,23 @@ int nested_loops_ok() { } } } + +extern bool some_bool(); +extern BasicStruct mk_basic_struct(); + +void FP_cond_inside_loop_ok() { + while (true) { + BasicStruct x; + if (some_bool()) { + x = mk_basic_struct(); + } + + x.some_method(); + } +} + +void nested_loops3_ok(std::vector* c) { + for (auto& b : *c) { + (&b)->~BasicStruct(); + } +}