@@ -1848,11 +1848,13 @@ set_contract_wrapper_function (tree fndecl, tree wrapper)
1848
1848
If is_cvh is true, we're wrapping a contract violation handler
1849
1849
in a noexcept wrapper. Otherwise, we're making a caller side
1850
1850
contract check wrapper. For caller side contract check, postconditions
1851
- are only checked if check_post is true. */
1851
+ are only checked if check_post is true.
1852
+ Defer the attachment of the contracts to this function until the callee
1853
+ is non-dependent, or we get cases where the conditions can be non-dependent
1854
+ but still need tsubst-ing. */
1852
1855
1853
1856
static tree
1854
- build_contract_wrapper_function (tree fndecl, bool is_cvh,
1855
- bool check_post = true )
1857
+ build_contract_wrapper_function (tree fndecl, bool is_cvh)
1856
1858
{
1857
1859
if (error_operand_p (fndecl))
1858
1860
return error_mark_node;
@@ -1939,11 +1941,6 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh,
1939
1941
/* Copy any alignment the user added. */
1940
1942
DECL_USER_ALIGN (wrapdecl) = DECL_USER_ALIGN (fndecl);
1941
1943
1942
- /* Apply contracts from the original fn if this isn't a contract
1943
- violation handler. */
1944
- if (!is_cvh)
1945
- copy_and_remap_contracts (wrapdecl, fndecl, true , check_post);
1946
-
1947
1944
/* Make this function internal. */
1948
1945
TREE_PUBLIC (wrapdecl) = false ;
1949
1946
DECL_EXTERNAL (wrapdecl) = false ;
@@ -3111,6 +3108,8 @@ finish_function_contracts (tree fndecl)
3111
3108
|| DECL_INITIAL (fndecl) == error_mark_node)
3112
3109
return ;
3113
3110
3111
+ /* If there are no contracts here, or we're building them in-line then we
3112
+ do not need to build the outlined functions. */
3114
3113
if (!handle_contracts_p (fndecl)
3115
3114
|| !outline_contracts_p (fndecl))
3116
3115
return ;
@@ -3160,20 +3159,6 @@ finish_function_contracts (tree fndecl)
3160
3159
post = finish_function (false );
3161
3160
expand_or_defer_fn (post);
3162
3161
}
3163
-
3164
- /* Check if we need to update wrapper function contracts. */
3165
- tree wrapdecl = get_contract_wrapper_function (fndecl);
3166
- if (wrapdecl)
3167
- {
3168
- /* We copy postconditions on virtual function wrapper calls or if
3169
- postcondition checks are enabled on the caller side. */
3170
- bool copy_post
3171
- = (flag_contract_nonattr_client_check > 1 )
3172
- || ((DECL_IOBJ_MEMBER_FUNCTION_P (fndecl)
3173
- && DECL_VIRTUAL_P (fndecl)));
3174
-
3175
- copy_and_remap_contracts (wrapdecl, fndecl, true , copy_post);
3176
- }
3177
3162
}
3178
3163
3179
3164
static location_t
@@ -3435,19 +3420,19 @@ maybe_contract_wrap_call (tree fndecl, tree call)
3435
3420
if (!should_contract_wrap_call (do_pre, do_post, is_virtual))
3436
3421
return call;
3437
3422
3423
+ /* We should not have reached here with nothing to do. */
3438
3424
/* We check postconditions on virtual function calls or if postcondition
3439
3425
checks are enabled for all clients. */
3440
- bool check_post = (flag_contract_nonattr_client_check > 1 ) || is_virtual;
3441
-
3442
- /* We should not have reached here with nothing to do. */
3443
- gcc_checking_assert (do_pre || (check_post && do_post ));
3426
+ gcc_checking_assert (do_pre
3427
+ || (do_post
3428
+ && ((flag_contract_nonattr_client_check > 1 )
3429
+ || is_virtual) ));
3444
3430
3445
3431
/* Build the declaration of the wrapper, if we need to. */
3446
3432
tree wrapdecl = get_contract_wrapper_function (fndecl);
3447
3433
if (!wrapdecl)
3448
3434
{
3449
- wrapdecl = build_contract_wrapper_function (fndecl, /* is_cvh*/ false ,
3450
- check_post);
3435
+ wrapdecl = build_contract_wrapper_function (fndecl, /* is_cvh*/ false );
3451
3436
set_contract_wrapper_function (fndecl, wrapdecl);
3452
3437
}
3453
3438
@@ -3477,6 +3462,18 @@ define_contract_wrapper_func (const tree& fndecl, const tree& wrapdecl, void*)
3477
3462
if (DECL_INITIAL (wrapdecl) && DECL_INITIAL (wrapdecl) != error_mark_node)
3478
3463
return true ;
3479
3464
3465
+ /* FIXME: Maybe we should check if fndecl is still dependent? */
3466
+
3467
+ /* FIXME: We should not really have any. */
3468
+ remove_contract_attributes (wrapdecl);
3469
+ bool is_virtual = DECL_IOBJ_MEMBER_FUNCTION_P (fndecl)
3470
+ && DECL_VIRTUAL_P (fndecl);
3471
+ /* We check postconditions on virtual function calls or if postcondition
3472
+ checks are enabled for all clients. We should not get here unless there
3473
+ are some checks to make. */
3474
+ bool check_post = (flag_contract_nonattr_client_check > 1 ) || is_virtual;
3475
+ copy_and_remap_contracts (wrapdecl, fndecl, /* remap_result*/ true , check_post);
3476
+
3480
3477
start_preparsed_function (wrapdecl, /* DECL_ATTRIBUTES*/ NULL_TREE,
3481
3478
SF_DEFAULT | SF_PRE_PARSED);
3482
3479
tree body = begin_function_body ();
0 commit comments