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