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

Reply via email to