From c3d55817b16686fd6c210d42cc7f373d9e80c253 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Mon, 17 Jun 2019 03:54:56 -0700 Subject: [PATCH] [pulse] another test for temporaries Summary: I rewrote the test so it doesn't need any C++ headers so that: - it's easier to see what's going on - it's easier to debug: the whole AST is now somewhat readable vs before the headers made it impossibly long Reviewed By: ezgicicek Differential Revision: D15674213 fbshipit-source-id: d98941983 --- .../codetoanalyze/cpp/pulse/temporaries.cpp | 60 +++++++++++++------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/infer/tests/codetoanalyze/cpp/pulse/temporaries.cpp b/infer/tests/codetoanalyze/cpp/pulse/temporaries.cpp index 1ea66bdfd..c72afacd8 100644 --- a/infer/tests/codetoanalyze/cpp/pulse/temporaries.cpp +++ b/infer/tests/codetoanalyze/cpp/pulse/temporaries.cpp @@ -4,33 +4,59 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -#include - namespace temporaries { +template +struct UniquePtr { + X* x_; + ~UniquePtr() { + if (x_) { + delete x_; + } + } + UniquePtr(X* y) { x_ = y; } + + UniquePtr(UniquePtr& p) = delete; // no copy constructor + UniquePtr(UniquePtr&& p) { + x_ = p.get(); + p.x_ = nullptr; + } + + X* get() const { return x_; } + + X& operator*() const { return *get(); } + + X* operator->() const { return get(); } +}; + struct A { - int f; + int s_; + ~A() {} + A() { A(42); } + A(int s) { s_ = s; } + A(A& a) { s_ = a.s_; } }; -std::unique_ptr some_f(); +UniquePtr mk_UniquePtr_A() { return UniquePtr(new A); } -void FN_call_some_f_deref_bad() { - const A& a_ref = *some_f(); // temporary unique_ptr returned by `some_f` is - // destroyed at the end of the statement - std::cout << a_ref.f; +int FN_call_mk_UniquePtr_A_deref_bad() { + A* a = mk_UniquePtr_A().get(); // temporary unique_ptr returned by + // `mk_UniquePtr_A` is destroyed at the end + // of the statement + return a->s_; } -void call_some_f_ok() { - auto local = some_f(); // ok, as ownership of a temporary unique_ptr is passed - // to `local` - const A& a_ref = *local; - std::cout << a_ref.f; +int call_mk_UniquePtr_A_ok() { + const UniquePtr& local = + mk_UniquePtr_A(); // ok, as ownership of a temporary unique_ptr is passed + // to `local` + return local->s_; } -void call_some_f_copy_object_ok() { - auto a = *some_f().get(); // ok, as value is copied before temporary - // unique_prt is destroyed - std::cout << a.f; +int call_mk_UniquePtr_A_copy_object_ok() { + A a = *mk_UniquePtr_A().get(); // ok, as value is copied before temporary + // unique_prt is destroyed + return a.s_; } } // namespace temporaries