xref: /llvm-project/libcxx/test/libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp (revision bd44174547aaf0b491039a5a71d967e1471b6d87)
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 **)39 int 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