Skip to content

Commit 8f5ad49

Browse files
committed
c++, contracts: Handle wrappers on CDTORs
Signed-off-by: Iain Sandoe <[email protected]>
1 parent 5eb84df commit 8f5ad49

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

gcc/cp/contracts.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,17 @@ set_contract_wrapper_function (tree fndecl, tree wrapper)
18451845
decl_wrapper_fn->put (fndecl, wrapper);
18461846
}
18471847

1848+
static tree
1849+
contracts_fixup_cdtorname (tree idin)
1850+
{
1851+
const char *n = IDENTIFIER_POINTER (idin);
1852+
size_t l = strlen (n);
1853+
char *nn = xasprintf ("%.*s_", (int)l-1, n);
1854+
tree nid = get_identifier (nn);
1855+
free (nn);
1856+
return nid;
1857+
}
1858+
18481859
/* Build a declaration for the contract wrapper of a caller FNDECL.
18491860
If is_cvh is true, we're wrapping a contract violation handler
18501861
in a noexcept wrapper. Otherwise, we're making a caller side
@@ -1863,6 +1874,8 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh)
18631874
tree fnname;
18641875
if (is_cvh)
18651876
fnname = get_identifier ("handle_contract_violation.noexcept_wrapper");
1877+
else if (DECL_NAME (fndecl) && IDENTIFIER_CDTOR_P (DECL_NAME (fndecl)))
1878+
fnname = contracts_fixup_cdtorname (DECL_NAME (fndecl));
18661879
else
18671880
fnname = copy_node (DECL_NAME (fndecl));
18681881
location_t loc = DECL_SOURCE_LOCATION (fndecl);
@@ -3469,7 +3482,10 @@ define_contract_wrapper_func (const tree& fndecl, const tree& wrapdecl, void*)
34693482
checks are enabled for all clients. We should not get here unless there
34703483
are some checks to make. */
34713484
bool check_post = (flag_contract_nonattr_client_check > 1) || is_virtual;
3472-
copy_and_remap_contracts (wrapdecl, fndecl, /*remap_result*/true, check_post);
3485+
/* For wrappers on CDTORs we need to refer to the original contracts,
3486+
when the wrapper is around a clone. */
3487+
copy_and_remap_contracts (wrapdecl, DECL_ORIGIN (fndecl),
3488+
/*remap_result*/true, check_post);
34733489

34743490
start_preparsed_function (wrapdecl, /*DECL_ATTRIBUTES*/NULL_TREE,
34753491
SF_DEFAULT | SF_PRE_PARSED);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// { dg-options "-std=c++2a -fcontracts -fcontracts-nonattr -fcontracts-nonattr-client-check=pre" }
2+
3+
struct X
4+
{
5+
X (int x) noexcept
6+
pre (x>1)
7+
{
8+
try {
9+
int i = 1;
10+
}
11+
catch(...) {
12+
}
13+
}
14+
};
15+
16+
int main()
17+
{
18+
try {
19+
X x(-42);
20+
} catch (...) {
21+
}
22+
}

0 commit comments

Comments
 (0)