diff mbox series

c++: Backport PR90505 fix to 9

Message ID 20200304210222.GI3554@redhat.com
State New
Headers show
Series c++: Backport PR90505 fix to 9 | expand

Commit Message

Marek Polacek March 4, 2020, 9:02 p.m. UTC
While backporting our 90505 fix to 9 I noticed a bunch of concepts regressions.
Fortunately I think the following variant of the fix is safe and still fixes
the deduction issue.  In 9, we want to reject 'auto' when tf_partial before
returning cp_build_qualified_type_real for TEMPLATE_TYPE_PARM and similar.
And then to fix 90505, return early before reducing the template level.

The difference is caused by the huge concepts merge, so it's tough to figure
out what specific change caused it.

Bootstrapped/regtested on x86_64-linux, ok for 9?

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.

	* 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.

Comments

Jason Merrill March 4, 2020, 10:23 p.m. UTC | #1
On 3/4/20 4:02 PM, Marek Polacek wrote:
> While backporting our 90505 fix to 9 I noticed a bunch of concepts regressions.
> Fortunately I think the following variant of the fix is safe and still fixes
> the deduction issue.  In 9, we want to reject 'auto' when tf_partial before
> returning cp_build_qualified_type_real for TEMPLATE_TYPE_PARM and similar.
> And then to fix 90505, return early before reducing the template level.
> 
> The difference is caused by the huge concepts merge, so it's tough to figure
> out what specific change caused it.
> 
> Bootstrapped/regtested on x86_64-linux, ok for 9?

OK.

> 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.
> 
> 	* 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/pt.c b/gcc/cp/pt.c
> index f233e78cc45..2de9036b647 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -14630,6 +14630,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
>   	     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 00000000000..e2c165dc788
> --- /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 00000000000..9d382bfe03a
> --- /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 00000000000..8fee6124f5a
> --- /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 00000000000..fbc28e5150d
> --- /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...);
> +};
>
diff mbox series

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f233e78cc45..2de9036b647 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14630,6 +14630,11 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	     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 00000000000..e2c165dc788
--- /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 00000000000..9d382bfe03a
--- /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 00000000000..8fee6124f5a
--- /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 00000000000..fbc28e5150d
--- /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...);
+};