diff mbox series

[v4] c++: fix constained auto deduction in templ spec scopes [PR114915]

Message ID 20240515172736.1844782-1-sska1377@gmail.com
State New
Headers show
Series [v4] c++: fix constained auto deduction in templ spec scopes [PR114915] | expand

Commit Message

Seyed Sajad Kahani May 15, 2024, 5:27 p.m. UTC
This patch resolves PR114915 by replacing the logic that fills in the
missing levels in do_auto_deduction in cp/pt.cc.
The new approach now trims targs if the depth of targs is deeper than desired
(this will only happen in specific contexts), and still fills targs with empty
layers if it has fewer depths than expected.

PR c++/114915

gcc/cp/ChangeLog:

	* pt.cc (do_auto_deduction): Handle excess outer template
arguments during constrained auto satisfaction.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/concepts-placeholder14.C: New test.
	* g++.dg/cpp2a/concepts-placeholder15.C: New test.
	* g++.dg/cpp2a/concepts-placeholder16.C: New test.
---
 gcc/cp/pt.cc                                  | 20 ++++++++---
 .../g++.dg/cpp2a/concepts-placeholder14.C     | 19 +++++++++++
 .../g++.dg/cpp2a/concepts-placeholder15.C     | 15 +++++++++
 .../g++.dg/cpp2a/concepts-placeholder16.C     | 33 +++++++++++++++++++
 4 files changed, 83 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C

Comments

Jason Merrill May 22, 2024, 8:30 p.m. UTC | #1
OK, on the right patch this time I hope.

Looks like you still need either FSF copyright assignment or DCO 
certification per https://gcc.gnu.org/contribute.html#legal

On 5/15/24 13:27, Seyed Sajad Kahani wrote:
> This patch resolves PR114915 by replacing the logic that fills in the
> missing levels in do_auto_deduction in cp/pt.cc.

I miss the text in your original patch that explained the problem more.

> The new approach now trims targs if the depth of targs is deeper than desired
> (this will only happen in specific contexts), and still fills targs with empty
> layers if it has fewer depths than expected.
> 
> PR c++/114915

This line needs to start with a tab.

> gcc/cp/ChangeLog:
> 
> 	* pt.cc (do_auto_deduction): Handle excess outer template
> arguments during constrained auto satisfaction.

This one, too.  These issues are flagged by git gcc-verify, and are 
easier to avoid with git gcc-commit-mklog.

> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp2a/concepts-placeholder14.C: New test.
> 	* g++.dg/cpp2a/concepts-placeholder15.C: New test.

This test still needs a variable template partial specialization.

A few coding style nits below.

> 	* g++.dg/cpp2a/concepts-placeholder16.C: New test.
> ---
>   gcc/cp/pt.cc                                  | 20 ++++++++---
>   .../g++.dg/cpp2a/concepts-placeholder14.C     | 19 +++++++++++
>   .../g++.dg/cpp2a/concepts-placeholder15.C     | 15 +++++++++
>   .../g++.dg/cpp2a/concepts-placeholder16.C     | 33 +++++++++++++++++++
>   4 files changed, 83 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C
> 
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 32640f8e9..ecfda67aa 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -31253,6 +31253,19 @@ do_auto_deduction (tree type, tree init, tree auto_node,
>   	full_targs = add_outermost_template_args (tmpl, full_targs);
>         full_targs = add_to_template_args (full_targs, targs);
>   
> +      int want = TEMPLATE_TYPE_ORIG_LEVEL (auto_node);
> +      int have = TMPL_ARGS_DEPTH (full_targs);
> +
> +      if (want < have)
> +	{
> +	  // if a constrained auto is declared in an explicit specialization

We generally use C-style /* */ comments, that start with a capital 
letter and end with a period.

> +	  gcc_assert (context == adc_variable_type || context == adc_return_type
> +			  || context == adc_decomp_type);

The || should line up with the 'c' on the previous line.

> +	  tree trimmed_full_args = get_innermost_template_args
> +	    (full_targs, want);

We try to avoid having arguments to the left of the function name; here 
I'd start the new line with the = instead.

> +	  full_targs = trimmed_full_args;
> +	}
> +

Unnecessary tab on this line.

>         /* HACK: Compensate for callers not always communicating all levels of
>   	 outer template arguments by filling in the outermost missing levels
>   	 with dummy levels before checking satisfaction.  We'll still crash
> @@ -31260,11 +31273,10 @@ do_auto_deduction (tree type, tree init, tree auto_node,
>   	 these missing levels, but this hack otherwise allows us to handle a
>   	 large subset of possible constraints (including all non-dependent
>   	 constraints).  */
> -      if (int missing_levels = (TEMPLATE_TYPE_ORIG_LEVEL (auto_node)
> -				- TMPL_ARGS_DEPTH (full_targs)))
> +      if (want > have)
>   	{
> -	  tree dummy_levels = make_tree_vec (missing_levels);
> -	  for (int i = 0; i < missing_levels; ++i)
> +	  tree dummy_levels = make_tree_vec (want - have);
> +	  for (int i = 0; i < want - have; ++i)
>   	    TREE_VEC_ELT (dummy_levels, i) = make_tree_vec (0);
>   	  full_targs = add_to_template_args (dummy_levels, full_targs);
>   	}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C
> new file mode 100644
> index 000000000..fcdbd7608
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C
> @@ -0,0 +1,19 @@
> +// PR c++/114915
> +// { dg-do compile { target c++20 } }
> +
> +template<typename T>
> +concept C = __is_same(T, int);
> +
> +template<typename T>
> +void f() {
> +}
> +
> +template<>
> +void f<int>() {
> +  C auto x = 1;
> +}
> +
> +int main() {
> +  f<int>();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C
> new file mode 100644
> index 000000000..b4f73f407
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C
> @@ -0,0 +1,15 @@
> +// PR c++/114915
> +// { dg-do compile { target c++20 } }
> +
> +template<typename T, typename U>
> +concept C = __is_same(T, U);
> +
> +template<typename T>
> +int x = 0;
> +
> +template<>
> +C<double> auto x<double> = 1.0;
> +
> +int main() {
> +  return 0;
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C
> new file mode 100644
> index 000000000..f808ef1b6
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C
> @@ -0,0 +1,33 @@
> +// PR c++/114915
> +// { dg-do compile { target c++20 } }
> +
> +template<typename T, typename U>
> +concept C = __is_same(T, U);
> +
> +template<typename T>
> +struct A
> +{
> +    template<typename U>
> +    void f() {
> +    }
> +};
> +
> +template<>
> +template<>
> +void A<int>::f<int>() {
> +  C<int> auto x = 1;
> +}
> +
> +template<>
> +template<typename U>
> +void A<bool>::f() {
> +  C<int> auto x = 1;
> +}
> +
> +int main() {
> +  A<bool> a;
> +  a.f<char>();
> +  A<int> b;
> +  b.f<int>();
> +  return 0;
> +}
diff mbox series

Patch

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 32640f8e9..ecfda67aa 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31253,6 +31253,19 @@  do_auto_deduction (tree type, tree init, tree auto_node,
 	full_targs = add_outermost_template_args (tmpl, full_targs);
       full_targs = add_to_template_args (full_targs, targs);
 
+      int want = TEMPLATE_TYPE_ORIG_LEVEL (auto_node);
+      int have = TMPL_ARGS_DEPTH (full_targs);
+
+      if (want < have)
+	{
+	  // if a constrained auto is declared in an explicit specialization
+	  gcc_assert (context == adc_variable_type || context == adc_return_type
+			  || context == adc_decomp_type);
+	  tree trimmed_full_args = get_innermost_template_args
+	    (full_targs, want);
+	  full_targs = trimmed_full_args;
+	}
+      
       /* HACK: Compensate for callers not always communicating all levels of
 	 outer template arguments by filling in the outermost missing levels
 	 with dummy levels before checking satisfaction.  We'll still crash
@@ -31260,11 +31273,10 @@  do_auto_deduction (tree type, tree init, tree auto_node,
 	 these missing levels, but this hack otherwise allows us to handle a
 	 large subset of possible constraints (including all non-dependent
 	 constraints).  */
-      if (int missing_levels = (TEMPLATE_TYPE_ORIG_LEVEL (auto_node)
-				- TMPL_ARGS_DEPTH (full_targs)))
+      if (want > have)
 	{
-	  tree dummy_levels = make_tree_vec (missing_levels);
-	  for (int i = 0; i < missing_levels; ++i)
+	  tree dummy_levels = make_tree_vec (want - have);
+	  for (int i = 0; i < want - have; ++i)
 	    TREE_VEC_ELT (dummy_levels, i) = make_tree_vec (0);
 	  full_targs = add_to_template_args (dummy_levels, full_targs);
 	}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C
new file mode 100644
index 000000000..fcdbd7608
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C
@@ -0,0 +1,19 @@ 
+// PR c++/114915
+// { dg-do compile { target c++20 } }
+
+template<typename T>
+concept C = __is_same(T, int);
+
+template<typename T>
+void f() {
+}
+
+template<>
+void f<int>() {
+  C auto x = 1;
+}
+
+int main() {
+  f<int>();
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C
new file mode 100644
index 000000000..b4f73f407
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C
@@ -0,0 +1,15 @@ 
+// PR c++/114915
+// { dg-do compile { target c++20 } }
+
+template<typename T, typename U>
+concept C = __is_same(T, U);
+
+template<typename T>
+int x = 0;
+
+template<>
+C<double> auto x<double> = 1.0;
+
+int main() {
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C
new file mode 100644
index 000000000..f808ef1b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C
@@ -0,0 +1,33 @@ 
+// PR c++/114915
+// { dg-do compile { target c++20 } }
+
+template<typename T, typename U>
+concept C = __is_same(T, U);
+
+template<typename T>
+struct A
+{ 
+    template<typename U>
+    void f() {
+    }
+};
+ 
+template<>
+template<>
+void A<int>::f<int>() {
+  C<int> auto x = 1;
+}
+
+template<>
+template<typename U>
+void A<bool>::f() {
+  C<int> auto x = 1;
+}
+
+int main() {
+  A<bool> a;
+  a.f<char>();
+  A<int> b;
+  b.f<int>();
+  return 0;
+}