From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id 46D2A3857366; Wed, 2 Nov 2022 18:44:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 46D2A3857366 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667414686; bh=44pa45sFJi7LryX7uRDKSUBnhHtndu12o2GAmfjsHGU=; h=From:To:Subject:Date:From; b=HMsMGMhyxrOBD8qJQdEIh92WBTj0NMVMnRwOw/DORU5gchNqBXfKVEJu1GcqUU/4x IEeuWXCscnb2x7g3ILrJzCxOsAPnpjSFyjhy7MYOWuBKO7+e98GzupdTgQiB7L68Q/ 1Ou9h5cGrK8pBrgzZeSiWpLeJvW9Sst2NtgiLv2E= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/c++-contracts] c++: small refactor X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/devel/c++-contracts X-Git-Oldrev: 4f428e8b3f0a8a2ee282a952e1f70a8146478cdd X-Git-Newrev: 0c073c813d4ca2bbba9d0801171308ff429dbbbe Message-Id: <20221102184446.46D2A3857366@sourceware.org> Date: Wed, 2 Nov 2022 18:44:45 +0000 (GMT) List-Id: https://gcc.gnu.org/g:0c073c813d4ca2bbba9d0801171308ff429dbbbe commit 0c073c813d4ca2bbba9d0801171308ff429dbbbe Author: Jason Merrill Date: Tue Nov 1 11:27:18 2022 -0400 c++: small refactor Reducing the number of places that check DECL_{CONS,DES}TRUCTOR_P to decide whether to outline the contracts. Diff: --- gcc/cp/contracts.cc | 97 ++++++++++++++++++++++++++++++----------------------- gcc/cp/decl.cc | 3 -- gcc/cp/semantics.cc | 6 +--- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc index 3a0377089a0..dc0df471dfc 100644 --- a/gcc/cp/contracts.cc +++ b/gcc/cp/contracts.cc @@ -1480,6 +1480,15 @@ build_contract_condition_function (tree fndecl, bool pre) return fn; } +/* Return true if CONTRACT is checked or assumed under the current build + configuration. */ + +bool +contract_active_p (tree contract) +{ + return get_contract_semantic (contract) != CCS_IGNORE; +} + static bool has_active_contract_condition (tree d, tree_code c) { @@ -1508,6 +1517,40 @@ has_active_postconditions (tree d) return has_active_contract_condition (d, POSTCONDITION_STMT); } +/* Return true if any contract in the CONTRACT list is checked or assumed + under the current build configuration. */ + +bool +contract_any_active_p (tree contract) +{ + for (; contract != NULL_TREE; contract = CONTRACT_CHAIN (contract)) + if (contract_active_p (TREE_VALUE (TREE_VALUE (contract)))) + return true; + return false; +} + +/* Do we need to mess with contracts for DECL1? */ + +static bool +handle_contracts_p (tree decl1) +{ + return (flag_contracts + && !processing_template_decl + && DECL_ORIGINAL_FN (decl1) == NULL_TREE + && contract_any_active_p (DECL_CONTRACTS (decl1))); +} + +/* Should we break out DECL1's pre/post contracts into separate functions? + FIXME I'd like this to default to 0, but that will need an overhaul to the + return identifier handling to just refor to the RESULT_DECL. */ + +static bool +outline_contracts_p (tree decl1) +{ + return (!DECL_CONSTRUCTOR_P (decl1) + && !DECL_DESTRUCTOR_P (decl1)); +} + /* Build the precondition checking function for D. */ static tree @@ -1540,7 +1583,7 @@ void build_contract_function_decls (tree d) { /* Constructors and destructors have their contracts inserted inline. */ - if (DECL_CONSTRUCTOR_P (d) || DECL_DESTRUCTOR_P (d)) + if (!outline_contracts_p (d)) return; /* Build the pre/post functions (or not). */ @@ -1651,12 +1694,7 @@ static tree build_contract_violation (tree contract, contract_continuation cmode) { expanded_location loc = expand_location (EXPR_LOCATION (contract)); - const char *function = - TREE_CODE (contract) == ASSERTION_STMT - || DECL_CONSTRUCTOR_P (current_function_decl) - || DECL_DESTRUCTOR_P (current_function_decl) - ? current_function_name () - : fndecl_name (DECL_ORIGINAL_FN (current_function_decl)); + const char *function = fndecl_name (DECL_ORIGIN (current_function_decl)); const char *level = get_contract_level_name (contract); const char *role = get_contract_role_name (contract); @@ -1747,27 +1785,6 @@ build_contract_handler_call (tree contract, finish_expr_stmt (call); } -/* Return true if CONTRACT is checked or assumed under the current build - configuration. */ - -bool -contract_active_p (tree contract) -{ - return get_contract_semantic (contract) != CCS_IGNORE; -} - -/* Return true if any contract in the CONTRACT list is checked or assumed - under the current build configuration. */ - -bool -contract_any_active_p (tree contract) -{ - for (; contract != NULL_TREE; contract = CONTRACT_CHAIN (contract)) - if (contract_active_p (TREE_VALUE (TREE_VALUE (contract)))) - return true; - return false; -} - /* Generate the code that checks or assumes a contract, but do not attach it to the current context. This is called during genericization. */ @@ -1984,15 +2001,16 @@ build_arg_list (tree fn) void start_function_contracts (tree decl1) { - bool starting_guarded_p = !processing_template_decl - && DECL_ORIGINAL_FN (decl1) == NULL_TREE - && contract_any_active_p (DECL_CONTRACTS (decl1)) - && !DECL_CONSTRUCTOR_P (decl1) - && !DECL_DESTRUCTOR_P (decl1); - - if (!starting_guarded_p) + if (!handle_contracts_p (decl1)) return; + if (!outline_contracts_p (decl1)) + { + emit_preconditions (DECL_CONTRACTS (current_function_decl)); + emit_postconditions_cleanup (DECL_CONTRACTS (current_function_decl)); + return; + } + /* Contracts may have just been added without a chance to parse them, though we still need the PRE_FN available to generate a call to it. */ if (!DECL_PRE_FN (decl1)) @@ -2018,13 +2036,8 @@ start_function_contracts (tree decl1) void finish_function_contracts (tree fndecl) { - bool finishing_guarded_p = !processing_template_decl - && DECL_ORIGINAL_FN (fndecl) == NULL_TREE - && contract_any_active_p (DECL_CONTRACTS (fndecl)) - && !DECL_CONSTRUCTOR_P (fndecl) - && !DECL_DESTRUCTOR_P (fndecl); - - if (!finishing_guarded_p) + if (!handle_contracts_p (fndecl) + || !outline_contracts_p (fndecl)) return; for (tree ca = DECL_CONTRACTS (fndecl); ca; ca = CONTRACT_CHAIN (ca)) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 4a85c858686..c845c3d7e8c 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -17701,9 +17701,6 @@ begin_destructor_body (void) { tree compound_stmt; - emit_preconditions (DECL_CONTRACTS (current_function_decl)); - emit_postconditions_cleanup (DECL_CONTRACTS (current_function_decl)); - /* If the CURRENT_CLASS_TYPE is incomplete, we will have already issued an error message. We still want to try to process the body of the function, but initialize_vtbl_ptrs will crash if diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 233d3129a6c..c909a43fe52 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2062,11 +2062,7 @@ finish_mem_initializers (tree mem_inits) CTOR_INITIALIZER, mem_inits)); } else - { - emit_preconditions (DECL_CONTRACTS (current_function_decl)); - emit_postconditions_cleanup (DECL_CONTRACTS (current_function_decl)); - emit_mem_initializers (mem_inits); - } + emit_mem_initializers (mem_inits); } /* Obfuscate EXPR if it looks like an id-expression or member access so