Message ID | 20231114210445.1469279-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: partially inst requires-expr in noexcept-spec [PR101043] | expand |
On 11/14/23 16:04, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? OK. > -- >8 -- > > Here we're ICEing from strip_typedefs for the partially instantiated > requires-expression when walking its REQUIRES_EXPR_EXTRA_ARGS since it's > a TREE_LIST with non-empty TREE_PURPOSE (to hold the captured local > specialization 't' as per build_extra_args) which strip_typedefs doesn't > expect. > > We can probably skip walking REQUIRES_EXPR_EXTRA_ARGS at all since it > shouldn't contain any typedefs in the first place, but it seems safer > and more generally useful to just teach strip_typedefs to handle non-empty > TREE_PURPOSE the obvious way. (The handling asserted TREE_PURPOSE was > empty ever since inception i.e. r189298.) > > PR c++/101043 > > gcc/cp/ChangeLog: > > * tree.cc (strip_typedefs_expr) <case TREE_LIST>: Handle > non-empty TREE_PURPOSE. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-requires37.C: New test. > --- > gcc/cp/tree.cc | 19 ++++++++++++------- > .../g++.dg/cpp2a/concepts-requires37.C | 11 +++++++++++ > 2 files changed, 23 insertions(+), 7 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C > > diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc > index dc4126f935c..0736e8d8f48 100644 > --- a/gcc/cp/tree.cc > +++ b/gcc/cp/tree.cc > @@ -1911,19 +1911,24 @@ strip_typedefs_expr (tree t, bool *remove_attributes, unsigned int flags) > case TREE_LIST: > { > bool changed = false; > - releasing_vec vec; > + auto_vec<tree_pair, 4> vec; > r = t; > for (; t; t = TREE_CHAIN (t)) > { > - gcc_assert (!TREE_PURPOSE (t)); > - tree elt = strip_typedefs (TREE_VALUE (t), > - remove_attributes, flags); > - if (elt != TREE_VALUE (t)) > + tree purpose = strip_typedefs (TREE_PURPOSE (t), > + remove_attributes, flags); > + tree value = strip_typedefs (TREE_VALUE (t), > + remove_attributes, flags); > + if (purpose != TREE_PURPOSE (t) || value != TREE_VALUE (t)) > changed = true; > - vec_safe_push (vec, elt); > + vec.safe_push ({purpose, value}); > } > if (changed) > - r = build_tree_list_vec (vec); > + { > + r = NULL_TREE; > + for (int i = vec.length () - 1; i >= 0; i--) > + r = tree_cons (vec[i].first, vec[i].second, r); > + } > return r; > } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C > new file mode 100644 > index 00000000000..72dad77fea1 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C > @@ -0,0 +1,11 @@ > +// PR c++/101043 > +// { dg-do compile { target c++20 } } > + > +template<class T> > +void f(T t) { > + [&](auto) noexcept(requires { { t.g() }; }) { }(0); > +} > + > +int main() { > + f(0); > +}
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index dc4126f935c..0736e8d8f48 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -1911,19 +1911,24 @@ strip_typedefs_expr (tree t, bool *remove_attributes, unsigned int flags) case TREE_LIST: { bool changed = false; - releasing_vec vec; + auto_vec<tree_pair, 4> vec; r = t; for (; t; t = TREE_CHAIN (t)) { - gcc_assert (!TREE_PURPOSE (t)); - tree elt = strip_typedefs (TREE_VALUE (t), - remove_attributes, flags); - if (elt != TREE_VALUE (t)) + tree purpose = strip_typedefs (TREE_PURPOSE (t), + remove_attributes, flags); + tree value = strip_typedefs (TREE_VALUE (t), + remove_attributes, flags); + if (purpose != TREE_PURPOSE (t) || value != TREE_VALUE (t)) changed = true; - vec_safe_push (vec, elt); + vec.safe_push ({purpose, value}); } if (changed) - r = build_tree_list_vec (vec); + { + r = NULL_TREE; + for (int i = vec.length () - 1; i >= 0; i--) + r = tree_cons (vec[i].first, vec[i].second, r); + } return r; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C new file mode 100644 index 00000000000..72dad77fea1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires37.C @@ -0,0 +1,11 @@ +// PR c++/101043 +// { dg-do compile { target c++20 } } + +template<class T> +void f(T t) { + [&](auto) noexcept(requires { { t.g() }; }) { }(0); +} + +int main() { + f(0); +}