blob: 8bd6b6f2eb78755047452827be3cdd86d2a3393b [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 S {
constexpr S () : s (0) {}
constexpr S (int x) : s (x) { if (x == 42) throw 42; }
constexpr S (const S &x) : s (x.s) {}
constexpr ~S () noexcept (false) { if (s == 41) throw 41; }
constexpr const char *what () const noexcept { return "S"; }
int s;
};
struct T : public S {
constexpr T () {}
constexpr T (int x) : S (x) {}
constexpr T (const T &x) : S (x.s) {}
constexpr ~T () {}
constexpr const char *what () const noexcept { return "T"; }
};
struct U {
constexpr U () : u (0) {}
constexpr U (int x) : u (x) {}
constexpr U (const S &x) : u (0) {}
constexpr U (const U &x) : u (x.u) { if (u == 42) throw 43; }
constexpr ~U () {}
constexpr const char *what () const noexcept { return "U"; }
int u;
};
constexpr int
foo (int x)
{
if (x == 1)
throw 43;
return x;
}
constexpr int
bar (int x) noexcept // { dg-error "'std::terminate' called" }
{ // { dg-message "uncaught exception exited from 'noexcept' function 'constexpr int bar\\\(int\\\)'" "" { target *-*-* } .-1 }
return foo (x);
}
constexpr int
baz (int x)
{
switch (x)
{
case 0: throw 1; break;
case 1: try { x = bar (x); } catch (...) {} break; // { dg-message "in 'constexpr' expansion of" }
case 2: throw S (2); break;
case 3: try { throw S (42); } catch (int a) { if (a != 42) throw -1; } break;
case 4: try { S s (41); throw 2; } catch (...) {} break; // { dg-error "'std::terminate' called" }
case 5: return 5; // { dg-message "destructor exited with an exception" "" { target *-*-* } .-1 }
case 6:
try
{
throw S (5);
}
catch (const T &) {}
catch (int) {}
catch (const bool &) {}
catch (const T **const &) {}
break;
case 7: try { constexpr int y = foo (2); } catch (...) {} break;
case 8:
try
{
try
{
throw U ();
}
catch (U &u)
{
u.u = 42;
throw;
}
}
catch (U u) // { dg-error "'std::terminate' called" }
{ // { dg-message "constructor exited with another exception while entering handler" "" { target *-*-* } .-1 }
}
break;
case 9:
try
{
throw U (S (41)); // { dg-error "'std::terminate' called" }
} // { dg-message "destructor exited with an exception" "" { target *-*-* } .-1 }
catch (...)
{
}
break;
}
return -1;
}
constexpr int
qux (int x)
{
try { constexpr int y = foo (1); } catch (...) {} // { dg-error "uncaught exception" }
return 0;
}
constexpr int a = baz (0); // { dg-error "uncaught exception" }
constexpr int b = baz (1); // { dg-message "in 'constexpr' expansion of" }
constexpr int c = baz (2); // { dg-error "uncaught exception" }
constexpr int d = baz (3);
constexpr int e = baz (4); // { dg-message "in 'constexpr' expansion of" }
constexpr int f = baz (5);
constexpr int g = baz (6); // { dg-error "uncaught exception" }
constexpr int h = baz (7);
constexpr int i = baz (8); // { dg-message "in 'constexpr' expansion of" }
constexpr int j = baz (9); // { dg-message "in 'constexpr' expansion of" }