1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // <memory> 10 11 // Test shared_ptr<T> with trivial_abi as parameter type. 12 13 // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI 14 15 // XFAIL: gcc 16 // UNSUPPORTED: c++03 17 18 #include <memory> 19 #include <cassert> 20 call_something()21__attribute__((noinline)) void call_something() { asm volatile(""); } 22 23 struct Node { 24 int* shared_val; 25 NodeNode26 explicit Node(int* ptr) : shared_val(ptr) {} ~NodeNode27 ~Node() { ++(*shared_val); } 28 }; 29 get_val(std::shared_ptr<Node>)30__attribute__((noinline)) bool get_val(std::shared_ptr<Node> /*unused*/) { 31 call_something(); 32 return true; 33 } 34 expect_1(int * shared,bool)35__attribute__((noinline)) void expect_1(int* shared, bool /*unused*/) { 36 assert(*shared == 1); 37 } 38 main(int,char **)39int main(int, char**) { 40 int shared = 0; 41 42 // Without trivial-abi, the shared_ptr is deleted at the end of this 43 // statement; expect_1 will see shared == 0 because it's not incremented (in 44 // ~Node()) until expect_1 returns. 45 // 46 // With trivial-abi, expect_1 will see shared == 1 because shared_val is 47 // incremented before get_val returns. 48 expect_1(&shared, get_val(std::make_shared<Node>(&shared))); 49 50 return 0; 51 } 52