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 <utility> 24 25 #include "test_macros.h" 26 27 struct A { 28 int i; 29 virtual ~A() {} 30 }; 31 struct B : public virtual A { 32 int j; 33 }; 34 struct Deleter { 35 void operator()(void*) const { 36 // do nothing 37 } 38 }; 39 40 int main(int, char**) { 41 #if TEST_STD_VER >= 11 42 alignas(B) char buffer[sizeof(B)]; 43 #else 44 std::aligned_storage<sizeof(B), std::alignment_of<B>::value>::type buffer; 45 #endif 46 B* pb = ::new ((void*)&buffer) B(); 47 std::shared_ptr<B> sp = std::shared_ptr<B>(pb, Deleter()); 48 std::weak_ptr<B> wp = sp; 49 sp = nullptr; 50 assert(wp.expired()); 51 52 // Overwrite the B object with junk. 53 std::memset(&buffer, '*', sizeof(buffer)); 54 55 std::weak_ptr<A> wq = wp; 56 assert(wq.expired()); 57 std::weak_ptr<A> wr = std::move(wp); 58 assert(wr.expired()); 59 60 return 0; 61 } 62