[PATCH] c++, contracts: Fix pack expansions referring to dummy parameters [PR125645]

Wang Jinghao <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Bootstrapped/regtested on x86_64-pc-linux-gnu.

-- >8 --

Contract conditions are parsed outside the function body, so
`at_function_scope_p()' is false when their parameter pack expansions
are formed.  However, function parameter packs in contract conditions
should use local specializations during substitution, just as they do
within a function body.

	PR c++/125645

gcc/cp/ChangeLog:

	* cp-tree.h (PACK_INDEX_PARENTHESIZED_P): Fix incorrect
	documentation in usage.
	(PACK_EXPANSION_LOCAL_P): Update comment.
	* pt.cc (make_pack_expansion): Mark function parameter pack
	expansions in contract conditions as local.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Wang Jinghao <[email protected]>
---
 gcc/cp/cp-tree.h                                |  5 +++--
 gcc/cp/pt.cc                                    |  6 +++++-
 gcc/testsuite/g++.dg/contracts/cpp26/pr125645.C | 13 +++++++++++++
 3 files changed, 21 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/contracts/cpp26/pr125645.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c73b42ed44f..5d970ea3fa7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -454,7 +454,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
       INIT_EXPR_NRV_P (in INIT_EXPR)
       ATOMIC_CONSTR_MAP_INSTANTIATED_P (in ATOMIC_CONSTR)
       RETURN_EXPR_LOCAL_ADDR_P (in RETURN_EXPR)
-      PACK_INDEX_PARENTHESIZED_P (in PACK_INDEX_*)
       MUST_NOT_THROW_NOEXCEPT_P (in MUST_NOT_THROW_EXPR)
       CONSTEVAL_BLOCK_P (in STATIC_ASSERT)
       LAMBDA_EXPR_CONSTEVAL_BLOCK_P (in LAMBDA_EXPR)
@@ -486,6 +485,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
       MUST_NOT_THROW_THROW_P (in MUST_NOT_THROW_EXPR)
       LAMBDA_EXPR_CONST_QUAL_P (in LAMBDA_EXPR)
       SPLICE_EXPR_MEMBER_ACCESS_P (in SPLICE_EXPR)
+      PACK_INDEX_PARENTHESIZED_P (in PACK_INDEX_*)
    2: IDENTIFIER_KIND_BIT_2 (in IDENTIFIER_NODE)
       ICS_THIS_FLAG (in _CONV)
       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
@@ -4425,7 +4425,8 @@ struct GTY(()) lang_decl {
     ? &TYPE_MAX_VALUE_RAW (NODE)			\
     : &TREE_OPERAND ((NODE), 1))
 
-/* True iff this pack expansion is within a function context.  */
+/* True if this pack expansion is within a function context or
+   contract conditions.  */
 #define PACK_EXPANSION_LOCAL_P(NODE) \
   TREE_LANG_FLAG_0 (PACK_EXPANSION_CHECK (NODE))
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 54a33f0be94..4b4b0ac8dea 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4451,7 +4451,11 @@ make_pack_expansion (tree arg, tsubst_flags_t complain)
     }
   PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
 
-  PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p ();
+  /* Contract conditions are parsed outside a function body but function
+     parameter pack expansions in them must use the instantiated parameters
+     rather than dummy declarations.  */
+  PACK_EXPANSION_LOCAL_P (result)
+    = at_function_scope_p () || processing_contract_condition;
   if (ppd.found_extra_args_tree_p)
     /* If the pattern of this pack expansion contains a subtree that has
        the extra args mechanism for avoiding partial instantiation, then
diff --git a/gcc/testsuite/g++.dg/contracts/cpp26/pr125645.C b/gcc/testsuite/g++.dg/contracts/cpp26/pr125645.C
new file mode 100644
index 00000000000..ecc9cf853ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/cpp26/pr125645.C
@@ -0,0 +1,13 @@
+// PR c++/125645
+// { dg-do run { target c++26 } }
+// { dg-additional-options "-fcontracts -fcontract-evaluation-semantic=enforce" }
+// { dg-skip-if "requires hosted libstdc++ for stdc++exp" { ! hostedlib } }
+
+template<typename... Args>
+  void f (Args... args)
+    pre (((args) && ...))
+    post (((args) && ...)) {}
+
+int main () {
+  f<const bool> (true);
+}
-- 
2.52.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.