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 **)38int 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