Bootstrapped and tested on x86_64-pc-linux-gnu, okay for trunk?

-- 8< --

When a function template has a placeholder return type, substitution of its
postconditions with a result binding need to be deferred until after the
return type is known.

Preconditions and postconditions lacking a result binding were also being
deferred, but rebuild_postconditions doesn't handle them, leaving them
unsubstituted.  This patch substitutes them immediately.

        PR c++/125537

gcc/cp/ChangeLog:

        * pt.cc (tsubst_contract): Only defer postconditions with a result.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Waffl3x <[email protected]>
---
 gcc/cp/pt.cc                                  |  4 ++--
 .../g++.dg/contracts/cpp26/pr125537.C         | 22 +++++++++++++++++++
 2 files changed, 24 insertions(+), 2 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 e8a4a040d78..99f62392c78 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -12400,7 +12400,7 @@ tsubst_contract (tree decl, tree t, tree args, 
tsubst_flags_t complain,
   begin_scope (sk_contract, decl);
   bool old_pc = processing_postcondition;
   processing_postcondition = POSTCONDITION_P (t);
-  if (auto_p)
+  if (auto_p && POSTCONDITION_P (t) && POSTCONDITION_IDENTIFIER (t))
     ++processing_template_decl;
   if (newvar)
     /* Make the variable available for lookup.  */
@@ -12426,7 +12426,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 (auto_p && POSTCONDITION_P (t) && POSTCONDITION_IDENTIFIER (t))
     --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..356f8292b25
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/cpp26/pr125537.C
@@ -0,0 +1,22 @@
+// PR c++/125537
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-fcontracts" }
+
+bool g(int) { return true; }
+
+template<typename T>
+auto f(T a)
+  pre(g(a)) {}
+
+template auto f<int>(int);
+
+struct S
+{
+  bool c() const
+  { return true; }
+  template<typename = void>
+  auto f()
+    pre(c()) {}
+};
+
+template auto S::f();
-- 
2.55.0

Reply via email to