blob: 4a85f1521cc7070babecadbf9a4bd0550d6b8cbf [file] [log] [blame]
// 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);