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