Skip to content

Commit 1eb297e

Browse files
Merge pull request gcc-mirror#82 from iains/contracts-nonattr-wrapper-renames
Contracts nonattr wrapper renames
2 parents 8db3df9 + 8f5ad49 commit 1eb297e

File tree

10 files changed

+91
-50
lines changed

10 files changed

+91
-50
lines changed

gcc/cp/contracts.cc

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,8 @@ build_contract_condition_function (tree fndecl, bool pre)
15471547
DECL_NAME (fn) = copy_node (DECL_NAME (fn));
15481548
DECL_INITIAL (fn) = NULL_TREE;
15491549
CONTRACT_HELPER (fn) = pre ? ldf_contract_pre : ldf_contract_post;
1550-
DECL_CONTRACT_WRAPPER (fn) = false;
1550+
/* We might have a pre/post for a wrapper. */
1551+
DECL_CONTRACT_WRAPPER (fn) = DECL_CONTRACT_WRAPPER (fndecl);
15511552

15521553
IDENTIFIER_VIRTUAL_P (DECL_NAME (fn)) = false;
15531554
DECL_VIRTUAL_P (fn) = false;
@@ -1844,6 +1845,17 @@ set_contract_wrapper_function (tree fndecl, tree wrapper)
18441845
decl_wrapper_fn->put (fndecl, wrapper);
18451846
}
18461847

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+
18471859
/* Build a declaration for the contract wrapper of a caller FNDECL.
18481860
If is_cvh is true, we're wrapping a contract violation handler
18491861
in a noexcept wrapper. Otherwise, we're making a caller side
@@ -1862,16 +1874,10 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh)
18621874
tree fnname;
18631875
if (is_cvh)
18641876
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));
18651879
else
1866-
{
1867-
/* Use mangled name so we can differentiate between different virtual
1868-
functions of the same name. */
1869-
const char *name = IDENTIFIER_POINTER ((mangle_decl_string (fndecl)));
1870-
char *buf = xasprintf ("%s.contract_wrapper", name);
1871-
fnname = get_identifier (buf);
1872-
free (buf);
1873-
}
1874-
1880+
fnname = copy_node (DECL_NAME (fndecl));
18751881
location_t loc = DECL_SOURCE_LOCATION (fndecl);
18761882

18771883
/* Handle the arg types list. */
@@ -1898,19 +1904,20 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh)
18981904
if (flag_exceptions && (is_cvh || type_noexcept_p (TREE_TYPE (fndecl))))
18991905
wrapper_type = build_exception_variant (wrapper_type, noexcept_true_spec);
19001906

1901-
/* This will create a member function if fndecl is a member function, so we
1902-
will need to adjust the type later. */
19031907
tree wrapdecl
19041908
= build_lang_decl_loc (loc, FUNCTION_DECL, fnname, wrapper_type);
19051909

1906-
DECL_CONTEXT (wrapdecl) = NULL_TREE;
1910+
/* Put the wrapper in the same context as the callee. */
1911+
DECL_CONTEXT (wrapdecl) = DECL_CONTEXT (fndecl);
1912+
if (!is_cvh)
1913+
/* This declaration is a contract wrapper function. */
1914+
DECL_CONTRACT_WRAPPER (wrapdecl) = true;
1915+
19071916
DECL_SOURCE_LOCATION (wrapdecl) = loc;
19081917
/* The declaration was implicitly generated by the compiler. */
19091918
DECL_ARTIFICIAL (wrapdecl) = true;
19101919
/* Declaration, no definition yet. */
19111920
DECL_INITIAL (wrapdecl) = NULL_TREE;
1912-
/* This declaration is a contract wrapper function. */
1913-
DECL_CONTRACT_WRAPPER (wrapdecl) = true;
19141921

19151922
/* Let the start function code fill in the result decl. */
19161923
DECL_RESULT (wrapdecl) = NULL_TREE;
@@ -2351,7 +2358,6 @@ declare_noexcept_cvh_wrapper (tree fncvh_decl)
23512358
if (!wrapdecl)
23522359
{
23532360
wrapdecl = build_contract_wrapper_function (fncvh_decl, /*is_cvh*/true);
2354-
wrapdecl = pushdecl_top_level (wrapdecl);
23552361
set_contract_wrapper_function (fncvh_decl, wrapdecl);
23562362
}
23572363

@@ -2842,9 +2848,13 @@ start_function_contracts (tree fndecl)
28422848
/* If this is not a client side check and definition side checks are
28432849
disabled, do nothing. */
28442850
if (!flag_contracts_nonattr_definition_check
2845-
&& !DECL_CONTRACT_WRAPPER(fndecl))
2851+
&& !DECL_CONTRACT_WRAPPER (fndecl))
28462852
return;
28472853

2854+
/* Even if we will use an outlined function for the check (which will be the
2855+
same one we might use on the callee-side) we still need to check the re-
2856+
mapped contracts for shadowing. */
2857+
28482858
/* Check that the user did not try to shadow a function parameter with the
28492859
specified postcondition result name. */
28502860
if (flag_contracts_nonattr)
@@ -3472,7 +3482,10 @@ define_contract_wrapper_func (const tree& fndecl, const tree& wrapdecl, void*)
34723482
checks are enabled for all clients. We should not get here unless there
34733483
are some checks to make. */
34743484
bool check_post = (flag_contract_nonattr_client_check > 1) || is_virtual;
3475-
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);
34763489

34773490
start_preparsed_function (wrapdecl, /*DECL_ATTRIBUTES*/NULL_TREE,
34783491
SF_DEFAULT | SF_PRE_PARSED);

gcc/cp/contracts.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ enum contract_matching_context
319319
(DECL_DECLARES_FUNCTION_P (NODE) && DECL_LANG_SPECIFIC (NODE) && \
320320
CONTRACT_HELPER (NODE) == ldf_contract_post)
321321

322+
#define DECL_IS_WRAPPER_FN_P(NODE) \
323+
(DECL_DECLARES_FUNCTION_P (NODE) && DECL_LANG_SPECIFIC (NODE) && \
324+
DECL_CONTRACT_WRAPPER (NODE))
325+
322326
extern void remove_contract_attributes (tree);
323327
extern void copy_contract_attributes (tree, tree);
324328
extern void remap_contracts (tree, tree, tree, bool);

gcc/cp/mangle.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,10 @@ write_mangled_name (const tree decl, bool top_level)
819819
write_encoding (decl);
820820
}
821821

822-
/* If this is the pre/post function for a guarded function, append
823-
.pre/post, like something from create_virtual_clone. */
822+
/* Identify helper functions for contracts support. */
823+
if (DECL_IS_WRAPPER_FN_P (decl))
824+
write_string (JOIN_STR "contract_wrapper");
825+
824826
if (DECL_IS_PRE_FN_P (decl))
825827
write_string (JOIN_STR "pre");
826828
else if (DECL_IS_POST_FN_P (decl))

gcc/testsuite/g++.dg/contracts/cpp26-attr/contracts-pre4.C

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,17 @@ int main(int, char**)
7878
return 0;
7979
}
8080

81-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:7: a > 5.*(\n|\r\n|\r)" }
81+
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8282
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8383
// { dg-output "Base: 13(\n|\r\n|\r)" }
84-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:7: a > 5.*(\n|\r\n|\r)" }
84+
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8585
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8686
// { dg-output "Child0: 13(\n|\r\n|\r)" }
87-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:23: a > 14.*(\n|\r\n|\r)" }
87+
// { dg-output "contract violation in function Child1::f at .*.C:23: a > 14.*(\n|\r\n|\r)" }
8888
// { dg-output "contract violation in function Child1::f at .*.C:23: a > 14.*(\n|\r\n|\r)" }
8989
// { dg-output "Child1: 27(\n|\r\n|\r)" }
9090
// { dg-output "Child2: 31(\n|\r\n|\r)" }
91-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:45: a > 0.*(\n|\r\n|\r)" }
91+
// { dg-output "contract violation in function Child3::f at .*.C:45: a > 0.*(\n|\r\n|\r)" }
9292
// { dg-output "contract violation in function Child3::f at .*.C:45: a > 0.*(\n|\r\n|\r)" }
9393
// { dg-output "Child3: 40(\n|\r\n|\r)" }
9494
// { dg-output "Child3: 41(\n|\r\n|\r)" }

gcc/testsuite/g++.dg/contracts/cpp26/callerside-checks/callerside-checks-all.C

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ int main(int, char**)
3434
return 0;
3535
}
3636

37-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 2.*(\n|\r\n|\r)" }
3837
// { dg-output "contract violation in function f at .*: a > 2.*(\n|\r\n|\r)" }
38+
// { dg-output "contract violation in function f at .*: a > 2.*(\n|\r\n|\r)" }
39+
// { dg-output "contract violation in function f at .*: r > 2.*(\n|\r\n|\r)" }
3940
// { dg-output "contract violation in function f at .*: r > 2.*(\n|\r\n|\r)" }
40-
// { dg-output "contract violation in function .*contract_wrapper at .*: r > 2.*(\n|\r\n|\r)" }
41-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 3.*(\n|\r\n|\r)" }
41+
// { dg-output "contract violation in function S::f at .*: a > 3.*(\n|\r\n|\r)" }
4242
// { dg-output "contract violation in function S::f at .*: a > 3.*(\n|\r\n|\r)" }
4343
// { dg-output "contract violation in function S::f at .*: r > 3.*(\n|\r\n|\r)" }
44-
// { dg-output "contract violation in function .*contract_wrapper at .*: r > 3.*(\n|\r\n|\r)" }
45-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 4.*(\n|\r\n|\r)" }
44+
// { dg-output "contract violation in function S::f at .*: r > 3.*(\n|\r\n|\r)" }
45+
// { dg-output "contract violation in function TS<int>::f at .*: a > 4.*(\n|\r\n|\r)" }
4646
// { dg-output "contract violation in function TS<int>::f at .*: a > 4.*(\n|\r\n|\r)" }
4747
// { dg-output "contract violation in function TS<int>::f at .*: r > 4.*(\n|\r\n|\r)" }
48-
// { dg-output "contract violation in function .*contract_wrapper at .*: r > 4.*(\n|\r\n|\r)" }
49-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
48+
// { dg-output "contract violation in function TS<int>::f at .*: r > 4.*(\n|\r\n|\r)" }
49+
// { dg-output "contract violation in function TS<int>::tf at .*: a > 5.*(\n|\r\n|\r)" }
5050
// { dg-output "contract violation in function TS<int>::tf<int> at .*: a > 5.*(\n|\r\n|\r)" }
5151
// { dg-output "contract violation in function TS<int>::tf<int> at .*: r > 5.*(\n|\r\n|\r)" }
52-
// { dg-output "contract violation in function .*contract_wrapper at .*: r > 5.*(\n|\r\n|\r)" }
52+
// { dg-output "contract violation in function TS<int>::tf at .*: r > 5.*(\n|\r\n|\r)" }
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+
}

gcc/testsuite/g++.dg/contracts/cpp26/contracts-pre4.C

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,17 @@ int main(int, char**)
7878
return 0;
7979
}
8080

81-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:7: a > 5.*(\n|\r\n|\r)" }
81+
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8282
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8383
// { dg-output "Base: 13(\n|\r\n|\r)" }
84-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:7: a > 5.*(\n|\r\n|\r)" }
84+
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8585
// { dg-output "contract violation in function Base::f at .*.C:7: a > 5.*(\n|\r\n|\r)" }
8686
// { dg-output "Child0: 13(\n|\r\n|\r)" }
87-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:23: a > 14.*(\n|\r\n|\r)" }
87+
// { dg-output "contract violation in function Child1::f at .*.C:23: a > 14.*(\n|\r\n|\r)" }
8888
// { dg-output "contract violation in function Child1::f at .*.C:23: a > 14.*(\n|\r\n|\r)" }
8989
// { dg-output "Child1: 27(\n|\r\n|\r)" }
9090
// { dg-output "Child2: 31(\n|\r\n|\r)" }
91-
// { dg-output "contract violation in function .*contract_wrapper at .*.C:45: a > 0.*(\n|\r\n|\r)" }
91+
// { dg-output "contract violation in function Child3::f at .*.C:45: a > 0.*(\n|\r\n|\r)" }
9292
// { dg-output "contract violation in function Child3::f at .*.C:45: a > 0.*(\n|\r\n|\r)" }
9393
// { dg-output "Child3: 40(\n|\r\n|\r)" }
9494
// { dg-output "Child3: 41(\n|\r\n|\r)" }

gcc/testsuite/g++.dg/contracts/cpp26/definition-checks/virtual-func-no-def-check2.C

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ int main(int, char**)
2727

2828
return 0;
2929
}
30-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 14.*(\n|\r\n|\r)" }
31-
// { dg-output "contract violation in function .*contract_wrapper at .*: r > 2.*(\n|\r\n|\r)" }
30+
// { dg-output "contract violation in function Base::f at .*: a > 14.*(\n|\r\n|\r)" }
31+
// { dg-output "contract violation in function Base::f at .*: r > 2.*(\n|\r\n|\r)" }

gcc/testsuite/g++.dg/contracts/cpp26/virtual_func1.C

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,33 +68,33 @@ int main(int, char**)
6868
return 0;
6969
}
7070

71-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
71+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
7272
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
7373
// { dg-output "Base: 3(\n|\r\n|\r)" }
74-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
74+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
7575
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
7676
// { dg-output "Child0: 3(\n|\r\n|\r)" }
77-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 14.*(\n|\r\n|\r)" }
77+
// { dg-output "contract violation in function Child1::f at .*: a > 14.*(\n|\r\n|\r)" }
7878
// { dg-output "contract violation in function Child1::f at .*: a > 14.*(\n|\r\n|\r)" }
7979
// { dg-output "Child1: 17(\n|\r\n|\r)" }
8080
// { dg-output "contract violation in function GChild1::f at .*: a > 6.*(\n|\r\n|\r)" }
81-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 6.*(\n|\r\n|\r)" }
81+
// { dg-output "contract violation in function GChild1::f at .*: a > 6.*(\n|\r\n|\r)" }
8282
// { dg-output "GChild1: 103(\n|\r\n|\r)" }
8383
// { dg-output "contract violation in function GChild2::f at .*: a > 30.*(\n|\r\n|\r)" }
84-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 30.*(\n|\r\n|\r)" }
84+
// { dg-output "contract violation in function GChild2::f at .*: a > 30.*(\n|\r\n|\r)" }
8585
// { dg-output "GChild2: 207(\n|\r\n|\r)" }
86-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
86+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
8787
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
8888
// { dg-output "fooBase.Base.: 1(\n|\r\n|\r)" }
89-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
89+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
9090
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
9191
// { dg-output "fooBase.Child0.: 1(\n|\r\n|\r)" }
92-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
92+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
9393
// { dg-output "contract violation in function Child1::f at .*: a > 14.*(\n|\r\n|\r)" }
9494
// { dg-output "fooBase.Child1.: 11(\n|\r\n|\r)" }
95-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
95+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
9696
// { dg-output "contract violation in function GChild1::f at .*: a > 6.*(\n|\r\n|\r)" }
9797
// { dg-output "fooBase.GChild1.: 101(\n|\r\n|\r)" }
98-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
98+
// { dg-output "contract violation in function Base::f at .*: a > 5.*(\n|\r\n|\r)" }
9999
// { dg-output "contract violation in function GChild2::f at .*: a > 30.*(\n|\r\n|\r)" }
100100
// { dg-output "fooBase.GChild2.: 201(\n|\r\n|\r)" }

gcc/testsuite/g++.dg/contracts/cpp26/virtual_func3.C

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ int main()
2525
foo(c);
2626

2727
}
28-
// { dg-output "contract violation in function .*contract_wrapper at .*: a > 5.*(\n|\r\n|\r)" }
28+
// { dg-output "contract violation in function Base<int>::f at .*: a > 5.*(\n|\r\n|\r)" }
2929
// { dg-output "contract violation in function Child1<int>::f at .*: a > 3.*(\n|\r\n|\r)" }
30-
// { dg-output "contract violation in function .*contract_wrapper at .*: i > 4.*(\n|\r\n|\r)" }
30+
// { dg-output "contract violation in function Base<int>::f at .*: i > 4.*(\n|\r\n|\r)" }

0 commit comments

Comments
 (0)