public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: converted lambda as template argument [PR83258, ...]
@ 2023-05-10 15:36 Patrick Palka
  2023-05-10 16:21 ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Patrick Palka @ 2023-05-10 15:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, Patrick Palka, Jonathan Wakely

r8-1253-g3d2e25a240c711 removed the template argument linkage requirement
in convert_nontype_argument for C++17, but we need to also remove the one
in convert_nontype_argument_function for sake of the first and third test
case which we incorrectly reject (in C++17/20 mode).

And in invalid_tparm_referent_p we're inadvertendly rejecting using the
address of a lambda's static op() due to the DECL_ARTIFICIAL check.
This patch relaxes this check for sake of the second test case which we
incorrectly reject (in C++20 mode).

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk and perhaps 13 (since it's a relatively easy/safe fix for a
popular non-regression bug).

Co-authored-by: Jonathan Wakely <jwakely@redhat.com>

	PR c++/83258
	PR c++/80488
	PR c++/97700

gcc/cp/ChangeLog:

	* pt.cc (convert_nontype_argument_function): Disable linkage
	requirement for C++17 and later.
	(invalid_tparm_referent_p): Relax DECL_ARTIFICIAL check for
	the artificial static op() of a lambda.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/visibility/anon8.C: Don't expect a "no linkage"
	error for the template argument &B2:fn in C++17 mode.
	* g++.dg/cpp0x/lambda/lambda-conv15.C: New test.
	* g++.dg/cpp2a/nontype-class56.C: New test.
	* g++.dg/template/function2.C: New test.
---
 gcc/cp/pt.cc                                      |  7 +++++--
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C | 11 +++++++++++
 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C      |  8 ++++++++
 gcc/testsuite/g++.dg/ext/visibility/anon8.C       |  4 ++--
 gcc/testsuite/g++.dg/template/function2.C         |  8 ++++++++
 5 files changed, 34 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
 create mode 100644 gcc/testsuite/g++.dg/template/function2.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 696df2bdd9f..c9b089f8fa7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -6782,7 +6782,8 @@ convert_nontype_argument_function (tree type, tree expr,
     }
 
   linkage = decl_linkage (fn_no_ptr);
-  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
+  if ((cxx_dialect < cxx11 && linkage != lk_external)
+      || (cxx_dialect < cxx17 && linkage == lk_none))
     {
       if (complain & tf_error)
 	{
@@ -7180,7 +7181,9 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain)
 	   * a string literal (5.13.5),
 	   * the result of a typeid expression (8.2.8), or
 	   * a predefined __func__ variable (11.4.1).  */
-	else if (DECL_ARTIFICIAL (decl))
+	else if (DECL_ARTIFICIAL (decl)
+		 /* Accept the artificial static op() of a lambda.  */
+		 && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (decl)))
 	  {
 	    if (complain & tf_error)
 	      error ("the address of %qD is not a valid template argument",
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
new file mode 100644
index 00000000000..cf45e06a33d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
@@ -0,0 +1,11 @@
+// PR c++/83258
+// PR c++/80488
+// { dg-do compile { target c++11 } }
+
+template<void(*)()> struct A { };
+
+int main() {
+  constexpr auto fp = +[]{}; // { dg-error "non-'constexpr' function" "" { target c++14_down } }
+  A<fp> a1;    // { dg-error "not a valid template argument" "" { target c++14_down } }
+  A<[]{}> a2;  // { dg-error "lambda-expression in template-argument|invalid" "" { target c++17_down } }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
new file mode 100644
index 00000000000..0efd735c8a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
@@ -0,0 +1,8 @@
+// PR c++/97700
+// { dg-do compile { target c++20 } }
+
+struct S { void (*f)(); };
+
+template<S> struct X { };
+
+X<S{[]{}}> x;
diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon8.C b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
index b8507497d32..bfcc2d06df6 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/anon8.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
@@ -2,7 +2,7 @@
 // { dg-do compile }
 
 template <void (*fn) ()>
-void call ()			// { dg-message "note" }
+void call ()			// { dg-message "note" "" { target c++14_down } }
 {
   fn ();
 }
@@ -26,7 +26,7 @@ int main ()
     static void fn2 () {}
   };
   call<&B1::fn1> ();
-  call<&B2::fn2> ();	// { dg-error "linkage|no matching" }
+  call<&B2::fn2> ();	// { dg-error "linkage|no matching" "" { target c++14_down } }
   call<&fn3> ();
   call<&B1::fn4> ();
   call<&fn5> ();	// { dg-error "linkage|no matching" "" { target { ! c++11 } } }
diff --git a/gcc/testsuite/g++.dg/template/function2.C b/gcc/testsuite/g++.dg/template/function2.C
new file mode 100644
index 00000000000..ad19f24c1cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/function2.C
@@ -0,0 +1,8 @@
+// PR c++/83258
+
+template<void(*)()> struct A { };
+
+int main() {
+  struct B { static void f(); };
+  A<B::f> a; // { dg-error "linkage" "" { target c++14_down } }
+}
-- 
2.40.1.476.g69c786637d


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: converted lambda as template argument [PR83258, ...]
  2023-05-10 15:36 [PATCH] c++: converted lambda as template argument [PR83258, ...] Patrick Palka
@ 2023-05-10 16:21 ` Jason Merrill
  2023-05-10 18:11   ` Patrick Palka
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2023-05-10 16:21 UTC (permalink / raw)
  To: Patrick Palka, gcc-patches; +Cc: Jonathan Wakely

On 5/10/23 11:36, Patrick Palka wrote:
> r8-1253-g3d2e25a240c711 removed the template argument linkage requirement
> in convert_nontype_argument for C++17, but we need to also remove the one
> in convert_nontype_argument_function for sake of the first and third test
> case which we incorrectly reject (in C++17/20 mode).
> 
> And in invalid_tparm_referent_p we're inadvertendly rejecting using the
> address of a lambda's static op() due to the DECL_ARTIFICIAL check.
> This patch relaxes this check for sake of the second test case which we
> incorrectly reject (in C++20 mode).
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk and perhaps 13 (since it's a relatively easy/safe fix for a
> popular non-regression bug).
> 
> Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
> 
> 	PR c++/83258
> 	PR c++/80488
> 	PR c++/97700
> 
> gcc/cp/ChangeLog:
> 
> 	* pt.cc (convert_nontype_argument_function): Disable linkage
> 	requirement for C++17 and later.
> 	(invalid_tparm_referent_p): Relax DECL_ARTIFICIAL check for
> 	the artificial static op() of a lambda.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/visibility/anon8.C: Don't expect a "no linkage"
> 	error for the template argument &B2:fn in C++17 mode.
> 	* g++.dg/cpp0x/lambda/lambda-conv15.C: New test.
> 	* g++.dg/cpp2a/nontype-class56.C: New test.
> 	* g++.dg/template/function2.C: New test.
> ---
>   gcc/cp/pt.cc                                      |  7 +++++--
>   gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C | 11 +++++++++++
>   gcc/testsuite/g++.dg/cpp2a/nontype-class56.C      |  8 ++++++++
>   gcc/testsuite/g++.dg/ext/visibility/anon8.C       |  4 ++--
>   gcc/testsuite/g++.dg/template/function2.C         |  8 ++++++++
>   5 files changed, 34 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
>   create mode 100644 gcc/testsuite/g++.dg/template/function2.C
> 
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 696df2bdd9f..c9b089f8fa7 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -6782,7 +6782,8 @@ convert_nontype_argument_function (tree type, tree expr,
>       }
>   
>     linkage = decl_linkage (fn_no_ptr);
> -  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
> +  if ((cxx_dialect < cxx11 && linkage != lk_external)
> +      || (cxx_dialect < cxx17 && linkage == lk_none))
>       {
>         if (complain & tf_error)
>   	{
> @@ -7180,7 +7181,9 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain)
>   	   * a string literal (5.13.5),
>   	   * the result of a typeid expression (8.2.8), or
>   	   * a predefined __func__ variable (11.4.1).  */
> -	else if (DECL_ARTIFICIAL (decl))
> +	else if (DECL_ARTIFICIAL (decl)
> +		 /* Accept the artificial static op() of a lambda.  */
> +		 && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (decl)))

Maybe check for FUNCTION_DECL instead?  I think the cases we want to 
diagnose are all VAR_DECL.

>   	  {
>   	    if (complain & tf_error)
>   	      error ("the address of %qD is not a valid template argument",
> diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
> new file mode 100644
> index 00000000000..cf45e06a33d
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
> @@ -0,0 +1,11 @@
> +// PR c++/83258
> +// PR c++/80488
> +// { dg-do compile { target c++11 } }
> +
> +template<void(*)()> struct A { };
> +
> +int main() {
> +  constexpr auto fp = +[]{}; // { dg-error "non-'constexpr' function" "" { target c++14_down } }
> +  A<fp> a1;    // { dg-error "not a valid template argument" "" { target c++14_down } }
> +  A<[]{}> a2;  // { dg-error "lambda-expression in template-argument|invalid" "" { target c++17_down } }
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
> new file mode 100644
> index 00000000000..0efd735c8a3
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
> @@ -0,0 +1,8 @@
> +// PR c++/97700
> +// { dg-do compile { target c++20 } }
> +
> +struct S { void (*f)(); };
> +
> +template<S> struct X { };
> +
> +X<S{[]{}}> x;
> diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon8.C b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
> index b8507497d32..bfcc2d06df6 100644
> --- a/gcc/testsuite/g++.dg/ext/visibility/anon8.C
> +++ b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
> @@ -2,7 +2,7 @@
>   // { dg-do compile }
>   
>   template <void (*fn) ()>
> -void call ()			// { dg-message "note" }
> +void call ()			// { dg-message "note" "" { target c++14_down } }
>   {
>     fn ();
>   }
> @@ -26,7 +26,7 @@ int main ()
>       static void fn2 () {}
>     };
>     call<&B1::fn1> ();
> -  call<&B2::fn2> ();	// { dg-error "linkage|no matching" }
> +  call<&B2::fn2> ();	// { dg-error "linkage|no matching" "" { target c++14_down } }
>     call<&fn3> ();
>     call<&B1::fn4> ();
>     call<&fn5> ();	// { dg-error "linkage|no matching" "" { target { ! c++11 } } }
> diff --git a/gcc/testsuite/g++.dg/template/function2.C b/gcc/testsuite/g++.dg/template/function2.C
> new file mode 100644
> index 00000000000..ad19f24c1cd
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/template/function2.C
> @@ -0,0 +1,8 @@
> +// PR c++/83258
> +
> +template<void(*)()> struct A { };
> +
> +int main() {
> +  struct B { static void f(); };
> +  A<B::f> a; // { dg-error "linkage" "" { target c++14_down } }
> +}


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: converted lambda as template argument [PR83258, ...]
  2023-05-10 16:21 ` Jason Merrill
@ 2023-05-10 18:11   ` Patrick Palka
  2023-05-10 21:23     ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Patrick Palka @ 2023-05-10 18:11 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Patrick Palka, gcc-patches, Jonathan Wakely

On Wed, 10 May 2023, Jason Merrill wrote:

> On 5/10/23 11:36, Patrick Palka wrote:
> > r8-1253-g3d2e25a240c711 removed the template argument linkage requirement
> > in convert_nontype_argument for C++17, but we need to also remove the one
> > in convert_nontype_argument_function for sake of the first and third test
> > case which we incorrectly reject (in C++17/20 mode).
> > 
> > And in invalid_tparm_referent_p we're inadvertendly rejecting using the
> > address of a lambda's static op() due to the DECL_ARTIFICIAL check.
> > This patch relaxes this check for sake of the second test case which we
> > incorrectly reject (in C++20 mode).
> > 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk and perhaps 13 (since it's a relatively easy/safe fix for a
> > popular non-regression bug).
> > 
> > Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
> > 
> > 	PR c++/83258
> > 	PR c++/80488
> > 	PR c++/97700
> > 
> > gcc/cp/ChangeLog:
> > 
> > 	* pt.cc (convert_nontype_argument_function): Disable linkage
> > 	requirement for C++17 and later.
> > 	(invalid_tparm_referent_p): Relax DECL_ARTIFICIAL check for
> > 	the artificial static op() of a lambda.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > 	* g++.dg/ext/visibility/anon8.C: Don't expect a "no linkage"
> > 	error for the template argument &B2:fn in C++17 mode.
> > 	* g++.dg/cpp0x/lambda/lambda-conv15.C: New test.
> > 	* g++.dg/cpp2a/nontype-class56.C: New test.
> > 	* g++.dg/template/function2.C: New test.
> > ---
> >   gcc/cp/pt.cc                                      |  7 +++++--
> >   gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C | 11 +++++++++++
> >   gcc/testsuite/g++.dg/cpp2a/nontype-class56.C      |  8 ++++++++
> >   gcc/testsuite/g++.dg/ext/visibility/anon8.C       |  4 ++--
> >   gcc/testsuite/g++.dg/template/function2.C         |  8 ++++++++
> >   5 files changed, 34 insertions(+), 4 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
> >   create mode 100644 gcc/testsuite/g++.dg/template/function2.C
> > 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index 696df2bdd9f..c9b089f8fa7 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -6782,7 +6782,8 @@ convert_nontype_argument_function (tree type, tree
> > expr,
> >       }
> >       linkage = decl_linkage (fn_no_ptr);
> > -  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
> > +  if ((cxx_dialect < cxx11 && linkage != lk_external)
> > +      || (cxx_dialect < cxx17 && linkage == lk_none))
> >       {
> >         if (complain & tf_error)
> >   	{
> > @@ -7180,7 +7181,9 @@ invalid_tparm_referent_p (tree type, tree expr,
> > tsubst_flags_t complain)
> >   	   * a string literal (5.13.5),
> >   	   * the result of a typeid expression (8.2.8), or
> >   	   * a predefined __func__ variable (11.4.1).  */
> > -	else if (DECL_ARTIFICIAL (decl))
> > +	else if (DECL_ARTIFICIAL (decl)
> > +		 /* Accept the artificial static op() of a lambda.  */
> > +		 && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (decl)))
> 
> Maybe check for FUNCTION_DECL instead?  I think the cases we want to diagnose
> are all VAR_DECL.

Makes sense, before r13-6970-gb5e38b1c166357 this code path would only
be reachable for VAR_DECL anyway.  Like so?  Bootstrapped and regtested
on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps 13?

-- >8 --

Subject: [PATCH] c++: converted lambda as template argument [PR83258, ...]

r8-1253-g3d2e25a240c711 removed the template argument linkage requirement
in convert_nontype_argument for C++17, but we need to also remove the one
in convert_nontype_argument_function for sake of the first and third test
case which we incorrectly reject (in C++17/20 mode).

And in invalid_tparm_referent_p we're inadvertendly diagnosing using the
address of a lambda's static op() since it's DECL_ARTIFICIAL, which causes
us to reject the second (C++20) testcase.  But this DECL_ARTIFICIAL check
seems to be relevant only for VAR_DECL, and indeed code path was reached
only for VAR_DECL until r13-6970-gb5e38b1c166357.  So this patch relaxes
the check accordingly.

Co-authored-by: Jonathan Wakely <jwakely@redhat.com>

	PR c++/83258
	PR c++/80488
	PR c++/97700

gcc/cp/ChangeLog:

	* pt.cc (convert_nontype_argument_function): Disable linkage
	check for C++17 and later.
	(invalid_tparm_referent_p): Accept DECL_ARTIFICIAL FUNCTION_DECL.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/visibility/anon8.C: Don't expect a "no linkage"
	error for the template argument &B2:fn in C++17 mode.
	* g++.dg/cpp0x/lambda/lambda-conv15.C: New test.
	* g++.dg/cpp2a/nontype-class56.C: New test.
	* g++.dg/template/function2.C: New test.
---
 gcc/cp/pt.cc                                      |  5 +++--
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C | 11 +++++++++++
 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C      |  8 ++++++++
 gcc/testsuite/g++.dg/ext/visibility/anon8.C       |  4 ++--
 gcc/testsuite/g++.dg/template/function2.C         |  8 ++++++++
 5 files changed, 32 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
 create mode 100644 gcc/testsuite/g++.dg/template/function2.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 696df2bdd9f..351fc18b600 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -6782,7 +6782,8 @@ convert_nontype_argument_function (tree type, tree expr,
     }
 
   linkage = decl_linkage (fn_no_ptr);
-  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
+  if ((cxx_dialect < cxx11 && linkage != lk_external)
+      || (cxx_dialect < cxx17 && linkage == lk_none))
     {
       if (complain & tf_error)
 	{
@@ -7180,7 +7181,7 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain)
 	   * a string literal (5.13.5),
 	   * the result of a typeid expression (8.2.8), or
 	   * a predefined __func__ variable (11.4.1).  */
-	else if (DECL_ARTIFICIAL (decl))
+	else if (VAR_P (decl) && DECL_ARTIFICIAL (decl))
 	  {
 	    if (complain & tf_error)
 	      error ("the address of %qD is not a valid template argument",
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
new file mode 100644
index 00000000000..cf45e06a33d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
@@ -0,0 +1,11 @@
+// PR c++/83258
+// PR c++/80488
+// { dg-do compile { target c++11 } }
+
+template<void(*)()> struct A { };
+
+int main() {
+  constexpr auto fp = +[]{}; // { dg-error "non-'constexpr' function" "" { target c++14_down } }
+  A<fp> a1;    // { dg-error "not a valid template argument" "" { target c++14_down } }
+  A<[]{}> a2;  // { dg-error "lambda-expression in template-argument|invalid" "" { target c++17_down } }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
new file mode 100644
index 00000000000..0efd735c8a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
@@ -0,0 +1,8 @@
+// PR c++/97700
+// { dg-do compile { target c++20 } }
+
+struct S { void (*f)(); };
+
+template<S> struct X { };
+
+X<S{[]{}}> x;
diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon8.C b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
index b8507497d32..bfcc2d06df6 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/anon8.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
@@ -2,7 +2,7 @@
 // { dg-do compile }
 
 template <void (*fn) ()>
-void call ()			// { dg-message "note" }
+void call ()			// { dg-message "note" "" { target c++14_down } }
 {
   fn ();
 }
@@ -26,7 +26,7 @@ int main ()
     static void fn2 () {}
   };
   call<&B1::fn1> ();
-  call<&B2::fn2> ();	// { dg-error "linkage|no matching" }
+  call<&B2::fn2> ();	// { dg-error "linkage|no matching" "" { target c++14_down } }
   call<&fn3> ();
   call<&B1::fn4> ();
   call<&fn5> ();	// { dg-error "linkage|no matching" "" { target { ! c++11 } } }
diff --git a/gcc/testsuite/g++.dg/template/function2.C b/gcc/testsuite/g++.dg/template/function2.C
new file mode 100644
index 00000000000..54c48e6b36f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/function2.C
@@ -0,0 +1,8 @@
+// PR c++/83258
+
+template<void(*)()> struct A { };
+
+int main() {
+  struct B { static void f() { } };
+  A<B::f> a; // { dg-error "linkage" "" { target c++14_down } }
+}
-- 
2.40.1.476.g69c786637d


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] c++: converted lambda as template argument [PR83258, ...]
  2023-05-10 18:11   ` Patrick Palka
@ 2023-05-10 21:23     ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2023-05-10 21:23 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches, Jonathan Wakely

On 5/10/23 14:11, Patrick Palka wrote:
> On Wed, 10 May 2023, Jason Merrill wrote:
> 
>> On 5/10/23 11:36, Patrick Palka wrote:
>>> r8-1253-g3d2e25a240c711 removed the template argument linkage requirement
>>> in convert_nontype_argument for C++17, but we need to also remove the one
>>> in convert_nontype_argument_function for sake of the first and third test
>>> case which we incorrectly reject (in C++17/20 mode).
>>>
>>> And in invalid_tparm_referent_p we're inadvertendly rejecting using the
>>> address of a lambda's static op() due to the DECL_ARTIFICIAL check.
>>> This patch relaxes this check for sake of the second test case which we
>>> incorrectly reject (in C++20 mode).
>>>
>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
>>> trunk and perhaps 13 (since it's a relatively easy/safe fix for a
>>> popular non-regression bug).
>>>
>>> Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
>>>
>>> 	PR c++/83258
>>> 	PR c++/80488
>>> 	PR c++/97700
>>>
>>> gcc/cp/ChangeLog:
>>>
>>> 	* pt.cc (convert_nontype_argument_function): Disable linkage
>>> 	requirement for C++17 and later.
>>> 	(invalid_tparm_referent_p): Relax DECL_ARTIFICIAL check for
>>> 	the artificial static op() of a lambda.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> 	* g++.dg/ext/visibility/anon8.C: Don't expect a "no linkage"
>>> 	error for the template argument &B2:fn in C++17 mode.
>>> 	* g++.dg/cpp0x/lambda/lambda-conv15.C: New test.
>>> 	* g++.dg/cpp2a/nontype-class56.C: New test.
>>> 	* g++.dg/template/function2.C: New test.
>>> ---
>>>    gcc/cp/pt.cc                                      |  7 +++++--
>>>    gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C | 11 +++++++++++
>>>    gcc/testsuite/g++.dg/cpp2a/nontype-class56.C      |  8 ++++++++
>>>    gcc/testsuite/g++.dg/ext/visibility/anon8.C       |  4 ++--
>>>    gcc/testsuite/g++.dg/template/function2.C         |  8 ++++++++
>>>    5 files changed, 34 insertions(+), 4 deletions(-)
>>>    create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
>>>    create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
>>>    create mode 100644 gcc/testsuite/g++.dg/template/function2.C
>>>
>>> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
>>> index 696df2bdd9f..c9b089f8fa7 100644
>>> --- a/gcc/cp/pt.cc
>>> +++ b/gcc/cp/pt.cc
>>> @@ -6782,7 +6782,8 @@ convert_nontype_argument_function (tree type, tree
>>> expr,
>>>        }
>>>        linkage = decl_linkage (fn_no_ptr);
>>> -  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
>>> +  if ((cxx_dialect < cxx11 && linkage != lk_external)
>>> +      || (cxx_dialect < cxx17 && linkage == lk_none))
>>>        {
>>>          if (complain & tf_error)
>>>    	{
>>> @@ -7180,7 +7181,9 @@ invalid_tparm_referent_p (tree type, tree expr,
>>> tsubst_flags_t complain)
>>>    	   * a string literal (5.13.5),
>>>    	   * the result of a typeid expression (8.2.8), or
>>>    	   * a predefined __func__ variable (11.4.1).  */
>>> -	else if (DECL_ARTIFICIAL (decl))
>>> +	else if (DECL_ARTIFICIAL (decl)
>>> +		 /* Accept the artificial static op() of a lambda.  */
>>> +		 && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (decl)))
>>
>> Maybe check for FUNCTION_DECL instead?  I think the cases we want to diagnose
>> are all VAR_DECL.
> 
> Makes sense, before r13-6970-gb5e38b1c166357 this code path would only
> be reachable for VAR_DECL anyway.  Like so?  Bootstrapped and regtested
> on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps 13?

OK for both.

> -- >8 --
> 
> Subject: [PATCH] c++: converted lambda as template argument [PR83258, ...]
> 
> r8-1253-g3d2e25a240c711 removed the template argument linkage requirement
> in convert_nontype_argument for C++17, but we need to also remove the one
> in convert_nontype_argument_function for sake of the first and third test
> case which we incorrectly reject (in C++17/20 mode).
> 
> And in invalid_tparm_referent_p we're inadvertendly diagnosing using the
> address of a lambda's static op() since it's DECL_ARTIFICIAL, which causes
> us to reject the second (C++20) testcase.  But this DECL_ARTIFICIAL check
> seems to be relevant only for VAR_DECL, and indeed code path was reached
> only for VAR_DECL until r13-6970-gb5e38b1c166357.  So this patch relaxes
> the check accordingly.
> 
> Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
> 
> 	PR c++/83258
> 	PR c++/80488
> 	PR c++/97700
> 
> gcc/cp/ChangeLog:
> 
> 	* pt.cc (convert_nontype_argument_function): Disable linkage
> 	check for C++17 and later.
> 	(invalid_tparm_referent_p): Accept DECL_ARTIFICIAL FUNCTION_DECL.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/visibility/anon8.C: Don't expect a "no linkage"
> 	error for the template argument &B2:fn in C++17 mode.
> 	* g++.dg/cpp0x/lambda/lambda-conv15.C: New test.
> 	* g++.dg/cpp2a/nontype-class56.C: New test.
> 	* g++.dg/template/function2.C: New test.
> ---
>   gcc/cp/pt.cc                                      |  5 +++--
>   gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C | 11 +++++++++++
>   gcc/testsuite/g++.dg/cpp2a/nontype-class56.C      |  8 ++++++++
>   gcc/testsuite/g++.dg/ext/visibility/anon8.C       |  4 ++--
>   gcc/testsuite/g++.dg/template/function2.C         |  8 ++++++++
>   5 files changed, 32 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
>   create mode 100644 gcc/testsuite/g++.dg/template/function2.C
> 
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 696df2bdd9f..351fc18b600 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -6782,7 +6782,8 @@ convert_nontype_argument_function (tree type, tree expr,
>       }
>   
>     linkage = decl_linkage (fn_no_ptr);
> -  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)
> +  if ((cxx_dialect < cxx11 && linkage != lk_external)
> +      || (cxx_dialect < cxx17 && linkage == lk_none))
>       {
>         if (complain & tf_error)
>   	{
> @@ -7180,7 +7181,7 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain)
>   	   * a string literal (5.13.5),
>   	   * the result of a typeid expression (8.2.8), or
>   	   * a predefined __func__ variable (11.4.1).  */
> -	else if (DECL_ARTIFICIAL (decl))
> +	else if (VAR_P (decl) && DECL_ARTIFICIAL (decl))
>   	  {
>   	    if (complain & tf_error)
>   	      error ("the address of %qD is not a valid template argument",
> diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
> new file mode 100644
> index 00000000000..cf45e06a33d
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv15.C
> @@ -0,0 +1,11 @@
> +// PR c++/83258
> +// PR c++/80488
> +// { dg-do compile { target c++11 } }
> +
> +template<void(*)()> struct A { };
> +
> +int main() {
> +  constexpr auto fp = +[]{}; // { dg-error "non-'constexpr' function" "" { target c++14_down } }
> +  A<fp> a1;    // { dg-error "not a valid template argument" "" { target c++14_down } }
> +  A<[]{}> a2;  // { dg-error "lambda-expression in template-argument|invalid" "" { target c++17_down } }
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
> new file mode 100644
> index 00000000000..0efd735c8a3
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class56.C
> @@ -0,0 +1,8 @@
> +// PR c++/97700
> +// { dg-do compile { target c++20 } }
> +
> +struct S { void (*f)(); };
> +
> +template<S> struct X { };
> +
> +X<S{[]{}}> x;
> diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon8.C b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
> index b8507497d32..bfcc2d06df6 100644
> --- a/gcc/testsuite/g++.dg/ext/visibility/anon8.C
> +++ b/gcc/testsuite/g++.dg/ext/visibility/anon8.C
> @@ -2,7 +2,7 @@
>   // { dg-do compile }
>   
>   template <void (*fn) ()>
> -void call ()			// { dg-message "note" }
> +void call ()			// { dg-message "note" "" { target c++14_down } }
>   {
>     fn ();
>   }
> @@ -26,7 +26,7 @@ int main ()
>       static void fn2 () {}
>     };
>     call<&B1::fn1> ();
> -  call<&B2::fn2> ();	// { dg-error "linkage|no matching" }
> +  call<&B2::fn2> ();	// { dg-error "linkage|no matching" "" { target c++14_down } }
>     call<&fn3> ();
>     call<&B1::fn4> ();
>     call<&fn5> ();	// { dg-error "linkage|no matching" "" { target { ! c++11 } } }
> diff --git a/gcc/testsuite/g++.dg/template/function2.C b/gcc/testsuite/g++.dg/template/function2.C
> new file mode 100644
> index 00000000000..54c48e6b36f
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/template/function2.C
> @@ -0,0 +1,8 @@
> +// PR c++/83258
> +
> +template<void(*)()> struct A { };
> +
> +int main() {
> +  struct B { static void f() { } };
> +  A<B::f> a; // { dg-error "linkage" "" { target c++14_down } }
> +}


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-05-10 21:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-10 15:36 [PATCH] c++: converted lambda as template argument [PR83258, ...] Patrick Palka
2023-05-10 16:21 ` Jason Merrill
2023-05-10 18:11   ` Patrick Palka
2023-05-10 21:23     ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).