On 12/17/24 11:04 AM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk/14/13?
OK.
-- >8 --
Here during partial substitution of the requires-expression (as part of
CTAD constraint rewriting) we segfault from the INDIRECT_REF case of
convert_to_void due *f(u) being type-dependent. We should just defer
checking convert_to_void until satisfaction.
PR c++/118060
gcc/cp/ChangeLog:
* constraint.cc (tsubst_valid_expression_requirement): Don't
check convert_to_void during partial substitution.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-requires40.C: New test.
---
gcc/cp/constraint.cc | 4 +++-
gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C | 12 ++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c75982d8009..eb47862fda0 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1336,7 +1336,9 @@ tsubst_valid_expression_requirement (tree t, tree args,
sat_info info)
{
tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
tree r = tsubst_expr (t, args, quiet, info.in_decl);
- if (convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node)
+ if (r != error_mark_node
+ && (processing_template_decl
+ || convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node))
return r;
if (info.diagnose_unsatisfaction_p ())
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C
b/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C
new file mode 100644
index 00000000000..918bab410f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires40.C
@@ -0,0 +1,12 @@
+// PR c++/118060
+// { dg-do compile { target c++20 } }
+
+int* f(int);
+
+template<class T>
+struct A {
+ template<class U> requires requires (U u) { *f(u); }
+ A(T, U);
+};
+
+A a{0, 0};