@@ -1848,11 +1848,13 @@ set_contract_wrapper_function (tree fndecl, tree wrapper)
18481848 If is_cvh is true, we're wrapping a contract violation handler
18491849 in a noexcept wrapper. Otherwise, we're making a caller side
18501850 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. */
18521855
18531856static 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)
18561858{
18571859 if (error_operand_p (fndecl))
18581860 return error_mark_node;
@@ -1939,11 +1941,6 @@ build_contract_wrapper_function (tree fndecl, bool is_cvh,
19391941 /* Copy any alignment the user added. */
19401942 DECL_USER_ALIGN (wrapdecl) = DECL_USER_ALIGN (fndecl);
19411943
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-
19471944 /* Make this function internal. */
19481945 TREE_PUBLIC (wrapdecl) = false ;
19491946 DECL_EXTERNAL (wrapdecl) = false ;
@@ -3111,6 +3108,8 @@ finish_function_contracts (tree fndecl)
31113108 || DECL_INITIAL (fndecl) == error_mark_node)
31123109 return ;
31133110
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. */
31143113 if (!handle_contracts_p (fndecl)
31153114 || !outline_contracts_p (fndecl))
31163115 return ;
@@ -3160,20 +3159,6 @@ finish_function_contracts (tree fndecl)
31603159 post = finish_function (false );
31613160 expand_or_defer_fn (post );
31623161 }
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- }
31773162}
31783163
31793164static location_t
@@ -3435,19 +3420,19 @@ maybe_contract_wrap_call (tree fndecl, tree call)
34353420 if (!should_contract_wrap_call (do_pre, do_post, is_virtual))
34363421 return call;
34373422
3423+ /* We should not have reached here with nothing to do. */
34383424 /* We check postconditions on virtual function calls or if postcondition
34393425 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) ));
34443430
34453431 /* Build the declaration of the wrapper, if we need to. */
34463432 tree wrapdecl = get_contract_wrapper_function (fndecl);
34473433 if (!wrapdecl)
34483434 {
3449- wrapdecl = build_contract_wrapper_function (fndecl, /* is_cvh*/ false ,
3450- check_post);
3435+ wrapdecl = build_contract_wrapper_function (fndecl, /* is_cvh*/ false );
34513436 set_contract_wrapper_function (fndecl, wrapdecl);
34523437 }
34533438
@@ -3477,6 +3462,18 @@ define_contract_wrapper_func (const tree& fndecl, const tree& wrapdecl, void*)
34773462 if (DECL_INITIAL (wrapdecl) && DECL_INITIAL (wrapdecl) != error_mark_node)
34783463 return true ;
34793464
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+
34803477 start_preparsed_function (wrapdecl, /* DECL_ATTRIBUTES*/ NULL_TREE,
34813478 SF_DEFAULT | SF_PRE_PARSED);
34823479 tree body = begin_function_body ();
0 commit comments