Re: [PATCH] c++, contracts: Preserve template arguments when rebuilding postconditions [PR125011]

Jason Merrill <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
On 8/14/26 4:49 PM, Wang Jinghao wrote:
> Bootstrapped/regtested on x86_64-pc-linux-gnu.
> 
> -- >8 --
> 
> `rebuild_postconditions' uses `tsubst_expr' to replace the
> placeholder result variable with one of the known return type.
> Passing an empty template argument vector causes direct references
> to template parameters in the condition to ICE in tsubst.
> 
> Use generic arguments for template declarations so that template
> parameters map to themselves while the result variable is rebuilt.

It seems simpler to just return early if processing_template_decl and 
not do this substitution at all, as attached.  That leads to an excess 
errors failure on dcl.contract.func.p7-t1.C, but this seems to actually 
be an improvement: the error about using a non-const parm in a 
postcondition refers to the location of the use.

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

So template-post2.C.

Jason
0001-c-don-t-rebuild-a-template-postcondition.patch (text/x-patch, 2.5 KB)
From 2b5dc0abb6f1d6a482ce7f9cf509478322ceffcf Mon Sep 17 00:00:00 2001
From: Jason Merrill <[email protected]>
Date: Mon, 17 Aug 2026 10:25:31 -0400
Subject: [PATCH] c++: don't rebuild a template postcondition
To: [email protected]

gcc/cp/ChangeLog:

	* contracts.cc (rebuild_postconditions): Skip if
	processing_template_decl.

gcc/testsuite/ChangeLog:

	* g++.dg/contracts/cpp26/dcl.contract.func.p7-t1.C: Expect
	additional error.
---
 gcc/cp/contracts.cc                                       | 8 ++------
 .../g++.dg/contracts/cpp26/dcl.contract.func.p7-t1.C      | 4 ++--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index d860c552bf2..a0f1ad07ff5 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -1976,7 +1976,7 @@ check_postcondition_result (tree fndecl, tree type, location_t loc)
 void
 rebuild_postconditions (tree fndecl)
 {
-  if (!fndecl || fndecl == error_mark_node)
+  if (!fndecl || fndecl == error_mark_node || processing_template_decl)
     return;
 
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
@@ -2031,11 +2031,7 @@ rebuild_postconditions (tree fndecl)
       bool old_pc = processing_postcondition;
       processing_postcondition = true;
 
-      /* Use generic arguments when rebuilding a template declaration.  */
-      tree args = (processing_template_decl && current_template_parms
-		   ? template_parms_to_args (current_template_parms)
-		   : make_tree_vec (0));
-      condition = tsubst_expr (condition, args,
+      condition = tsubst_expr (condition, make_tree_vec (0),
 			       tf_warning_or_error, fndecl);
 
       /* Update the contract condition and result.  */
diff --git a/gcc/testsuite/g++.dg/contracts/cpp26/dcl.contract.func.p7-t1.C b/gcc/testsuite/g++.dg/contracts/cpp26/dcl.contract.func.p7-t1.C
index 91d3f4a306e..82640d3b0fb 100644
--- a/gcc/testsuite/g++.dg/contracts/cpp26/dcl.contract.func.p7-t1.C
+++ b/gcc/testsuite/g++.dg/contracts/cpp26/dcl.contract.func.p7-t1.C
@@ -99,11 +99,11 @@ void PostCondT<int>::f<NTClass>(NTClass, NTClass&, NTClass*, NTClass const*, NTC
 
 template <typename T>
 int f2(const T i[10])
-post(r : r == i[0]){ return 1;};
+post(r : r == i[0]){ return 1;}; // { dg-error "used in a postcondition must be const" } on use
 
 template
 int f2<int>(const int i[10]);
-// { dg-error "used in a postcondition must be const" "" { target *-*-* } 101  }
+// { dg-error "used in a postcondition must be const" "" { target *-*-* } 101  } on decl
 
 // P3520
 template <typename T>
-- 
2.55.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.