[PATCH] c++, contracts: Only defer contracts that use an undeduced result binding [PR125537]

Wang Jinghao <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Bootstrapped/regtested on x86_64-pc-linux-gnu.

-- >8 --

For precondition and postcondition without a result binding, whether
the return type is auto is irrelevant to the condition expression, so
type conversions should be completed immediately.

	PR c++/125537

gcc/cp/ChangeLog:

	* pt.cc (tsubst_contract): Keep template processing enabled
	only for postconditions with an undeduced result binding.

gcc/testsuite/ChangeLog:

	* g++.dg/contracts/cpp26/pr125537.C: New test.

Signed-off-by: Wang Jinghao <[email protected]>
---
 gcc/cp/pt.cc                                   | 10 ++++++----
 .../g++.dg/contracts/cpp26/pr125537.C          | 18 ++++++++++++++++++
 2 files changed, 24 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/contracts/cpp26/pr125537.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1290db45e18..54a33f0be94 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -12394,12 +12394,14 @@ tsubst_contract (tree decl, tree t, tree args, tsubst_flags_t complain,
 	  return invalidate_contract (r);
     }
 
-  /* Instantiate the condition.  If the return type is undeduced, process
-     the expression as if inside a template to avoid spurious type errors.  */
+  /* Instantiate the condition.  If the postcondition has a result binding
+     whose type is undeduced, process the expression as if inside a template to
+     avoid spurious type errors.  */
   begin_scope (sk_contract, decl);
   bool old_pc = processing_postcondition;
   processing_postcondition = POSTCONDITION_P (t);
-  if (auto_p)
+  const bool undeduced_result_type_p = auto_p && newvar;
+  if (undeduced_result_type_p)
     ++processing_template_decl;
   if (newvar)
     /* Make the variable available for lookup.  */
@@ -12425,7 +12427,7 @@ tsubst_contract (tree decl, tree t, tree args, tsubst_flags_t complain,
      && !type_dependent_expression_p (CONTRACT_ASSERTION_KIND (r))
      && !type_dependent_expression_p (CONTRACT_COMMENT (r)));
 
-  if (auto_p)
+  if (undeduced_result_type_p)
     --processing_template_decl;
   processing_postcondition = old_pc;
   gcc_checking_assert (scope_chain && scope_chain->bindings
diff --git a/gcc/testsuite/g++.dg/contracts/cpp26/pr125537.C b/gcc/testsuite/g++.dg/contracts/cpp26/pr125537.C
new file mode 100644
index 00000000000..38579f582b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/cpp26/pr125537.C
@@ -0,0 +1,18 @@
+// PR c++/125537
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-fcontracts" }
+
+template<typename>
+  auto f (const bool b)
+    pre (b)
+    post (b)
+    post (r: r)
+  {
+    return b;
+  }
+
+
+int main ()
+{
+  f<bool> (true);
+}
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.