On Wed, Dec 1, 2021 at 10:26 AM Marek Polacek via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Here we ICE on > > int f() requires (auto(0)); > > in do_auto_deduction when handling the auto: we're in a non-templated > requires-expression which are parsed under processing_template_decl == 1 > and empty current_template_parms, so 'current_template_args ()' will > crash. This code is invalid as per "C++20 CA378: Remove non-templated > constrained functions", but of course we shouldn't crash.
FWIW it looks like we can trip over the same bug with valid code: static_assert(requires { auto(0); }); > > Since in the scenario above it's expected that current_template_parms is > null, I've just added a check, and let grokfndecl issue an error. > I guess another approch would be to fake up a template parameter list > before calling do_auto_deduction. > > For good measure, I've added several well-formed cases with auto(x) in > a requires-expression. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > PR c++/103408 > > gcc/cp/ChangeLog: > > * pt.c (do_auto_deduction): Check current_template_parms before > current_template_args (). > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp23/auto-fncast9.C: New test. > --- > gcc/cp/pt.c | 2 +- > gcc/testsuite/g++.dg/cpp23/auto-fncast9.C | 27 +++++++++++++++++++++++ > 2 files changed, 28 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-fncast9.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index f4b9d9673fb..012ca5d06c0 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -30041,7 +30041,7 @@ do_auto_deduction (tree type, tree init, tree > auto_node, > (but we still may have used them for constraint checking above). */; > else if (context == adc_unify) > targs = add_to_template_args (outer_targs, targs); > - else if (processing_template_decl) > + else if (processing_template_decl && current_template_parms) > targs = add_to_template_args (current_template_args (), targs); > return tsubst (type, targs, complain, NULL_TREE); Won't this mean the call to tsubst here will end up lowering the level of the auto from 2 to 1 rather than replacing it with the actual deduced type? It also looks like this approach doesn't handle static_assert(requires { auto(auto(0)); }), probably due to this substitution issue. I guess we could add a dummy level to 'targs' to work around this.. > } > diff --git a/gcc/testsuite/g++.dg/cpp23/auto-fncast9.C > b/gcc/testsuite/g++.dg/cpp23/auto-fncast9.C > new file mode 100644 > index 00000000000..45a0ff9b460 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp23/auto-fncast9.C > @@ -0,0 +1,27 @@ > +// PR c++/103408 > +// { dg-do compile { target c++23 } } > + > +int bad1() requires (auto(true)); // { dg-error "constraints on a > non-templated function" } > + > +template<bool B> > +int f1() requires (auto(B)); > + > +template<typename T> > +struct S { T t; constexpr operator bool() { return true; } }; > + > +int bad2() requires (bool(S{1})); // { dg-error "constraints on a > non-templated function" } > +int bad3() requires (bool(S(1))); // { dg-error "constraints on a > non-templated function" } > + > +template<int N> > +int f2() requires (bool(S{N})); > + > +template<int N> > +int f3() requires (bool(S(N))); > + > +void > +g () > +{ > + f1<true>(); > + f2<42>(); > + f3<42>(); > +} > > base-commit: 6b8ecbc6d6652d061d7c72c64352d51eca2df6ca > -- > 2.33.1 >