1b861457cSAmirreza Ashouri //===----------------------------------------------------------------------===//
2b861457cSAmirreza Ashouri //
3b861457cSAmirreza Ashouri // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b861457cSAmirreza Ashouri // See https://llvm.org/LICENSE.txt for license information.
5b861457cSAmirreza Ashouri // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b861457cSAmirreza Ashouri //
7b861457cSAmirreza Ashouri //===----------------------------------------------------------------------===//
8b861457cSAmirreza Ashouri 
9b861457cSAmirreza Ashouri // <memory>
10b861457cSAmirreza Ashouri 
11b861457cSAmirreza Ashouri // weak_ptr
12b861457cSAmirreza Ashouri 
13b861457cSAmirreza Ashouri // template<class Y> weak_ptr(const weak_ptr<Y>& r);
14b861457cSAmirreza Ashouri // template<class Y> weak_ptr(weak_ptr<Y>&& r);
15b861457cSAmirreza Ashouri //
16b861457cSAmirreza Ashouri // Regression test for https://github.com/llvm/llvm-project/issues/40459
17b861457cSAmirreza Ashouri // Verify that these constructors never attempt a derived-to-virtual-base
18b861457cSAmirreza Ashouri // conversion on a dangling weak_ptr.
19b861457cSAmirreza Ashouri 
20b861457cSAmirreza Ashouri #include <cassert>
21b861457cSAmirreza Ashouri #include <cstring>
22b861457cSAmirreza Ashouri #include <memory>
23*3a442237SLouis Dionne #include <new>
24b861457cSAmirreza Ashouri #include <utility>
25b861457cSAmirreza Ashouri 
26b861457cSAmirreza Ashouri #include "test_macros.h"
27b861457cSAmirreza Ashouri 
28b861457cSAmirreza Ashouri struct A {
29b861457cSAmirreza Ashouri   int i;
~AA30b861457cSAmirreza Ashouri   virtual ~A() {}
31b861457cSAmirreza Ashouri };
32b861457cSAmirreza Ashouri struct B : public virtual A {
33b861457cSAmirreza Ashouri   int j;
34b861457cSAmirreza Ashouri };
35b861457cSAmirreza Ashouri struct Deleter {
operator ()Deleter36b861457cSAmirreza Ashouri   void operator()(void*) const {
37b861457cSAmirreza Ashouri     // do nothing
38b861457cSAmirreza Ashouri   }
39b861457cSAmirreza Ashouri };
40b861457cSAmirreza Ashouri 
main(int,char **)41b861457cSAmirreza Ashouri int main(int, char**) {
42b861457cSAmirreza Ashouri #if TEST_STD_VER >= 11
43b861457cSAmirreza Ashouri   alignas(B) char buffer[sizeof(B)];
44b861457cSAmirreza Ashouri #else
45b861457cSAmirreza Ashouri   std::aligned_storage<sizeof(B), std::alignment_of<B>::value>::type buffer;
46b861457cSAmirreza Ashouri #endif
47b861457cSAmirreza Ashouri   B* pb                 = ::new ((void*)&buffer) B();
48b861457cSAmirreza Ashouri   std::shared_ptr<B> sp = std::shared_ptr<B>(pb, Deleter());
49b861457cSAmirreza Ashouri   std::weak_ptr<B> wp   = sp;
50b861457cSAmirreza Ashouri   sp                    = nullptr;
51b861457cSAmirreza Ashouri   assert(wp.expired());
52b861457cSAmirreza Ashouri 
53b861457cSAmirreza Ashouri   // Overwrite the B object with junk.
54b861457cSAmirreza Ashouri   std::memset(&buffer, '*', sizeof(buffer));
55b861457cSAmirreza Ashouri 
56b861457cSAmirreza Ashouri   std::weak_ptr<A> wq = wp;
57b861457cSAmirreza Ashouri   assert(wq.expired());
58b861457cSAmirreza Ashouri   std::weak_ptr<A> wr = std::move(wp);
59b861457cSAmirreza Ashouri   assert(wr.expired());
60b861457cSAmirreza Ashouri 
61b861457cSAmirreza Ashouri   return 0;
62b861457cSAmirreza Ashouri }
63