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 arguments destruction order involving unique_ptr<T> with trivial_abi.
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
20 #include "test_macros.h"
21
call_something()22 __attribute__((noinline)) void call_something() { asm volatile(""); }
23
24 struct Base {
25 char* shared_buff;
26 int* cur_idx;
27 const char id;
28
BaseBase29 explicit Base(char* buf, int* idx, char ch)
30 : shared_buff(buf), cur_idx(idx), id(ch) {}
31 Base(const Base& other) = default;
32 Base& operator=(const Base&) = delete;
~BaseBase33 ~Base() { shared_buff[(*cur_idx)++] = id; }
34 };
35
36 struct A : Base {
AA37 explicit A(char* buf, int* idx) : Base(buf, idx, 'A') {}
38 };
39
40 struct B : Base {
BB41 explicit B(char* buf, int* idx) : Base(buf, idx, 'B') {}
42 };
43
44 struct C : Base {
CC45 explicit C(char* buf, int* idx) : Base(buf, idx, 'C') {}
46 };
47
func(A,std::unique_ptr<B>,C)48 __attribute__((noinline)) void func(A /*unused*/, std::unique_ptr<B> /*unused*/,
49 C /*unused*/) {
50 call_something();
51 }
52
main(int,char **)53 int main(int, char**) {
54 char shared_buf[3] = {'0', '0', '0'};
55 int cur_idx = 0;
56
57 func(A(shared_buf, &cur_idx), std::unique_ptr<B>(new B(shared_buf, &cur_idx)),
58 C(shared_buf, &cur_idx));
59
60 #if defined(TEST_ABI_MICROSOFT)
61 // On Microsoft ABI, the dtor order is always A,B,C (because callee-destroyed)
62 assert(shared_buf[0] == 'A' && shared_buf[1] == 'B' && shared_buf[2] == 'C');
63 #else
64 // With trivial_abi, the std::unique_ptr<B> arg is always destructed first.
65 assert(shared_buf[0] == 'B');
66 #endif
67 return 0;
68 }
69