public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-contracts] c++: small refactor
@ 2022-11-02 18:44 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-11-02 18:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0c073c813d4ca2bbba9d0801171308ff429dbbbe

commit 0c073c813d4ca2bbba9d0801171308ff429dbbbe
Author: Jason Merrill <jason@redhat.com>
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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-02 18:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-02 18:44 [gcc/devel/c++-contracts] c++: small refactor Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).