@@ -1547,7 +1547,8 @@ build_contract_condition_function (tree fndecl, bool pre)
1547
1547
DECL_NAME (fn) = copy_node (DECL_NAME (fn));
1548
1548
DECL_INITIAL (fn) = NULL_TREE;
1549
1549
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);
1551
1552
1552
1553
IDENTIFIER_VIRTUAL_P (DECL_NAME (fn)) = false ;
1553
1554
DECL_VIRTUAL_P (fn) = false ;
@@ -1844,6 +1845,17 @@ set_contract_wrapper_function (tree fndecl, tree wrapper)
1844
1845
decl_wrapper_fn->put (fndecl, wrapper);
1845
1846
}
1846
1847
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
+
1847
1859
/* Build a declaration for the contract wrapper of a caller FNDECL.
1848
1860
If is_cvh is true, we're wrapping a contract violation handler
1849
1861
in a noexcept wrapper. Otherwise, we're making a caller side
@@ -1862,16 +1874,10 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh)
1862
1874
tree fnname;
1863
1875
if (is_cvh)
1864
1876
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));
1865
1879
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));
1875
1881
location_t loc = DECL_SOURCE_LOCATION (fndecl);
1876
1882
1877
1883
/* Handle the arg types list. */
@@ -1898,19 +1904,20 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh)
1898
1904
if (flag_exceptions && (is_cvh || type_noexcept_p (TREE_TYPE (fndecl))))
1899
1905
wrapper_type = build_exception_variant (wrapper_type, noexcept_true_spec);
1900
1906
1901
- /* This will create a member function if fndecl is a member function, so we
1902
- will need to adjust the type later. */
1903
1907
tree wrapdecl
1904
1908
= build_lang_decl_loc (loc, FUNCTION_DECL, fnname, wrapper_type);
1905
1909
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
+
1907
1916
DECL_SOURCE_LOCATION (wrapdecl) = loc;
1908
1917
/* The declaration was implicitly generated by the compiler. */
1909
1918
DECL_ARTIFICIAL (wrapdecl) = true ;
1910
1919
/* Declaration, no definition yet. */
1911
1920
DECL_INITIAL (wrapdecl) = NULL_TREE;
1912
- /* This declaration is a contract wrapper function. */
1913
- DECL_CONTRACT_WRAPPER (wrapdecl) = true ;
1914
1921
1915
1922
/* Let the start function code fill in the result decl. */
1916
1923
DECL_RESULT (wrapdecl) = NULL_TREE;
@@ -2351,7 +2358,6 @@ declare_noexcept_cvh_wrapper (tree fncvh_decl)
2351
2358
if (!wrapdecl)
2352
2359
{
2353
2360
wrapdecl = build_contract_wrapper_function (fncvh_decl, /* is_cvh*/ true );
2354
- wrapdecl = pushdecl_top_level (wrapdecl);
2355
2361
set_contract_wrapper_function (fncvh_decl, wrapdecl);
2356
2362
}
2357
2363
@@ -2842,9 +2848,13 @@ start_function_contracts (tree fndecl)
2842
2848
/* If this is not a client side check and definition side checks are
2843
2849
disabled, do nothing. */
2844
2850
if (!flag_contracts_nonattr_definition_check
2845
- && !DECL_CONTRACT_WRAPPER (fndecl))
2851
+ && !DECL_CONTRACT_WRAPPER (fndecl))
2846
2852
return ;
2847
2853
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
+
2848
2858
/* Check that the user did not try to shadow a function parameter with the
2849
2859
specified postcondition result name. */
2850
2860
if (flag_contracts_nonattr)
@@ -3472,7 +3482,10 @@ define_contract_wrapper_func (const tree& fndecl, const tree& wrapdecl, void*)
3472
3482
checks are enabled for all clients. We should not get here unless there
3473
3483
are some checks to make. */
3474
3484
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);
3476
3489
3477
3490
start_preparsed_function (wrapdecl, /* DECL_ATTRIBUTES*/ NULL_TREE,
3478
3491
SF_DEFAULT | SF_PRE_PARSED);
0 commit comments