Message ID | 20211007133115.3705691-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: NTTP with array/function type after substitution [PR61355] | expand |
On 10/7/21 09:31, Patrick Palka wrote: > We're implementing [temp.param]/10 at parse time but not also at > substitution time. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? OK. > PR c++/61355 > > gcc/cp/ChangeLog: > > * pt.c (convert_template_argument): Perform array/function to > pointer conversion on the substituted type of an NTTP. > > gcc/testsuite/ChangeLog: > > * g++.old-deja/g++.pt/nontype5.C: > * g++.dg/template/param6.C: New test. > --- > gcc/cp/pt.c | 4 +++ > gcc/testsuite/g++.dg/template/param6.C | 32 ++++++++++++++++++++ > gcc/testsuite/g++.old-deja/g++.pt/nontype5.C | 2 +- > 3 files changed, 37 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/template/param6.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 5af3a6472f8..170edbd6f1e 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -8528,6 +8528,10 @@ convert_template_argument (tree parm, > else > t = tsubst (t, args, complain, in_decl); > > + /* Perform array-to-pointer and function-to-pointer conversion > + as per [temp.param]/10. */ > + t = type_decays_to (t); > + > if (invalid_nontype_parm_type_p (t, complain)) > return error_mark_node; > > diff --git a/gcc/testsuite/g++.dg/template/param6.C b/gcc/testsuite/g++.dg/template/param6.C > new file mode 100644 > index 00000000000..8306e753d70 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/param6.C > @@ -0,0 +1,32 @@ > +// PR c++/61355 > +// Verify we perform array-to-pointer and function-to-pointer conversion > +// on the substituted/deduced type of an NTTP. > + > +int f(); > +int p[5]; > + > +namespace cpp98 { > + template<class T, T> struct X; > + typedef X<int(), f> ty1; > + typedef X<int[5], p> ty2; > +} > + > +namespace cpp11 { > +#if __cpp_variadic_templates > + template<class T, T...> struct X; > + using ty1 = X<int(), f>; > + using ty2 = X<int[5], p>; > +#endif > +} > + > +namespace cpp17 { > +#if __cpp_nontype_template_parameter_auto > + template<decltype(auto)> struct X; > + using ty1 = X<f>; > + using ty2 = X<p>; > + > + template<decltype(auto)...> struct Y; > + using ty3 = Y<f>; > + using ty4 = Y<p>; > +#endif > +} > diff --git a/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C b/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C > index 2678cf78a7d..e24dca43622 100644 > --- a/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C > +++ b/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C > @@ -19,5 +19,5 @@ static int g() { return f(); } > int f() { return 0; } > > int main() { > -return B<int,&f>::g(); // { dg-error "" } could not convert arg > +return B<int,&f>::g(); > } >
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5af3a6472f8..170edbd6f1e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8528,6 +8528,10 @@ convert_template_argument (tree parm, else t = tsubst (t, args, complain, in_decl); + /* Perform array-to-pointer and function-to-pointer conversion + as per [temp.param]/10. */ + t = type_decays_to (t); + if (invalid_nontype_parm_type_p (t, complain)) return error_mark_node; diff --git a/gcc/testsuite/g++.dg/template/param6.C b/gcc/testsuite/g++.dg/template/param6.C new file mode 100644 index 00000000000..8306e753d70 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/param6.C @@ -0,0 +1,32 @@ +// PR c++/61355 +// Verify we perform array-to-pointer and function-to-pointer conversion +// on the substituted/deduced type of an NTTP. + +int f(); +int p[5]; + +namespace cpp98 { + template<class T, T> struct X; + typedef X<int(), f> ty1; + typedef X<int[5], p> ty2; +} + +namespace cpp11 { +#if __cpp_variadic_templates + template<class T, T...> struct X; + using ty1 = X<int(), f>; + using ty2 = X<int[5], p>; +#endif +} + +namespace cpp17 { +#if __cpp_nontype_template_parameter_auto + template<decltype(auto)> struct X; + using ty1 = X<f>; + using ty2 = X<p>; + + template<decltype(auto)...> struct Y; + using ty3 = Y<f>; + using ty4 = Y<p>; +#endif +} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C b/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C index 2678cf78a7d..e24dca43622 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C @@ -19,5 +19,5 @@ static int g() { return f(); } int f() { return 0; } int main() { -return B<int,&f>::g(); // { dg-error "" } could not convert arg +return B<int,&f>::g(); }