| // C++26 P3068R5 - Allowing exception throwing in constant-evaluation |
| // { dg-do compile { target c++26 } } |
| // { dg-require-effective-target exceptions_enabled } |
| |
| struct A { |
| explicit constexpr A (int x) noexcept : a (x) {} |
| constexpr virtual int foo () const noexcept { return a; } |
| constexpr virtual ~A () {} |
| int a; |
| }; |
| struct B : public A { |
| explicit constexpr B (int x) noexcept : A (x) {} |
| constexpr int foo () const noexcept override { return a | 0x10; } |
| }; |
| struct C : public A { |
| explicit constexpr C (int x) noexcept : A (x) {} |
| }; |
| struct D : public A { |
| explicit constexpr D (int x) noexcept : A (x) {} |
| }; |
| struct E { |
| constexpr E () noexcept : e (0) {} |
| explicit constexpr E (int x) noexcept : e (x) {} |
| int e; |
| }; |
| struct F : public E, public B { |
| explicit constexpr F (int x) noexcept : B (x) {} |
| }; |
| struct G : public E, public C { |
| explicit constexpr G (int x) noexcept : C (x) {} |
| }; |
| struct H : public E, public D { |
| explicit constexpr H (int x) noexcept : D (x) {} |
| }; |
| |
| consteval int |
| bar (void (*fn) ()) |
| { |
| int r = 0; |
| try |
| { |
| fn (); |
| } |
| catch (C *a) |
| { |
| r = a->foo () | 0x20; |
| delete a; |
| } |
| catch (const C *b) |
| { |
| r = b->foo () | 0x60; |
| delete b; |
| } |
| catch (A *c) |
| { |
| r = c->foo (); |
| delete c; |
| } |
| catch (const A *d) |
| { |
| r = d->foo () | 0x40; |
| delete d; |
| } |
| return r; |
| } |
| |
| static_assert (bar ([] { throw new A { 1 }; }) == 1); |
| static_assert (bar ([] { throw new B { 2 }; }) == 0x12); |
| static_assert (bar ([] { throw new C { 3 }; }) == 0x23); |
| static_assert (bar ([] { throw new D { 4 }; }) == 4); |
| constexpr int a = bar ([] { throw new E { 5 }; }); // { dg-error "uncaught exception of type 'E\\\*'" } |
| static_assert (bar ([] { throw new F { 6 }; }) == 0x16); |
| static_assert (bar ([] { throw new G { 7 }; }) == 0x27); |
| static_assert (bar ([] { throw new H { 8 }; }) == 8); |