* [PATCH] c++: address of NTTP object as targ [PR113242] @ 2024-01-05 16:50 Patrick Palka 2024-01-15 19:34 ` Patrick Palka 2024-01-15 21:00 ` Jason Merrill 0 siblings, 2 replies; 5+ messages in thread From: Patrick Palka @ 2024-01-05 16:50 UTC (permalink / raw) To: gcc-patches; +Cc: jason, Patrick Palka Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps 13? -- >8 -- invalid_tparm_referent_p was rejecting using the address of a class NTTP object as a template argument, but this should be fine. PR c++/113242 gcc/cp/ChangeLog: * pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Suppress DECL_ARTIFICIAL rejection test for class NTTP objects. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/nontype-class61.C: New test. --- gcc/cp/pt.cc | 3 ++- gcc/testsuite/g++.dg/cpp2a/nontype-class61.C | 27 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class61.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 154ac76cb65..8c7d178328d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7219,7 +7219,8 @@ 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 (VAR_P (decl) && DECL_ARTIFICIAL (decl)) + else if (VAR_P (decl) && !DECL_NTTP_OBJECT_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/cpp2a/nontype-class61.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C new file mode 100644 index 00000000000..90805a05ecf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C @@ -0,0 +1,27 @@ +// PR c++/113242 +// { dg-do compile { target c++20 } } + +struct wrapper { + int n; +}; + +template<const wrapper& X> +void f1() { + static_assert(X.n == 42); +} + +template<const wrapper* X> +void f2() { + static_assert(X->n == 42); +} + +template<wrapper X> +void g() { + f1<X>(); + f2<&X>(); +} + +int main() { + constexpr wrapper X = {42}; + g<X>(); +} -- 2.43.0.254.ga26002b628 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] c++: address of NTTP object as targ [PR113242] 2024-01-05 16:50 [PATCH] c++: address of NTTP object as targ [PR113242] Patrick Palka @ 2024-01-15 19:34 ` Patrick Palka 2024-01-15 21:00 ` Jason Merrill 1 sibling, 0 replies; 5+ messages in thread From: Patrick Palka @ 2024-01-15 19:34 UTC (permalink / raw) To: gcc-patches; +Cc: jason On Fri, Jan 5, 2024 at 11:50 AM Patrick Palka <ppalka@redhat.com> wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK > for trunk and perhaps 13? Ping. > > -- >8 -- > > invalid_tparm_referent_p was rejecting using the address of a class NTTP > object as a template argument, but this should be fine. > > PR c++/113242 > > gcc/cp/ChangeLog: > > * pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Suppress > DECL_ARTIFICIAL rejection test for class NTTP objects. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/nontype-class61.C: New test. > --- > gcc/cp/pt.cc | 3 ++- > gcc/testsuite/g++.dg/cpp2a/nontype-class61.C | 27 ++++++++++++++++++++ > 2 files changed, 29 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 154ac76cb65..8c7d178328d 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -7219,7 +7219,8 @@ 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 (VAR_P (decl) && DECL_ARTIFICIAL (decl)) > + else if (VAR_P (decl) && !DECL_NTTP_OBJECT_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/cpp2a/nontype-class61.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > new file mode 100644 > index 00000000000..90805a05ecf > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > @@ -0,0 +1,27 @@ > +// PR c++/113242 > +// { dg-do compile { target c++20 } } > + > +struct wrapper { > + int n; > +}; > + > +template<const wrapper& X> > +void f1() { > + static_assert(X.n == 42); > +} > + > +template<const wrapper* X> > +void f2() { > + static_assert(X->n == 42); > +} > + > +template<wrapper X> > +void g() { > + f1<X>(); > + f2<&X>(); > +} > + > +int main() { > + constexpr wrapper X = {42}; > + g<X>(); > +} > -- > 2.43.0.254.ga26002b628 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] c++: address of NTTP object as targ [PR113242] 2024-01-05 16:50 [PATCH] c++: address of NTTP object as targ [PR113242] Patrick Palka 2024-01-15 19:34 ` Patrick Palka @ 2024-01-15 21:00 ` Jason Merrill 2024-01-17 15:43 ` Patrick Palka 1 sibling, 1 reply; 5+ messages in thread From: Jason Merrill @ 2024-01-15 21:00 UTC (permalink / raw) To: Patrick Palka, gcc-patches On 1/5/24 11:50, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK > for trunk and perhaps 13? > > -- >8 -- > > invalid_tparm_referent_p was rejecting using the address of a class NTTP > object as a template argument, but this should be fine. Hmm, I suppose so; https://eel.is/c++draft/temp#param-8 saying "No two template parameter objects are template-argument-equivalent" suggests there can be only one. And clang/msvc allow it. > PR c++/113242 > > gcc/cp/ChangeLog: > > * pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Suppress > DECL_ARTIFICIAL rejection test for class NTTP objects. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/nontype-class61.C: New test. > --- > gcc/cp/pt.cc | 3 ++- > gcc/testsuite/g++.dg/cpp2a/nontype-class61.C | 27 ++++++++++++++++++++ > 2 files changed, 29 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 154ac76cb65..8c7d178328d 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -7219,7 +7219,8 @@ 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 (VAR_P (decl) && DECL_ARTIFICIAL (decl)) > + else if (VAR_P (decl) && !DECL_NTTP_OBJECT_P (decl) > + && DECL_ARTIFICIAL (decl)) If now some artificial variables are OK and others are not, perhaps we should enumerate them either way and abort if it's one we haven't specifically considered. Jason ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] c++: address of NTTP object as targ [PR113242] 2024-01-15 21:00 ` Jason Merrill @ 2024-01-17 15:43 ` Patrick Palka 2024-01-17 16:34 ` Jason Merrill 0 siblings, 1 reply; 5+ messages in thread From: Patrick Palka @ 2024-01-17 15:43 UTC (permalink / raw) To: Jason Merrill; +Cc: Patrick Palka, gcc-patches On Mon, 15 Jan 2024, Jason Merrill wrote: > On 1/5/24 11:50, Patrick Palka wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK > > for trunk and perhaps 13? > > > > -- >8 -- > > > > invalid_tparm_referent_p was rejecting using the address of a class NTTP > > object as a template argument, but this should be fine. > > Hmm, I suppose so; https://eel.is/c++draft/temp#param-8 saying "No two > template parameter objects are template-argument-equivalent" suggests there > can be only one. And clang/msvc allow it. > > > PR c++/113242 > > > > gcc/cp/ChangeLog: > > > > * pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Suppress > > DECL_ARTIFICIAL rejection test for class NTTP objects. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp2a/nontype-class61.C: New test. > > --- > > gcc/cp/pt.cc | 3 ++- > > gcc/testsuite/g++.dg/cpp2a/nontype-class61.C | 27 ++++++++++++++++++++ > > 2 files changed, 29 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index 154ac76cb65..8c7d178328d 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -7219,7 +7219,8 @@ 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 (VAR_P (decl) && DECL_ARTIFICIAL (decl)) > > + else if (VAR_P (decl) && !DECL_NTTP_OBJECT_P (decl) > > + && DECL_ARTIFICIAL (decl)) > > If now some artificial variables are OK and others are not, perhaps we should > enumerate them either way and abort if it's one we haven't specifically > considered. Sounds good, like so? Shall we backport this patch or the original patch to the 13 branch? -- >8 -- Subject: [PATCH] c++: address of class NTTP object as targ [PR113242] invalid_tparm_referent_p was rejecting using the address of a class NTTP object as a template argument, but this should be fine. This patch fixes this by refining the DECL_ARTIFICIAL rejection test to check specifically for the kinds of artificial variables we want to exclude. PR c++/113242 gcc/cp/ChangeLog: * pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Refine DECL_ARTIFICIAL rejection test. Assert that C++20 template parameter objects are the only artificial variables we accept. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/nontype-class61.C: New test. --- gcc/cp/pt.cc | 13 +++++++--- gcc/testsuite/g++.dg/cpp2a/nontype-class61.C | 27 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class61.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index b6117231de1..885c297450e 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7212,12 +7212,14 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain) /* C++17: For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of): - * a subobject (4.5), + * a subobject (4.5), (relaxed in C++20) * a temporary object (15.2), - * a string literal (5.13.5), + * a string literal (5.13.5), (we diagnose this early in + convert_nontype_argument) * the result of a typeid expression (8.2.8), or * a predefined __func__ variable (11.4.1). */ - else if (VAR_P (decl) && DECL_ARTIFICIAL (decl)) + else if (VAR_P (decl) + && (DECL_TINFO_P (decl) || DECL_FNAME_P (decl))) { if (complain & tf_error) error ("the address of %qD is not a valid template argument", @@ -7242,6 +7244,11 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain) decl); return true; } + + /* The only artificial variables we do accept are C++20 + template parameter objects. */ + if (VAR_P (decl) && DECL_ARTIFICIAL (decl)) + gcc_checking_assert (DECL_NTTP_OBJECT_P (decl)); } break; diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C new file mode 100644 index 00000000000..90805a05ecf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C @@ -0,0 +1,27 @@ +// PR c++/113242 +// { dg-do compile { target c++20 } } + +struct wrapper { + int n; +}; + +template<const wrapper& X> +void f1() { + static_assert(X.n == 42); +} + +template<const wrapper* X> +void f2() { + static_assert(X->n == 42); +} + +template<wrapper X> +void g() { + f1<X>(); + f2<&X>(); +} + +int main() { + constexpr wrapper X = {42}; + g<X>(); +} -- 2.43.0.367.g186b115d30 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] c++: address of NTTP object as targ [PR113242] 2024-01-17 15:43 ` Patrick Palka @ 2024-01-17 16:34 ` Jason Merrill 0 siblings, 0 replies; 5+ messages in thread From: Jason Merrill @ 2024-01-17 16:34 UTC (permalink / raw) To: Patrick Palka; +Cc: gcc-patches On 1/17/24 10:43, Patrick Palka wrote: > On Mon, 15 Jan 2024, Jason Merrill wrote: >> On 1/5/24 11:50, Patrick Palka wrote: >>> >>> invalid_tparm_referent_p was rejecting using the address of a class NTTP >>> object as a template argument, but this should be fine. >> >> Hmm, I suppose so; https://eel.is/c++draft/temp#param-8 saying "No two >> template parameter objects are template-argument-equivalent" suggests there >> can be only one. And clang/msvc allow it. >> >>> + else if (VAR_P (decl) && !DECL_NTTP_OBJECT_P (decl) >>> + && DECL_ARTIFICIAL (decl)) >> >> If now some artificial variables are OK and others are not, perhaps we should >> enumerate them either way and abort if it's one we haven't specifically >> considered. > > Sounds good, like so? Shall we backport this patch or the original > patch to the 13 branch? Hmm, looks like this patch changes the non-checking default behavior from reject to accept; maybe just add a checking_assert (tinfo || fname) to your original patch? OK with that change, for trunk and 13. > -- >8 -- > > Subject: [PATCH] c++: address of class NTTP object as targ [PR113242] > > invalid_tparm_referent_p was rejecting using the address of a class NTTP > object as a template argument, but this should be fine. > > This patch fixes this by refining the DECL_ARTIFICIAL rejection test to > check specifically for the kinds of artificial variables we want to > exclude. > > PR c++/113242 > > gcc/cp/ChangeLog: > > * pt.cc (invalid_tparm_referent_p) <case ADDR_EXPR>: Refine > DECL_ARTIFICIAL rejection test. Assert that C++20 template > parameter objects are the only artificial variables we accept. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/nontype-class61.C: New test. > --- > gcc/cp/pt.cc | 13 +++++++--- > gcc/testsuite/g++.dg/cpp2a/nontype-class61.C | 27 ++++++++++++++++++++ > 2 files changed, 37 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index b6117231de1..885c297450e 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -7212,12 +7212,14 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain) > /* C++17: For a non-type template-parameter of reference or pointer > type, the value of the constant expression shall not refer to (or > for a pointer type, shall not be the address of): > - * a subobject (4.5), > + * a subobject (4.5), (relaxed in C++20) > * a temporary object (15.2), > - * a string literal (5.13.5), > + * a string literal (5.13.5), (we diagnose this early in > + convert_nontype_argument) > * the result of a typeid expression (8.2.8), or > * a predefined __func__ variable (11.4.1). */ > - else if (VAR_P (decl) && DECL_ARTIFICIAL (decl)) > + else if (VAR_P (decl) > + && (DECL_TINFO_P (decl) || DECL_FNAME_P (decl))) > { > if (complain & tf_error) > error ("the address of %qD is not a valid template argument", > @@ -7242,6 +7244,11 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain) > decl); > return true; > } > + > + /* The only artificial variables we do accept are C++20 > + template parameter objects. */ > + if (VAR_P (decl) && DECL_ARTIFICIAL (decl)) > + gcc_checking_assert (DECL_NTTP_OBJECT_P (decl)); > } > break; > > diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > new file mode 100644 > index 00000000000..90805a05ecf > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class61.C > @@ -0,0 +1,27 @@ > +// PR c++/113242 > +// { dg-do compile { target c++20 } } > + > +struct wrapper { > + int n; > +}; > + > +template<const wrapper& X> > +void f1() { > + static_assert(X.n == 42); > +} > + > +template<const wrapper* X> > +void f2() { > + static_assert(X->n == 42); > +} > + > +template<wrapper X> > +void g() { > + f1<X>(); > + f2<&X>(); > +} > + > +int main() { > + constexpr wrapper X = {42}; > + g<X>(); > +} ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-01-17 16:35 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-01-05 16:50 [PATCH] c++: address of NTTP object as targ [PR113242] Patrick Palka 2024-01-15 19:34 ` Patrick Palka 2024-01-15 21:00 ` Jason Merrill 2024-01-17 15:43 ` Patrick Palka 2024-01-17 16:34 ` 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).