brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.6 KiB · 6a74531 Raw
49 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions -Wno-unevaluated-expression -std=c++20 %s2 3namespace std {4  struct destroying_delete_t {5    explicit destroying_delete_t() = default;6  };7 8  inline constexpr destroying_delete_t destroying_delete{};9}10 11struct Explicit {12    ~Explicit() noexcept(false) {}13 14    void operator delete(Explicit*, std::destroying_delete_t) noexcept {15    }16};17 18Explicit *qn = nullptr;19// This assertion used to fail, see GH11866020static_assert(noexcept(delete(qn)));21 22struct ThrowingDestroyingDelete {23    ~ThrowingDestroyingDelete() noexcept(false) {}24 25    void operator delete(ThrowingDestroyingDelete*, std::destroying_delete_t) noexcept(false) {26    }27};28 29ThrowingDestroyingDelete *pn = nullptr;30// noexcept should return false here because the destroying delete itself is a31// potentially throwing function.32static_assert(!noexcept(delete(pn)));33 34 35struct A {36  virtual ~A(); // implicitly noexcept37};38struct B : A {39  void operator delete(B *p, std::destroying_delete_t) { throw "oh no"; } // expected-warning {{'operator delete' has a non-throwing exception specification but can still throw}} \40                                                                             expected-note {{deallocator has a implicit non-throwing exception specification}}41};42A *p = new B;43 44// Because the destructor for A is virtual, it is the only thing we consider45// when determining whether the delete expression can throw or not, despite the46// fact that the selected operator delete is a destroying delete. For virtual47// destructors, it's the dynamic type that matters.48static_assert(noexcept(delete p));49