Here is a patch which conforms to the style requirements. On Thu, Aug 7, 2025 at 9:30 PM Ben Wu <soggysocks...@gmail.com> wrote: > > PR 120618 > > gcc/cp/ChangeLog: > > * constraint.cc (tsubst_compound_requirement): Return NULL_TREE when > t1 > is not a TEMPLATE_TYPE_PARM > (tsubst_requires_expr): Propagate failure when the compound > requirement has an ill-formed type-constraint > > gcc/testsuite/ChangeLog: > > * g++.dg/concepts/pr120618.C: New test. > > This testcase caused an ICE in mangle.cc when attempting to mangle the > compound requirement > `requires (!requires(T t) { { t } -> bool; })`, since > write_type_constraint expects a TEMPLATE_TYPE_PARM. > > When instantiating the call `foo(b)`, the constraint `requires(T t) { > { t } -> bool; }` seems to be > cached as a boolean_false_node, so the constraints were met due to the > TRUTH_NOT_EXPR even though > the type-constraint was invalid. This was Andrew's hypothesis which we > discussed on irc, and it seems to be correct from what I > tried to do here. > > This patch attempts to bail out when building a call for a function > with an ill-formed type-constraint in a > compound requirement. > > Bootstrapped and tested with check-gcc-c++ on x86_64-linux-gnu (I did > not see new regressions with compare_tests). Could someone help > review? > > Thanks. > > Suggested-by: Andrew Pinski <quic_apin...@quicinc.com> > > --- > gcc/cp/constraint.cc | 8 ++++++++ > gcc/testsuite/g++.dg/concepts/pr120618.C | 13 +++++++++++++ > 2 files changed, 21 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/concepts/pr120618.C > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index cbdfafc90c0..a9f6bcc9c69 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -1478,6 +1478,9 @@ tsubst_compound_requirement (tree t, tree args, > sat_info info) > { > tree t0 = TREE_OPERAND (t, 0); > tree t1 = TREE_OPERAND (t, 1); > + if (t1 && TREE_CODE (t1) != TEMPLATE_TYPE_PARM) > + return NULL_TREE; > + > tree expr = tsubst_valid_expression_requirement (t0, args, info); > if (expr == error_mark_node) > return error_mark_node; > @@ -1744,6 +1747,11 @@ tsubst_requires_expr (tree t, tree args, sat_info info) > else > break; > } > + else if (req == NULL_TREE) > + { > + result = error_mark_node; > + break; > + } > else if (processing_template_decl) > result = tree_cons (NULL_TREE, req, result); > } > diff --git a/gcc/testsuite/g++.dg/concepts/pr120618.C > b/gcc/testsuite/g++.dg/concepts/pr120618.C > new file mode 100644 > index 00000000000..13f390a7aa0 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/concepts/pr120618.C > @@ -0,0 +1,13 @@ > +// { dg-do compile { target c++17 } } > +// { dg-options "-fconcepts" } > + > +class B{}; > + > +template <typename T> > +requires (!requires(T t) { { t } -> bool; }) // { dg-error > "return-type-requirement is not a type-constraint" } > +void foo(T t) {} > + > +int main() { > + B b; > + foo(b); // { dg-error "no matching function" } > +} > -- > 2.43.0
From 60bacf53fe23bd5da7fea98610ebe15f42e4181a Mon Sep 17 00:00:00 2001 From: benwu25 <soggysocks...@gmail.com> Date: Fri, 8 Aug 2025 00:07:29 -0700 Subject: [PATCH] c++: fix ICE on function call with ill-formed compound requirement [PR120618]
PR 120618 gcc/cp/ChangeLog: * constraint.cc (tsubst_compound_requirement): Return NULL_TREE when t1 is not a TEMPLATE_TYPE_PARM (tsubst_requires_expr): Propagate failure when the compound requirement has an ill-formed type-constraint gcc/testsuite/ChangeLog: * g++.dg/concepts/pr120618.C: New test. This testcase caused an ICE in mangle.cc when attempting to mangle the compound requirement `requires (!requires(T t) { { t } -> bool; })`, since write_type_constraint expects a TEMPLATE_TYPE_PARM. When instantiating the call `foo(b)`, the constraint `requires(T t) { { t } -> bool; }` seems to be cached as a boolean_false_node, so the constraints were met due to the TRUTH_NOT_EXPR even though the type-constraint was invalid. This was Andrew's hypothesis which we discussed on irc, and it seems to be correct from what I tried to do here. This patch attempts to bail out when building a call for a function with an ill-formed type-constraint in a compound requirement. Bootstrapped and tested with check-gcc-c++ on x86_64-linux-gnu (I did not see new regressions with compare_tests). Could someone help review? Thanks. Suggested-by: Andrew Pinski <quic_apin...@quicinc.com> --- gcc/cp/constraint.cc | 8 ++++++++ gcc/testsuite/g++.dg/concepts/pr120618.C | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/g++.dg/concepts/pr120618.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index cbdfafc90c0..e360323112f 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1478,6 +1478,9 @@ tsubst_compound_requirement (tree t, tree args, sat_info info) { tree t0 = TREE_OPERAND (t, 0); tree t1 = TREE_OPERAND (t, 1); + if (t1 && TREE_CODE (t1) != TEMPLATE_TYPE_PARM) + return NULL_TREE; + tree expr = tsubst_valid_expression_requirement (t0, args, info); if (expr == error_mark_node) return error_mark_node; @@ -1744,6 +1747,11 @@ tsubst_requires_expr (tree t, tree args, sat_info info) else break; } + else if (req == NULL_TREE) + { + result = error_mark_node; + break; + } else if (processing_template_decl) result = tree_cons (NULL_TREE, req, result); } diff --git a/gcc/testsuite/g++.dg/concepts/pr120618.C b/gcc/testsuite/g++.dg/concepts/pr120618.C new file mode 100644 index 00000000000..cff79b4ba49 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr120618.C @@ -0,0 +1,13 @@ +// { dg-do compile { target c++17 } } +// { dg-options "-fconcepts" } + +class B{}; + +template <typename T> +requires (!requires(T t) { { t } -> bool; }) // { dg-error "return-type-requirement is not a type-constraint" } +void foo(T t) {} + +int main() { + B b; + foo(b); // { dg-error "no matching function" } +} -- 2.43.0