Skip to content

Commit 04bf921

Browse files
Make the built-in contract violation handler noexcept
1 parent fb8924f commit 04bf921

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// test that the default contract violation handler can't throw
2+
// { dg-do run }
3+
// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on -fcontracts-nonattr " }
4+
5+
#include <experimental/contract>
6+
#include <iostream>
7+
#include <exception>
8+
#include <cstdlib>
9+
10+
// Throws on all overflow and underflow calls.
11+
struct underflow_error: std::exception { };
12+
struct overflow_error: std::exception { };
13+
struct positioning_error: std::exception { };
14+
15+
template<typename T>
16+
struct fail_buf
17+
: public T
18+
{
19+
typedef typename T::char_type char_type;
20+
typedef typename T::int_type int_type;
21+
typedef typename T::off_type off_type;
22+
typedef typename T::pos_type pos_type;
23+
24+
private:
25+
char_type p[2];
26+
27+
public:
28+
fail_buf()
29+
{
30+
p[0] = char_type('s');
31+
p[1] = char_type();
32+
this->setg(p, p, p + 1);
33+
}
34+
35+
virtual int_type underflow()
36+
{
37+
throw underflow_error();
38+
return int_type();
39+
}
40+
41+
virtual int_type uflow()
42+
{
43+
throw underflow_error();
44+
return int_type();
45+
}
46+
47+
virtual int_type
48+
overflow(int_type)
49+
{
50+
throw overflow_error();
51+
return int_type();
52+
}
53+
54+
virtual pos_type
55+
seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode)
56+
{
57+
throw positioning_error();
58+
return pos_type(off_type(-1));
59+
}
60+
61+
virtual pos_type
62+
seekpos(pos_type, std::ios_base::openmode)
63+
{
64+
throw positioning_error();
65+
return pos_type(off_type(-1));
66+
}
67+
68+
virtual int
69+
sync()
70+
{
71+
throw positioning_error();
72+
return 0;
73+
}
74+
};
75+
76+
typedef fail_buf<std::streambuf> fail_streambuf;
77+
78+
79+
// Test that there is an active exception when we reach the terminate handler.
80+
void my_term()
81+
{
82+
try { throw; }
83+
catch(...) { std::exit(0); }
84+
}
85+
86+
void f(int x) noexcept pre(x >= 0)
87+
{
88+
try{
89+
int i = 1;
90+
}
91+
catch(...) {
92+
}
93+
}
94+
95+
int main()
96+
{
97+
std::set_terminate (my_term);
98+
fail_streambuf buf;
99+
std::cerr.rdbuf(&buf);
100+
try
101+
{
102+
f(-42);
103+
} catch (...) {
104+
}
105+
// We should not get here
106+
return 1;
107+
}

libstdc++-v3/src/experimental/contract.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#endif
3030

3131
__attribute__ ((weak)) void
32-
handle_contract_violation (const std::experimental::contract_violation &violation)
32+
handle_contract_violation (const std::experimental::contract_violation &violation) noexcept
3333
{
3434
#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE
3535
bool level_default_p = violation.assertion_level() == "default";

0 commit comments

Comments
 (0)