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