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// weak_ptr
12
13// template<class Y> weak_ptr(const weak_ptr<Y>& r);
14// template<class Y> weak_ptr(weak_ptr<Y>&& r);
15//
16// Regression test for https://github.com/llvm/llvm-project/issues/40459
17// Verify that these constructors never attempt a derived-to-virtual-base
18// conversion on a dangling weak_ptr.
19
20#include <cassert>
21#include <cstring>
22#include <memory>
23#include <new>
24#include <utility>
25
26#include "test_macros.h"
27
28struct A {
29 int i;
30 virtual ~A() {}
31};
32struct B : public virtual A {
33 int j;
34};
35struct Deleter {
36 void operator()(void*) const {
37 // do nothing
38 }
39};
40
41int main(int, char**) {
42#if TEST_STD_VER >= 11
43 alignas(B) char buffer[sizeof(B)];
44#else
45 std::aligned_storage<sizeof(B), std::alignment_of<B>::value>::type buffer;
46#endif
47 B* pb = ::new ((void*)&buffer) B();
48 std::shared_ptr<B> sp = std::shared_ptr<B>(pb, Deleter());
49 std::weak_ptr<B> wp = sp;
50 sp = nullptr;
51 assert(wp.expired());
52
53 // Overwrite the B object with junk.
54 std::memset(s: &buffer, c: '*', n: sizeof(buffer));
55
56 std::weak_ptr<A> wq = wp;
57 assert(wq.expired());
58 std::weak_ptr<A> wr = std::move(wp);
59 assert(wr.expired());
60
61 return 0;
62}
63

source code of libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/pr40459.pass.cpp