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 28 struct A { 29 int i; ~AA30 virtual ~A() {} 31 }; 32 struct B : public virtual A { 33 int j; 34 }; 35 struct Deleter { operator ()Deleter36 void operator()(void*) const { 37 // do nothing 38 } 39 }; 40 main(int,char **)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(&buffer, '*', 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