diff mbox series

c++: missing SFINAE during alias CTAD [PR115296]

Message ID 20240705174959.2440677-1-ppalka@redhat.com
State New
Headers show
Series c++: missing SFINAE during alias CTAD [PR115296] | expand

Commit Message

Patrick Palka July 5, 2024, 5:49 p.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/14?

-- >8 --

During the alias CTAD transformation, if substitution failed for some
guide we should just discard the guide silently.  We currently do
discard the guide, but not silently, which causes us to reject the
below testcase due to forming a too-large array type when transforming
the user-defined deduction guides.

This patch fixes this by passing complain=tf_none instead of
=tf_warning_or_error in the couple of spots where we expect subsitution
to possibly fail and so subsequently check for error_mark_node.

	PR c++/115296

gcc/cp/ChangeLog:

	* pt.cc (alias_ctad_tweaks): Pass complain=tf_none to
	tsubst_decl and tsubst_constraint_info.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/class-deduction-alias23.C: New test.
---
 gcc/cp/pt.cc                                  |  4 ++--
 .../g++.dg/cpp2a/class-deduction-alias23.C    | 20 +++++++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C

Comments

Patrick Palka July 19, 2024, 2:55 p.m. UTC | #1
On Fri, Jul 5, 2024 at 1:50 PM Patrick Palka <ppalka@redhat.com> wrote:
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> OK for trunk/14?
>
> -- >8 --
>
> During the alias CTAD transformation, if substitution failed for some
> guide we should just discard the guide silently.  We currently do
> discard the guide, but not silently, which causes us to reject the
> below testcase due to forming a too-large array type when transforming
> the user-defined deduction guides.
>
> This patch fixes this by passing complain=tf_none instead of
> =tf_warning_or_error in the couple of spots where we expect subsitution
> to possibly fail and so subsequently check for error_mark_node.

Ping.  Alternatively we could set complain=tf_none everywhere.

>
>         PR c++/115296
>
> gcc/cp/ChangeLog:
>
>         * pt.cc (alias_ctad_tweaks): Pass complain=tf_none to
>         tsubst_decl and tsubst_constraint_info.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/cpp2a/class-deduction-alias23.C: New test.
> ---
>  gcc/cp/pt.cc                                  |  4 ++--
>  .../g++.dg/cpp2a/class-deduction-alias23.C    | 20 +++++++++++++++++++
>  2 files changed, 22 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
>
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index d1316483e24..a382dce8788 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -30451,7 +30451,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
>               /* Parms are to have DECL_CHAIN tsubsted, which would be skipped
>                  if cp_unevaluated_operand.  */
>               cp_evaluated ev;
> -             g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, complain,
> +             g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, tf_none,
>                                /*use_spec_table=*/false);
>             }
>           if (g == error_mark_node)
> @@ -30478,7 +30478,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
>             {
>               if (tree outer_targs = outer_template_args (f))
>                 ci = tsubst_constraint_info (ci, outer_targs, complain, in_decl);
> -             ci = tsubst_constraint_info (ci, targs, complain, in_decl);
> +             ci = tsubst_constraint_info (ci, targs, tf_none, in_decl);
>             }
>           if (ci == error_mark_node)
>             continue;
> diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
> new file mode 100644
> index 00000000000..e5766586761
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
> @@ -0,0 +1,20 @@
> +// PR c++/115296
> +// { dg-do compile { target c++20 } }
> +
> +using size_t = decltype(sizeof(0));
> +
> +template<class T, size_t N = -1ULL>
> +struct span { span(T); };
> +
> +template<class T, size_t N>
> +span(T(&)[N]) -> span<T, N>; // { dg-bogus "array exceeds maximum" }
> +
> +template<class T, size_t N>
> +requires (sizeof(T(&)[N]) != 42) // { dg-bogus "array exceeds maximum" }
> +span(T*) -> span<T, N>;
> +
> +template<class T>
> +using array_view = span<T>;
> +
> +span x = 0;
> +array_view y = 0;
> --
> 2.45.2.746.g06e570c0df
>
Jason Merrill July 19, 2024, 4:06 p.m. UTC | #2
On 7/19/24 10:55 AM, Patrick Palka wrote:
> On Fri, Jul 5, 2024 at 1:50 PM Patrick Palka <ppalka@redhat.com> wrote:
>>
>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
>> OK for trunk/14?
>>
>> -- >8 --
>>
>> During the alias CTAD transformation, if substitution failed for some
>> guide we should just discard the guide silently.  We currently do
>> discard the guide, but not silently, which causes us to reject the
>> below testcase due to forming a too-large array type when transforming
>> the user-defined deduction guides.
>>
>> This patch fixes this by passing complain=tf_none instead of
>> =tf_warning_or_error in the couple of spots where we expect subsitution
>> to possibly fail and so subsequently check for error_mark_node.
> 
> Ping.  Alternatively we could set complain=tf_none everywhere.

That sounds better, unless you think there's a reason to have different 
complain args for different calls.

Jason
Patrick Palka July 19, 2024, 4:24 p.m. UTC | #3
On Fri, 19 Jul 2024, Jason Merrill wrote:

> On 7/19/24 10:55 AM, Patrick Palka wrote:
> > On Fri, Jul 5, 2024 at 1:50 PM Patrick Palka <ppalka@redhat.com> wrote:
> > > 
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> > > OK for trunk/14?
> > > 
> > > -- >8 --
> > > 
> > > During the alias CTAD transformation, if substitution failed for some
> > > guide we should just discard the guide silently.  We currently do
> > > discard the guide, but not silently, which causes us to reject the
> > > below testcase due to forming a too-large array type when transforming
> > > the user-defined deduction guides.
> > > 
> > > This patch fixes this by passing complain=tf_none instead of
> > > =tf_warning_or_error in the couple of spots where we expect subsitution
> > > to possibly fail and so subsequently check for error_mark_node.
> > 
> > Ping.  Alternatively we could set complain=tf_none everywhere.
> 
> That sounds better, unless you think there's a reason to have different
> complain args for different calls.

I was initially worried about a stray error_mark_node silently leaking
into the rewritten guide signature (since we don't check for
error_mark_node after each substitution) but on second thought that
seems unlikely.  The substitution steps in alias_ctad_tweaks  that
aren't checked should probably never fail, since they're just reindexing
template parameters etc.

So like so?

-- >8 --

Subject: [PATCH] c++: missing SFINAE during alias CTAD [PR115296]

	PR c++/115296

gcc/cp/ChangeLog:

	* pt.cc (alias_ctad_tweaks): Use complain=tf_none
	instead of tf_warning_or_error.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/class-deduction-alias23.C: New test.
---
 gcc/cp/pt.cc                                  |  2 +-
 .../g++.dg/cpp2a/class-deduction-alias23.C    | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 45453c0d45a..8e9951a9066 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -30298,7 +30298,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
 			  (INNERMOST_TEMPLATE_PARMS (fullatparms)));
     }
 
-  tsubst_flags_t complain = tf_warning_or_error;
+  tsubst_flags_t complain = tf_none;
   tree aguides = NULL_TREE;
   tree atparms = INNERMOST_TEMPLATE_PARMS (fullatparms);
   unsigned natparms = TREE_VEC_LENGTH (atparms);
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
new file mode 100644
index 00000000000..117212c67de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
@@ -0,0 +1,19 @@
+// PR c++/115296
+// { dg-do compile { target c++20 } }
+
+using size_t = decltype(sizeof(0));
+
+template<class T, size_t N = size_t(-1)>
+struct span { span(T); };
+
+template<class T, size_t N>
+span(T(&)[N]) -> span<T, N>; // { dg-bogus "array exceeds maximum" }
+
+template<class T, size_t N>
+requires (sizeof(T[N]) != 42) // { dg-bogus "array exceeds maximum" }
+span(T*) -> span<T, N>;
+
+template<class T>
+using array_view = span<T>;
+
+array_view x = 0;
Jason Merrill July 23, 2024, 12:27 p.m. UTC | #4
On 7/19/24 12:24 PM, Patrick Palka wrote:
> On Fri, 19 Jul 2024, Jason Merrill wrote:
> 
>> On 7/19/24 10:55 AM, Patrick Palka wrote:
>>> On Fri, Jul 5, 2024 at 1:50 PM Patrick Palka <ppalka@redhat.com> wrote:
>>>>
>>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
>>>> OK for trunk/14?
>>>>
>>>> -- >8 --
>>>>
>>>> During the alias CTAD transformation, if substitution failed for some
>>>> guide we should just discard the guide silently.  We currently do
>>>> discard the guide, but not silently, which causes us to reject the
>>>> below testcase due to forming a too-large array type when transforming
>>>> the user-defined deduction guides.
>>>>
>>>> This patch fixes this by passing complain=tf_none instead of
>>>> =tf_warning_or_error in the couple of spots where we expect subsitution
>>>> to possibly fail and so subsequently check for error_mark_node.
>>>
>>> Ping.  Alternatively we could set complain=tf_none everywhere.
>>
>> That sounds better, unless you think there's a reason to have different
>> complain args for different calls.
> 
> I was initially worried about a stray error_mark_node silently leaking
> into the rewritten guide signature (since we don't check for
> error_mark_node after each substitution) but on second thought that
> seems unlikely.  The substitution steps in alias_ctad_tweaks  that
> aren't checked should probably never fail, since they're just reindexing
> template parameters etc.
> 
> So like so?

OK.

> -- >8 --
> 
> Subject: [PATCH] c++: missing SFINAE during alias CTAD [PR115296]
> 
> 	PR c++/115296
> 
> gcc/cp/ChangeLog:
> 
> 	* pt.cc (alias_ctad_tweaks): Use complain=tf_none
> 	instead of tf_warning_or_error.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp2a/class-deduction-alias23.C: New test.
> ---
>   gcc/cp/pt.cc                                  |  2 +-
>   .../g++.dg/cpp2a/class-deduction-alias23.C    | 19 +++++++++++++++++++
>   2 files changed, 20 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
> 
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 45453c0d45a..8e9951a9066 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -30298,7 +30298,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
>   			  (INNERMOST_TEMPLATE_PARMS (fullatparms)));
>       }
>   
> -  tsubst_flags_t complain = tf_warning_or_error;
> +  tsubst_flags_t complain = tf_none;
>     tree aguides = NULL_TREE;
>     tree atparms = INNERMOST_TEMPLATE_PARMS (fullatparms);
>     unsigned natparms = TREE_VEC_LENGTH (atparms);
> diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
> new file mode 100644
> index 00000000000..117212c67de
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
> @@ -0,0 +1,19 @@
> +// PR c++/115296
> +// { dg-do compile { target c++20 } }
> +
> +using size_t = decltype(sizeof(0));
> +
> +template<class T, size_t N = size_t(-1)>
> +struct span { span(T); };
> +
> +template<class T, size_t N>
> +span(T(&)[N]) -> span<T, N>; // { dg-bogus "array exceeds maximum" }
> +
> +template<class T, size_t N>
> +requires (sizeof(T[N]) != 42) // { dg-bogus "array exceeds maximum" }
> +span(T*) -> span<T, N>;
> +
> +template<class T>
> +using array_view = span<T>;
> +
> +array_view x = 0;
diff mbox series

Patch

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index d1316483e24..a382dce8788 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -30451,7 +30451,7 @@  alias_ctad_tweaks (tree tmpl, tree uguides)
 	      /* Parms are to have DECL_CHAIN tsubsted, which would be skipped
 		 if cp_unevaluated_operand.  */
 	      cp_evaluated ev;
-	      g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, complain,
+	      g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, tf_none,
 			       /*use_spec_table=*/false);
 	    }
 	  if (g == error_mark_node)
@@ -30478,7 +30478,7 @@  alias_ctad_tweaks (tree tmpl, tree uguides)
 	    {
 	      if (tree outer_targs = outer_template_args (f))
 		ci = tsubst_constraint_info (ci, outer_targs, complain, in_decl);
-	      ci = tsubst_constraint_info (ci, targs, complain, in_decl);
+	      ci = tsubst_constraint_info (ci, targs, tf_none, in_decl);
 	    }
 	  if (ci == error_mark_node)
 	    continue;
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
new file mode 100644
index 00000000000..e5766586761
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias23.C
@@ -0,0 +1,20 @@ 
+// PR c++/115296
+// { dg-do compile { target c++20 } }
+
+using size_t = decltype(sizeof(0));
+
+template<class T, size_t N = -1ULL>
+struct span { span(T); };
+
+template<class T, size_t N>
+span(T(&)[N]) -> span<T, N>; // { dg-bogus "array exceeds maximum" }
+
+template<class T, size_t N>
+requires (sizeof(T(&)[N]) != 42) // { dg-bogus "array exceeds maximum" }
+span(T*) -> span<T, N>;
+
+template<class T>
+using array_view = span<T>;
+
+span x = 0;
+array_view y = 0;