Skip to content

Commit 11f4a27

Browse files
Merge pull request gcc-mirror#84 from villevoutilainen/exception-leak-found-by-ran
Fix the exception leak found by Ran
2 parents 7a5d238 + 113e9f6 commit 11f4a27

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

gcc/cp/contracts.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,13 @@ build_contract_condition_function (tree fndecl, bool pre)
15431543
*last = void_list_node;
15441544

15451545
/* The handlers are void fns. */
1546-
TREE_TYPE (fn) = build_function_type (void_type_node, arg_types);
1546+
tree adjusted_type = build_function_type (void_type_node, arg_types);
1547+
1548+
/* If the original function is noexcept, build a noexcept function. */
1549+
if (flag_exceptions && type_noexcept_p (TREE_TYPE (fndecl)))
1550+
adjusted_type = build_exception_variant (adjusted_type, noexcept_true_spec);
1551+
1552+
TREE_TYPE (fn) = adjusted_type;
15471553
DECL_RESULT (fn) = NULL_TREE; /* Let the start function code fill it in. */
15481554

15491555
if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl))
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// test that a noexcept function can't throw even if a violation handler throws
2+
// { dg-do run }
3+
// { dg-options "-std=c++2a -fcontracts -fcontracts-nonattr " }
4+
// { dg-additional-sources "throwing-violation-handler.cc" }
5+
6+
#include <exception>
7+
8+
void f(int x) noexcept pre(x >= 0)
9+
{
10+
}
11+
12+
void g();
13+
14+
bool f_result = true;
15+
16+
void my_term()
17+
{
18+
try { throw; }
19+
catch(int) { __builtin_exit(0); }
20+
}
21+
22+
23+
int main()
24+
{
25+
std::set_terminate (my_term);
26+
try
27+
{
28+
g();
29+
} catch (...) {
30+
// We should not get here
31+
__builtin_abort();
32+
}
33+
if (!f_result)
34+
// We should not get here
35+
__builtin_abort();
36+
// We should not get here
37+
__builtin_abort();
38+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <contracts>
2+
3+
void handle_contract_violation(const std::contracts::contract_violation&)
4+
{
5+
throw 666;
6+
}
7+
8+
/* ODR hack to the hilt - f is actually noexcept, and has a contract.
9+
We do this to avoid the call site knowing that, so that we verify
10+
that the function terminates when it calls the throwing handler
11+
that we use above. */
12+
int f(int);
13+
14+
extern bool f_result;
15+
16+
void g()
17+
{
18+
try {
19+
f(-42);
20+
} catch (...) {
21+
f_result = false;
22+
}
23+
}

0 commit comments

Comments
 (0)