c++: Fix mismatch in template argument deduction [PR90505] 2020-03-03 Jason Merrill <jason@redhat.com> Marek Polacek <polacek@redhat.com> PR c++/90505 - mismatch in template argument deduction. * pt.c (tsubst): Don't reduce the template level of template parameters when tf_partial. * g++.dg/template/deduce4.C: New test. * g++.dg/template/deduce5.C: New test. * g++.dg/template/deduce6.C: New test. * g++.dg/template/deduce7.C: New test.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 80fb96e..cb5211e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog
@@ -1,4 +1,11 @@ 2020-03-04 Jason Merrill <jason@redhat.com> + Marek Polacek <polacek@redhat.com> + + PR c++/90505 - mismatch in template argument deduction. + * pt.c (tsubst): Don't reduce the template level of template + parameters when tf_partial. + +2020-03-04 Jason Merrill <jason@redhat.com> PR c++/90432 * init.c (perform_member_init): Don't do aggregate initialization of
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f233e78..2de9036 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c
@@ -14630,6 +14630,11 @@ about the template parameter in question. */ return t; + /* Like with 'auto', don't reduce the level of template parameters + to avoid mismatches when deducing their types. */ + if (complain & tf_partial) + return t; + /* If we get here, we must have been looking at a parm for a more deeply nested template. Make a new version of this template parameter, but with a lower level. */
diff --git a/gcc/testsuite/g++.dg/template/deduce4.C b/gcc/testsuite/g++.dg/template/deduce4.C new file mode 100644 index 0000000..e2c165d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce4.C
@@ -0,0 +1,17 @@ +// PR c++/90505 - mismatch in template argument deduction. +// { dg-do compile } + +template <typename T> +struct S { + template <typename U, typename V> + static void foo(V) { } + + void bar () { foo<int>(10); } +}; + +void +test () +{ + S<int> s; + s.bar (); +}
diff --git a/gcc/testsuite/g++.dg/template/deduce5.C b/gcc/testsuite/g++.dg/template/deduce5.C new file mode 100644 index 0000000..9d382bf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce5.C
@@ -0,0 +1,17 @@ +// PR c++/90505 - mismatch in template argument deduction. +// { dg-do compile { target c++11 } } + +template <typename T> +struct S { + template <typename U, typename V = void> + static void foo(U) { } + + void bar () { foo<int>(10); } +}; + +void +test () +{ + S<int> s; + s.bar (); +}
diff --git a/gcc/testsuite/g++.dg/template/deduce6.C b/gcc/testsuite/g++.dg/template/deduce6.C new file mode 100644 index 0000000..8fee612 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce6.C
@@ -0,0 +1,17 @@ +// PR c++/90505 - mismatch in template argument deduction. +// { dg-do compile { target c++11 } } + +template <typename T> +struct S { + template <typename U = int, typename V> + static void foo(V) { } + + void bar () { foo<>(10); } +}; + +void +test () +{ + S<int> s; + s.bar (); +}
diff --git a/gcc/testsuite/g++.dg/template/deduce7.C b/gcc/testsuite/g++.dg/template/deduce7.C new file mode 100644 index 0000000..fbc28e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce7.C
@@ -0,0 +1,10 @@ +// PR c++/90505 - mismatch in template argument deduction. +// { dg-do compile { target c++11 } } + +template <typename> class a { + using b = int; + using c = int; + b d; + void e() { g<c>(d); } + template <typename... f> static void g(f...); +};