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 unique_ptr<T> with trivial_abi as parameter type.
12 
13 // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
14 
15 // XFAIL: gcc
16 
17 #include <memory>
18 #include <cassert>
19 
call_something()20 __attribute__((noinline)) void call_something() { asm volatile(""); }
21 
22 struct Node {
23   int* shared_val;
24 
NodeNode25   explicit Node(int* ptr) : shared_val(ptr) {}
~NodeNode26   ~Node() { ++(*shared_val); }
27 };
28 
get_val(std::unique_ptr<Node>)29 __attribute__((noinline)) bool get_val(std::unique_ptr<Node> /*unused*/) {
30   call_something();
31   return true;
32 }
33 
expect_1(int * shared,bool)34 __attribute__((noinline)) void expect_1(int* shared, bool /*unused*/) {
35   assert(*shared == 1);
36 }
37 
main(int,char **)38 int main(int, char**) {
39   int shared = 0;
40 
41   // Without trivial-abi, the unique_ptr is deleted at the end of this
42   // statement; expect_1 will see shared == 0 because it's not incremented (in
43   // ~Node()) until expect_1 returns.
44   //
45   // With trivial-abi, expect_1 will see shared == 1 because shared_val is
46   // incremented before get_val returns.
47   expect_1(&shared, get_val(std::unique_ptr<Node>(new Node(&shared))));
48 
49   // Check that the shared-value is still 1.
50   expect_1(&shared, true);
51   return 0;
52 }
53