Re: [PATCH] c++: address of NTTP object as targ [PR113242]
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) : 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 000..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 +void f1() { + static_assert(X.n == 42); +} + +template +void f2() { + static_assert(X->n == 42); +} + +template +void g() { + f1(); + f2<>(); +} + +int main() { + constexpr wrapper X = {42}; + g(); +}
Re: [PATCH] c++: address of NTTP object as targ [PR113242]
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) : 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) : 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 000..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 +void f1() { + static_assert(X.n == 42); +} + +template +void f2() { + static_assert(X->n == 42); +} + +template +void g() { + f1(); + f2<>(); +} + +int main() { + constexpr wrapper X = {42}; + g(); +} -- 2.43.0.367.g186b115d30
Re: [PATCH] c++: address of NTTP object as targ [PR113242]
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) : 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
Re: [PATCH] c++: address of NTTP object as targ [PR113242]
On Fri, Jan 5, 2024 at 11:50 AM Patrick Palka 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) : 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 000..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 > +void f1() { > + static_assert(X.n == 42); > +} > + > +template > +void f2() { > + static_assert(X->n == 42); > +} > + > +template > +void g() { > + f1(); > + f2<>(); > +} > + > +int main() { > + constexpr wrapper X = {42}; > + g(); > +} > -- > 2.43.0.254.ga26002b628 >