public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] c++: implement __remove_pointer built-in trait
@ 2023-06-15 12:21 Ken Matsui
  2023-06-15 12:21 ` [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
  2023-06-17 12:35 ` [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  0 siblings, 2 replies; 13+ messages in thread
From: Ken Matsui @ 2023-06-15 12:21 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
	* g++.dg/ext/remove_pointer.C: New test.

Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
---
 gcc/cp/cp-trait.def                       |  1 +
 gcc/cp/semantics.cc                       |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
 4 files changed, 59 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..07823e55579 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..885c7a6fb64 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12373,6 +12373,10 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
       if (TYPE_REF_P (type1))
 	type1 = TREE_TYPE (type1);
       return cv_unqualified (type1);
+    case CPTK_REMOVE_POINTER:
+      if (TYPE_PTR_P (type1))
+    type1 = TREE_TYPE (type1);
+      return type1;
 
     case CPTK_TYPE_PACK_ELEMENT:
       return finish_type_pack_element (type1, type2, complain);
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..e21e0a95509 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_pointer)
+# error "__has_builtin (__remove_pointer) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
new file mode 100644
index 00000000000..7b13db93950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(__is_same(__remove_pointer(int), int));
+SA(__is_same(__remove_pointer(int*), int));
+SA(__is_same(__remove_pointer(int**), int*));
+
+SA(__is_same(__remove_pointer(const int*), const int));
+SA(__is_same(__remove_pointer(const int**), const int*));
+SA(__is_same(__remove_pointer(int* const), int));
+SA(__is_same(__remove_pointer(int** const), int*));
+SA(__is_same(__remove_pointer(int* const* const), int* const));
+
+SA(__is_same(__remove_pointer(volatile int*), volatile int));
+SA(__is_same(__remove_pointer(volatile int**), volatile int*));
+SA(__is_same(__remove_pointer(int* volatile), int));
+SA(__is_same(__remove_pointer(int** volatile), int*));
+SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
+
+SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
+SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
+SA(__is_same(__remove_pointer(const int* volatile), const int));
+SA(__is_same(__remove_pointer(volatile int* const), volatile int));
+SA(__is_same(__remove_pointer(int* const volatile), int));
+SA(__is_same(__remove_pointer(const int** volatile), const int*));
+SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
+SA(__is_same(__remove_pointer(int** const volatile), int*));
+SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
+SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
+SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
+
+SA(__is_same(__remove_pointer(int&), int&));
+SA(__is_same(__remove_pointer(const int&), const int&));
+SA(__is_same(__remove_pointer(volatile int&), volatile int&));
+SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
+
+SA(__is_same(__remove_pointer(int&&), int&&));
+SA(__is_same(__remove_pointer(const int&&), const int&&));
+SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
+SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
+
+SA(__is_same(__remove_pointer(int[3]), int[3]));
+SA(__is_same(__remove_pointer(const int[3]), const int[3]));
+SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
+SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
+
+SA(__is_same(__remove_pointer(int(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
-- 
2.41.0


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

* [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer
  2023-06-15 12:21 [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
@ 2023-06-15 12:21 ` Ken Matsui
  2023-06-17 12:35 ` [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  1 sibling, 0 replies; 13+ messages in thread
From: Ken Matsui @ 2023-06-15 12:21 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch lets libstdc++ use new built-in trait __remove_pointer.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_pointer): Use __remove_pointer built-in trait.

Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
---
 libstdc++-v3/include/std/type_traits | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 0e7a9c9c7f3..81497e2f3e1 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2023,6 +2023,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if __has_builtin(__remove_pointer)
+  template<typename _Tp>
+    struct remove_pointer
+    { using type = __remove_pointer(_Tp); };
+#else
   template<typename _Tp, typename>
     struct __remove_pointer_helper
     { using type = _Tp; };
@@ -2031,11 +2037,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __remove_pointer_helper<_Tp, _Up*>
     { using type = _Up; };
 
-  /// remove_pointer
   template<typename _Tp>
     struct remove_pointer
     : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
     { };
+#endif
 
   template<typename _Tp, typename = void>
     struct __add_pointer_helper
-- 
2.41.0


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

* Re: [PATCH 1/2] c++: implement __remove_pointer built-in trait
  2023-06-15 12:21 [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  2023-06-15 12:21 ` [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
@ 2023-06-17 12:35 ` Ken Matsui
  2023-06-20 13:20   ` Ken Matsui
  2023-06-20 15:21   ` Patrick Palka
  1 sibling, 2 replies; 13+ messages in thread
From: Ken Matsui @ 2023-06-17 12:35 UTC (permalink / raw)
  To: gcc-patches

Hi,

I conducted a benchmark for remove_pointer as well as is_object. Just
like the is_object benchmark, here is the benchmark code:

https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer_benchmark.cc

On my computer, using the gcc HEAD of this patch for a release build,
the patch with -DUSE_BUILTIN took 8.7% less time and used 4.3-4.9%
less memory on average compared to not using it. Although the
performance improvement was not as significant as with is_object, the
benchmark demonstrated that the compilation was consistently more
efficient.

Sincerely,
Ken Matsui

On Thu, Jun 15, 2023 at 5:22 AM Ken Matsui <kmatsui@cs.washington.edu> wrote:
>
> This patch implements built-in trait for std::remove_pointer.
>
> gcc/cp/ChangeLog:
>
>         * cp-trait.def: Define __remove_pointer.
>         * semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
>         * g++.dg/ext/remove_pointer.C: New test.
>
> Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
> ---
>  gcc/cp/cp-trait.def                       |  1 +
>  gcc/cp/semantics.cc                       |  4 ++
>  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
>  gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
>  4 files changed, 59 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C
>
> diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> index 8b7fece0cc8..07823e55579 100644
> --- a/gcc/cp/cp-trait.def
> +++ b/gcc/cp/cp-trait.def
> @@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
>  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
>  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
>  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> +DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
>  DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
>  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
>
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 8fb47fd179e..885c7a6fb64 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12373,6 +12373,10 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
>        if (TYPE_REF_P (type1))
>         type1 = TREE_TYPE (type1);
>        return cv_unqualified (type1);
> +    case CPTK_REMOVE_POINTER:
> +      if (TYPE_PTR_P (type1))
> +    type1 = TREE_TYPE (type1);
> +      return type1;
>
>      case CPTK_TYPE_PACK_ELEMENT:
>        return finish_type_pack_element (type1, type2, complain);
> diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> index f343e153e56..e21e0a95509 100644
> --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> @@ -146,3 +146,6 @@
>  #if !__has_builtin (__remove_cvref)
>  # error "__has_builtin (__remove_cvref) failed"
>  #endif
> +#if !__has_builtin (__remove_pointer)
> +# error "__has_builtin (__remove_pointer) failed"
> +#endif
> diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> new file mode 100644
> index 00000000000..7b13db93950
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> @@ -0,0 +1,51 @@
> +// { dg-do compile { target c++11 } }
> +
> +#define SA(X) static_assert((X),#X)
> +
> +SA(__is_same(__remove_pointer(int), int));
> +SA(__is_same(__remove_pointer(int*), int));
> +SA(__is_same(__remove_pointer(int**), int*));
> +
> +SA(__is_same(__remove_pointer(const int*), const int));
> +SA(__is_same(__remove_pointer(const int**), const int*));
> +SA(__is_same(__remove_pointer(int* const), int));
> +SA(__is_same(__remove_pointer(int** const), int*));
> +SA(__is_same(__remove_pointer(int* const* const), int* const));
> +
> +SA(__is_same(__remove_pointer(volatile int*), volatile int));
> +SA(__is_same(__remove_pointer(volatile int**), volatile int*));
> +SA(__is_same(__remove_pointer(int* volatile), int));
> +SA(__is_same(__remove_pointer(int** volatile), int*));
> +SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
> +
> +SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
> +SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
> +SA(__is_same(__remove_pointer(const int* volatile), const int));
> +SA(__is_same(__remove_pointer(volatile int* const), volatile int));
> +SA(__is_same(__remove_pointer(int* const volatile), int));
> +SA(__is_same(__remove_pointer(const int** volatile), const int*));
> +SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
> +SA(__is_same(__remove_pointer(int** const volatile), int*));
> +SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
> +SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
> +SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
> +
> +SA(__is_same(__remove_pointer(int&), int&));
> +SA(__is_same(__remove_pointer(const int&), const int&));
> +SA(__is_same(__remove_pointer(volatile int&), volatile int&));
> +SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
> +
> +SA(__is_same(__remove_pointer(int&&), int&&));
> +SA(__is_same(__remove_pointer(const int&&), const int&&));
> +SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
> +SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
> +
> +SA(__is_same(__remove_pointer(int[3]), int[3]));
> +SA(__is_same(__remove_pointer(const int[3]), const int[3]));
> +SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
> +SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
> +
> +SA(__is_same(__remove_pointer(int(int)), int(int)));
> +SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
> +SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
> +SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
> --
> 2.41.0
>

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

* Re: [PATCH 1/2] c++: implement __remove_pointer built-in trait
  2023-06-17 12:35 ` [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
@ 2023-06-20 13:20   ` Ken Matsui
  2023-06-20 15:21   ` Patrick Palka
  1 sibling, 0 replies; 13+ messages in thread
From: Ken Matsui @ 2023-06-20 13:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++

Just a quick update, the benchmark code link has been updated and can
now be accessed at
https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer.cc.
I have also created a report file which can be found at
https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer.md.

On Sat, Jun 17, 2023 at 5:35 AM Ken Matsui <kmatsui@cs.washington.edu> wrote:
>
> Hi,
>
> I conducted a benchmark for remove_pointer as well as is_object. Just
> like the is_object benchmark, here is the benchmark code:
>
> https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer_benchmark.cc
>
> On my computer, using the gcc HEAD of this patch for a release build,
> the patch with -DUSE_BUILTIN took 8.7% less time and used 4.3-4.9%
> less memory on average compared to not using it. Although the
> performance improvement was not as significant as with is_object, the
> benchmark demonstrated that the compilation was consistently more
> efficient.
>
> Sincerely,
> Ken Matsui
>
> On Thu, Jun 15, 2023 at 5:22 AM Ken Matsui <kmatsui@cs.washington.edu> wrote:
> >
> > This patch implements built-in trait for std::remove_pointer.
> >
> > gcc/cp/ChangeLog:
> >
> >         * cp-trait.def: Define __remove_pointer.
> >         * semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
> >         * g++.dg/ext/remove_pointer.C: New test.
> >
> > Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
> > ---
> >  gcc/cp/cp-trait.def                       |  1 +
> >  gcc/cp/semantics.cc                       |  4 ++
> >  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
> >  gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
> >  4 files changed, 59 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C
> >
> > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > index 8b7fece0cc8..07823e55579 100644
> > --- a/gcc/cp/cp-trait.def
> > +++ b/gcc/cp/cp-trait.def
> > @@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> >  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> >  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> >  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> > +DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
> >  DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
> >  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> >
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 8fb47fd179e..885c7a6fb64 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -12373,6 +12373,10 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> >        if (TYPE_REF_P (type1))
> >         type1 = TREE_TYPE (type1);
> >        return cv_unqualified (type1);
> > +    case CPTK_REMOVE_POINTER:
> > +      if (TYPE_PTR_P (type1))
> > +    type1 = TREE_TYPE (type1);
> > +      return type1;
> >
> >      case CPTK_TYPE_PACK_ELEMENT:
> >        return finish_type_pack_element (type1, type2, complain);
> > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > index f343e153e56..e21e0a95509 100644
> > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > @@ -146,3 +146,6 @@
> >  #if !__has_builtin (__remove_cvref)
> >  # error "__has_builtin (__remove_cvref) failed"
> >  #endif
> > +#if !__has_builtin (__remove_pointer)
> > +# error "__has_builtin (__remove_pointer) failed"
> > +#endif
> > diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> > new file mode 100644
> > index 00000000000..7b13db93950
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> > @@ -0,0 +1,51 @@
> > +// { dg-do compile { target c++11 } }
> > +
> > +#define SA(X) static_assert((X),#X)
> > +
> > +SA(__is_same(__remove_pointer(int), int));
> > +SA(__is_same(__remove_pointer(int*), int));
> > +SA(__is_same(__remove_pointer(int**), int*));
> > +
> > +SA(__is_same(__remove_pointer(const int*), const int));
> > +SA(__is_same(__remove_pointer(const int**), const int*));
> > +SA(__is_same(__remove_pointer(int* const), int));
> > +SA(__is_same(__remove_pointer(int** const), int*));
> > +SA(__is_same(__remove_pointer(int* const* const), int* const));
> > +
> > +SA(__is_same(__remove_pointer(volatile int*), volatile int));
> > +SA(__is_same(__remove_pointer(volatile int**), volatile int*));
> > +SA(__is_same(__remove_pointer(int* volatile), int));
> > +SA(__is_same(__remove_pointer(int** volatile), int*));
> > +SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
> > +
> > +SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
> > +SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
> > +SA(__is_same(__remove_pointer(const int* volatile), const int));
> > +SA(__is_same(__remove_pointer(volatile int* const), volatile int));
> > +SA(__is_same(__remove_pointer(int* const volatile), int));
> > +SA(__is_same(__remove_pointer(const int** volatile), const int*));
> > +SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
> > +SA(__is_same(__remove_pointer(int** const volatile), int*));
> > +SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
> > +SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
> > +SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
> > +
> > +SA(__is_same(__remove_pointer(int&), int&));
> > +SA(__is_same(__remove_pointer(const int&), const int&));
> > +SA(__is_same(__remove_pointer(volatile int&), volatile int&));
> > +SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
> > +
> > +SA(__is_same(__remove_pointer(int&&), int&&));
> > +SA(__is_same(__remove_pointer(const int&&), const int&&));
> > +SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
> > +SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
> > +
> > +SA(__is_same(__remove_pointer(int[3]), int[3]));
> > +SA(__is_same(__remove_pointer(const int[3]), const int[3]));
> > +SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
> > +SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
> > +
> > +SA(__is_same(__remove_pointer(int(int)), int(int)));
> > +SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
> > +SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
> > +SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
> > --
> > 2.41.0
> >

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

* Re: [PATCH 1/2] c++: implement __remove_pointer built-in trait
  2023-06-17 12:35 ` [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  2023-06-20 13:20   ` Ken Matsui
@ 2023-06-20 15:21   ` Patrick Palka
  2023-06-24 10:07     ` Ken Matsui
  1 sibling, 1 reply; 13+ messages in thread
From: Patrick Palka @ 2023-06-20 15:21 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 7995 bytes --]

On Sat, 17 Jun 2023, Ken Matsui via Gcc-patches wrote:

> Hi,
> 
> I conducted a benchmark for remove_pointer as well as is_object. Just
> like the is_object benchmark, here is the benchmark code:
> 
> https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer_benchmark.cc
> 
> On my computer, using the gcc HEAD of this patch for a release build,
> the patch with -DUSE_BUILTIN took 8.7% less time and used 4.3-4.9%
> less memory on average compared to not using it. Although the
> performance improvement was not as significant as with is_object, the
> benchmark demonstrated that the compilation was consistently more
> efficient.

Thanks for the benchmark.  The improvement is lesser than I expected,
but that might be because the benchmark is "biased":

  template <std::size_t N, std::size_t Count = 256>
  struct Instantiator : Instantiator<N, Count - 1> {
      static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator>>);
  };

This only invokes remove_pointer_t on the non-pointer type Instantiator,
and so the benchmark doesn't factor in the performance of the trait when
invoked on pointer types, and traits typically will have different
performance characteristics depending on the kind of type it's given.

To more holistically assess the real-world performance of the trait the
benchmark should also consider pointer types and maybe also cv-qualified
types (given that the original implementation is in terms of
__remove_cv_t and thus performance of the original implementation may be
sensitive to cv-qualification).  So we should probably uniformly
benchmark these classes of types, via doing e.g.:

  static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator>>);
  static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator*>>);
  static_assert(!std::is_pointer_v<remove_pointer_t<const Instantiator>>);
  static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator* const>>);

(We could consider other kinds of types too, e.g. reference types and
integral types, but it seems clear based on the implementations being
benchmarked that performance won't be sensitive to reference-ness
or integral-ness.)

> 
> Sincerely,
> Ken Matsui
> 
> On Thu, Jun 15, 2023 at 5:22 AM Ken Matsui <kmatsui@cs.washington.edu> wrote:
> >
> > This patch implements built-in trait for std::remove_pointer.
> >
> > gcc/cp/ChangeLog:
> >
> >         * cp-trait.def: Define __remove_pointer.
> >         * semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
> >         * g++.dg/ext/remove_pointer.C: New test.
> >
> > Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
> > ---
> >  gcc/cp/cp-trait.def                       |  1 +
> >  gcc/cp/semantics.cc                       |  4 ++
> >  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
> >  gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
> >  4 files changed, 59 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C
> >
> > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > index 8b7fece0cc8..07823e55579 100644
> > --- a/gcc/cp/cp-trait.def
> > +++ b/gcc/cp/cp-trait.def
> > @@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> >  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> >  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> >  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> > +DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
> >  DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
> >  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> >
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 8fb47fd179e..885c7a6fb64 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -12373,6 +12373,10 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> >        if (TYPE_REF_P (type1))
> >         type1 = TREE_TYPE (type1);
> >        return cv_unqualified (type1);
> > +    case CPTK_REMOVE_POINTER:
> > +      if (TYPE_PTR_P (type1))
> > +    type1 = TREE_TYPE (type1);
> > +      return type1;

Maybe add a newline before the 'case' to visually separate it from the
previous 'case'?  LGTM otherwise, thanks!

> >
> >      case CPTK_TYPE_PACK_ELEMENT:
> >        return finish_type_pack_element (type1, type2, complain);
> > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > index f343e153e56..e21e0a95509 100644
> > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > @@ -146,3 +146,6 @@
> >  #if !__has_builtin (__remove_cvref)
> >  # error "__has_builtin (__remove_cvref) failed"
> >  #endif
> > +#if !__has_builtin (__remove_pointer)
> > +# error "__has_builtin (__remove_pointer) failed"
> > +#endif
> > diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> > new file mode 100644
> > index 00000000000..7b13db93950
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> > @@ -0,0 +1,51 @@
> > +// { dg-do compile { target c++11 } }
> > +
> > +#define SA(X) static_assert((X),#X)
> > +
> > +SA(__is_same(__remove_pointer(int), int));
> > +SA(__is_same(__remove_pointer(int*), int));
> > +SA(__is_same(__remove_pointer(int**), int*));
> > +
> > +SA(__is_same(__remove_pointer(const int*), const int));
> > +SA(__is_same(__remove_pointer(const int**), const int*));
> > +SA(__is_same(__remove_pointer(int* const), int));
> > +SA(__is_same(__remove_pointer(int** const), int*));
> > +SA(__is_same(__remove_pointer(int* const* const), int* const));
> > +
> > +SA(__is_same(__remove_pointer(volatile int*), volatile int));
> > +SA(__is_same(__remove_pointer(volatile int**), volatile int*));
> > +SA(__is_same(__remove_pointer(int* volatile), int));
> > +SA(__is_same(__remove_pointer(int** volatile), int*));
> > +SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
> > +
> > +SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
> > +SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
> > +SA(__is_same(__remove_pointer(const int* volatile), const int));
> > +SA(__is_same(__remove_pointer(volatile int* const), volatile int));
> > +SA(__is_same(__remove_pointer(int* const volatile), int));
> > +SA(__is_same(__remove_pointer(const int** volatile), const int*));
> > +SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
> > +SA(__is_same(__remove_pointer(int** const volatile), int*));
> > +SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
> > +SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
> > +SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
> > +
> > +SA(__is_same(__remove_pointer(int&), int&));
> > +SA(__is_same(__remove_pointer(const int&), const int&));
> > +SA(__is_same(__remove_pointer(volatile int&), volatile int&));
> > +SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
> > +
> > +SA(__is_same(__remove_pointer(int&&), int&&));
> > +SA(__is_same(__remove_pointer(const int&&), const int&&));
> > +SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
> > +SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
> > +
> > +SA(__is_same(__remove_pointer(int[3]), int[3]));
> > +SA(__is_same(__remove_pointer(const int[3]), const int[3]));
> > +SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
> > +SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
> > +
> > +SA(__is_same(__remove_pointer(int(int)), int(int)));
> > +SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
> > +SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
> > +SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
> > --
> > 2.41.0
> >
> 
> 

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

* Re: [PATCH 1/2] c++: implement __remove_pointer built-in trait
  2023-06-20 15:21   ` Patrick Palka
@ 2023-06-24 10:07     ` Ken Matsui
  2023-06-24 10:12       ` Ken Matsui
  0 siblings, 1 reply; 13+ messages in thread
From: Ken Matsui @ 2023-06-24 10:07 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches

On Tue, Jun 20, 2023 at 8:22 AM Patrick Palka <ppalka@redhat.com> wrote:
>
> On Sat, 17 Jun 2023, Ken Matsui via Gcc-patches wrote:
>
> > Hi,
> >
> > I conducted a benchmark for remove_pointer as well as is_object. Just
> > like the is_object benchmark, here is the benchmark code:
> >
> > https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer_benchmark.cc
> >
> > On my computer, using the gcc HEAD of this patch for a release build,
> > the patch with -DUSE_BUILTIN took 8.7% less time and used 4.3-4.9%
> > less memory on average compared to not using it. Although the
> > performance improvement was not as significant as with is_object, the
> > benchmark demonstrated that the compilation was consistently more
> > efficient.
>
> Thanks for the benchmark.  The improvement is lesser than I expected,
> but that might be because the benchmark is "biased":
>
>   template <std::size_t N, std::size_t Count = 256>
>   struct Instantiator : Instantiator<N, Count - 1> {
>       static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator>>);
>   };
>
> This only invokes remove_pointer_t on the non-pointer type Instantiator,
> and so the benchmark doesn't factor in the performance of the trait when
> invoked on pointer types, and traits typically will have different
> performance characteristics depending on the kind of type it's given.
>
> To more holistically assess the real-world performance of the trait the
> benchmark should also consider pointer types and maybe also cv-qualified
> types (given that the original implementation is in terms of
> __remove_cv_t and thus performance of the original implementation may be
> sensitive to cv-qualification).  So we should probably uniformly
> benchmark these classes of types, via doing e.g.:
>
>   static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator>>);
>   static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator*>>);
>   static_assert(!std::is_pointer_v<remove_pointer_t<const Instantiator>>);
>   static_assert(!std::is_pointer_v<remove_pointer_t<Instantiator* const>>);
>
> (We could consider other kinds of types too, e.g. reference types and
> integral types, but it seems clear based on the implementations being
> benchmarked that performance won't be sensitive to reference-ness
> or integral-ness.)

Thank you for your review! I totally agree with your opinion that the
benchmark should have been exhaustive. I conducted a benchmark for
this new change:

https://github.com/ken-matsui/gcc-benches/blob/main/remove_pointer.md#tue-jun-20-030313-pm-pdt-2023

Time: -27.918%
Peak Memory Usage: -19.0755%
Total Memory Usage: -20.0199%

> >
> > Sincerely,
> > Ken Matsui
> >
> > On Thu, Jun 15, 2023 at 5:22 AM Ken Matsui <kmatsui@cs.washington.edu> wrote:
> > >
> > > This patch implements built-in trait for std::remove_pointer.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >         * cp-trait.def: Define __remove_pointer.
> > >         * semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >         * g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
> > >         * g++.dg/ext/remove_pointer.C: New test.
> > >
> > > Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
> > > ---
> > >  gcc/cp/cp-trait.def                       |  1 +
> > >  gcc/cp/semantics.cc                       |  4 ++
> > >  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
> > >  gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
> > >  4 files changed, 59 insertions(+)
> > >  create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C
> > >
> > > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > > index 8b7fece0cc8..07823e55579 100644
> > > --- a/gcc/cp/cp-trait.def
> > > +++ b/gcc/cp/cp-trait.def
> > > @@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> > >  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> > >  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > >  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> > > +DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
> > >  DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
> > >  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> > >
> > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > > index 8fb47fd179e..885c7a6fb64 100644
> > > --- a/gcc/cp/semantics.cc
> > > +++ b/gcc/cp/semantics.cc
> > > @@ -12373,6 +12373,10 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> > >        if (TYPE_REF_P (type1))
> > >         type1 = TREE_TYPE (type1);
> > >        return cv_unqualified (type1);
> > > +    case CPTK_REMOVE_POINTER:
> > > +      if (TYPE_PTR_P (type1))
> > > +    type1 = TREE_TYPE (type1);
> > > +      return type1;
>
> Maybe add a newline before the 'case' to visually separate it from the
> previous 'case'?  LGTM otherwise, thanks!

Will do! Thank you!

> > >
> > >      case CPTK_TYPE_PACK_ELEMENT:
> > >        return finish_type_pack_element (type1, type2, complain);
> > > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > index f343e153e56..e21e0a95509 100644
> > > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > @@ -146,3 +146,6 @@
> > >  #if !__has_builtin (__remove_cvref)
> > >  # error "__has_builtin (__remove_cvref) failed"
> > >  #endif
> > > +#if !__has_builtin (__remove_pointer)
> > > +# error "__has_builtin (__remove_pointer) failed"
> > > +#endif
> > > diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> > > new file mode 100644
> > > index 00000000000..7b13db93950
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> > > @@ -0,0 +1,51 @@
> > > +// { dg-do compile { target c++11 } }
> > > +
> > > +#define SA(X) static_assert((X),#X)
> > > +
> > > +SA(__is_same(__remove_pointer(int), int));
> > > +SA(__is_same(__remove_pointer(int*), int));
> > > +SA(__is_same(__remove_pointer(int**), int*));
> > > +
> > > +SA(__is_same(__remove_pointer(const int*), const int));
> > > +SA(__is_same(__remove_pointer(const int**), const int*));
> > > +SA(__is_same(__remove_pointer(int* const), int));
> > > +SA(__is_same(__remove_pointer(int** const), int*));
> > > +SA(__is_same(__remove_pointer(int* const* const), int* const));
> > > +
> > > +SA(__is_same(__remove_pointer(volatile int*), volatile int));
> > > +SA(__is_same(__remove_pointer(volatile int**), volatile int*));
> > > +SA(__is_same(__remove_pointer(int* volatile), int));
> > > +SA(__is_same(__remove_pointer(int** volatile), int*));
> > > +SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
> > > +
> > > +SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
> > > +SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
> > > +SA(__is_same(__remove_pointer(const int* volatile), const int));
> > > +SA(__is_same(__remove_pointer(volatile int* const), volatile int));
> > > +SA(__is_same(__remove_pointer(int* const volatile), int));
> > > +SA(__is_same(__remove_pointer(const int** volatile), const int*));
> > > +SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
> > > +SA(__is_same(__remove_pointer(int** const volatile), int*));
> > > +SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
> > > +SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
> > > +SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
> > > +
> > > +SA(__is_same(__remove_pointer(int&), int&));
> > > +SA(__is_same(__remove_pointer(const int&), const int&));
> > > +SA(__is_same(__remove_pointer(volatile int&), volatile int&));
> > > +SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
> > > +
> > > +SA(__is_same(__remove_pointer(int&&), int&&));
> > > +SA(__is_same(__remove_pointer(const int&&), const int&&));
> > > +SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
> > > +SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
> > > +
> > > +SA(__is_same(__remove_pointer(int[3]), int[3]));
> > > +SA(__is_same(__remove_pointer(const int[3]), const int[3]));
> > > +SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
> > > +SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
> > > +
> > > +SA(__is_same(__remove_pointer(int(int)), int(int)));
> > > +SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
> > > +SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
> > > +SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
> > > --
> > > 2.41.0
> > >
> >
> >

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

* [PATCH 1/2] c++: implement __remove_pointer built-in trait
  2023-06-24 10:07     ` Ken Matsui
@ 2023-06-24 10:12       ` Ken Matsui
  2023-06-24 10:12         ` [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
  2023-07-08  5:29         ` [PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  0 siblings, 2 replies; 13+ messages in thread
From: Ken Matsui @ 2023-06-24 10:12 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
	* g++.dg/ext/remove_pointer.C: New test.

Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
---
 gcc/cp/cp-trait.def                       |  1 +
 gcc/cp/semantics.cc                       |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
 4 files changed, 60 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..07823e55579 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..a3b283ce938 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12374,6 +12374,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return cv_unqualified (type1);
 
+    case CPTK_REMOVE_POINTER:
+      if (TYPE_PTR_P (type1))
+    type1 = TREE_TYPE (type1);
+      return type1;
+
     case CPTK_TYPE_PACK_ELEMENT:
       return finish_type_pack_element (type1, type2, complain);
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..e21e0a95509 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_pointer)
+# error "__has_builtin (__remove_pointer) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
new file mode 100644
index 00000000000..7b13db93950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(__is_same(__remove_pointer(int), int));
+SA(__is_same(__remove_pointer(int*), int));
+SA(__is_same(__remove_pointer(int**), int*));
+
+SA(__is_same(__remove_pointer(const int*), const int));
+SA(__is_same(__remove_pointer(const int**), const int*));
+SA(__is_same(__remove_pointer(int* const), int));
+SA(__is_same(__remove_pointer(int** const), int*));
+SA(__is_same(__remove_pointer(int* const* const), int* const));
+
+SA(__is_same(__remove_pointer(volatile int*), volatile int));
+SA(__is_same(__remove_pointer(volatile int**), volatile int*));
+SA(__is_same(__remove_pointer(int* volatile), int));
+SA(__is_same(__remove_pointer(int** volatile), int*));
+SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
+
+SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
+SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
+SA(__is_same(__remove_pointer(const int* volatile), const int));
+SA(__is_same(__remove_pointer(volatile int* const), volatile int));
+SA(__is_same(__remove_pointer(int* const volatile), int));
+SA(__is_same(__remove_pointer(const int** volatile), const int*));
+SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
+SA(__is_same(__remove_pointer(int** const volatile), int*));
+SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
+SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
+SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
+
+SA(__is_same(__remove_pointer(int&), int&));
+SA(__is_same(__remove_pointer(const int&), const int&));
+SA(__is_same(__remove_pointer(volatile int&), volatile int&));
+SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
+
+SA(__is_same(__remove_pointer(int&&), int&&));
+SA(__is_same(__remove_pointer(const int&&), const int&&));
+SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
+SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
+
+SA(__is_same(__remove_pointer(int[3]), int[3]));
+SA(__is_same(__remove_pointer(const int[3]), const int[3]));
+SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
+SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
+
+SA(__is_same(__remove_pointer(int(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
-- 
2.41.0


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

* [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer
  2023-06-24 10:12       ` Ken Matsui
@ 2023-06-24 10:12         ` Ken Matsui
  2023-07-08  5:29         ` [PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  1 sibling, 0 replies; 13+ messages in thread
From: Ken Matsui @ 2023-06-24 10:12 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch lets libstdc++ use new built-in trait __remove_pointer.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_pointer): Use __remove_pointer built-in trait.

Signed-off-by: Ken Matsui <kmatsui@cs.washington.edu>
---
 libstdc++-v3/include/std/type_traits | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 0e7a9c9c7f3..81497e2f3e1 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2023,6 +2023,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if __has_builtin(__remove_pointer)
+  template<typename _Tp>
+    struct remove_pointer
+    { using type = __remove_pointer(_Tp); };
+#else
   template<typename _Tp, typename>
     struct __remove_pointer_helper
     { using type = _Tp; };
@@ -2031,11 +2037,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __remove_pointer_helper<_Tp, _Up*>
     { using type = _Up; };
 
-  /// remove_pointer
   template<typename _Tp>
     struct remove_pointer
     : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
     { };
+#endif
 
   template<typename _Tp, typename = void>
     struct __add_pointer_helper
-- 
2.41.0


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

* [PATCH v2 1/2] c++: implement __remove_pointer built-in trait
  2023-06-24 10:12       ` Ken Matsui
  2023-06-24 10:12         ` [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
@ 2023-07-08  5:29         ` Ken Matsui
  2023-07-08  5:29           ` [PATCH v2 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
  2023-09-04 15:00           ` [PING][PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  1 sibling, 2 replies; 13+ messages in thread
From: Ken Matsui @ 2023-07-08  5:29 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
	* g++.dg/ext/remove_pointer.C: New test.

Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
---
 gcc/cp/cp-trait.def                       |  1 +
 gcc/cp/semantics.cc                       |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
 4 files changed, 60 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..07823e55579 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..a3b283ce938 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12374,6 +12374,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return cv_unqualified (type1);
 
+    case CPTK_REMOVE_POINTER:
+      if (TYPE_PTR_P (type1))
+    type1 = TREE_TYPE (type1);
+      return type1;
+
     case CPTK_TYPE_PACK_ELEMENT:
       return finish_type_pack_element (type1, type2, complain);
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..e21e0a95509 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_pointer)
+# error "__has_builtin (__remove_pointer) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
new file mode 100644
index 00000000000..7b13db93950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(__is_same(__remove_pointer(int), int));
+SA(__is_same(__remove_pointer(int*), int));
+SA(__is_same(__remove_pointer(int**), int*));
+
+SA(__is_same(__remove_pointer(const int*), const int));
+SA(__is_same(__remove_pointer(const int**), const int*));
+SA(__is_same(__remove_pointer(int* const), int));
+SA(__is_same(__remove_pointer(int** const), int*));
+SA(__is_same(__remove_pointer(int* const* const), int* const));
+
+SA(__is_same(__remove_pointer(volatile int*), volatile int));
+SA(__is_same(__remove_pointer(volatile int**), volatile int*));
+SA(__is_same(__remove_pointer(int* volatile), int));
+SA(__is_same(__remove_pointer(int** volatile), int*));
+SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
+
+SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
+SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
+SA(__is_same(__remove_pointer(const int* volatile), const int));
+SA(__is_same(__remove_pointer(volatile int* const), volatile int));
+SA(__is_same(__remove_pointer(int* const volatile), int));
+SA(__is_same(__remove_pointer(const int** volatile), const int*));
+SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
+SA(__is_same(__remove_pointer(int** const volatile), int*));
+SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
+SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
+SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
+
+SA(__is_same(__remove_pointer(int&), int&));
+SA(__is_same(__remove_pointer(const int&), const int&));
+SA(__is_same(__remove_pointer(volatile int&), volatile int&));
+SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
+
+SA(__is_same(__remove_pointer(int&&), int&&));
+SA(__is_same(__remove_pointer(const int&&), const int&&));
+SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
+SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
+
+SA(__is_same(__remove_pointer(int[3]), int[3]));
+SA(__is_same(__remove_pointer(const int[3]), const int[3]));
+SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
+SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
+
+SA(__is_same(__remove_pointer(int(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
-- 
2.41.0


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

* [PATCH v2 2/2] libstdc++: use new built-in trait __remove_pointer
  2023-07-08  5:29         ` [PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
@ 2023-07-08  5:29           ` Ken Matsui
  2023-07-12 10:20             ` Jonathan Wakely
  2023-09-04 15:00           ` [PING][PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  1 sibling, 1 reply; 13+ messages in thread
From: Ken Matsui @ 2023-07-08  5:29 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch lets libstdc++ use new built-in trait __remove_pointer.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_pointer): Use __remove_pointer built-in trait.

Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
---
 libstdc++-v3/include/std/type_traits | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 0e7a9c9c7f3..81497e2f3e1 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2023,6 +2023,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if __has_builtin(__remove_pointer)
+  template<typename _Tp>
+    struct remove_pointer
+    { using type = __remove_pointer(_Tp); };
+#else
   template<typename _Tp, typename>
     struct __remove_pointer_helper
     { using type = _Tp; };
@@ -2031,11 +2037,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __remove_pointer_helper<_Tp, _Up*>
     { using type = _Up; };
 
-  /// remove_pointer
   template<typename _Tp>
     struct remove_pointer
     : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
     { };
+#endif
 
   template<typename _Tp, typename = void>
     struct __add_pointer_helper
-- 
2.41.0


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

* Re: [PATCH v2 2/2] libstdc++: use new built-in trait __remove_pointer
  2023-07-08  5:29           ` [PATCH v2 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
@ 2023-07-12 10:20             ` Jonathan Wakely
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Wakely @ 2023-07-12 10:20 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches, libstdc++

On Sat, 8 Jul 2023 at 06:31, Ken Matsui via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> This patch lets libstdc++ use new built-in trait __remove_pointer.
>
> libstdc++-v3/ChangeLog:
>
>         * include/std/type_traits (remove_pointer): Use __remove_pointer built-in trait.
>
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>

OK for trunk after the front-end __remove_pointer is committed.


> ---
>  libstdc++-v3/include/std/type_traits | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
> index 0e7a9c9c7f3..81497e2f3e1 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -2023,6 +2023,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>    // Pointer modifications.
>
> +  /// remove_pointer
> +#if __has_builtin(__remove_pointer)
> +  template<typename _Tp>
> +    struct remove_pointer
> +    { using type = __remove_pointer(_Tp); };
> +#else
>    template<typename _Tp, typename>
>      struct __remove_pointer_helper
>      { using type = _Tp; };
> @@ -2031,11 +2037,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      struct __remove_pointer_helper<_Tp, _Up*>
>      { using type = _Up; };
>
> -  /// remove_pointer
>    template<typename _Tp>
>      struct remove_pointer
>      : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
>      { };
> +#endif
>
>    template<typename _Tp, typename = void>
>      struct __add_pointer_helper
> --
> 2.41.0
>


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

* [PING][PATCH v2 1/2] c++: implement __remove_pointer built-in trait
  2023-07-08  5:29         ` [PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  2023-07-08  5:29           ` [PATCH v2 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
@ 2023-09-04 15:00           ` Ken Matsui
  1 sibling, 0 replies; 13+ messages in thread
From: Ken Matsui @ 2023-09-04 15:00 UTC (permalink / raw)
  To: jason; +Cc: gcc-patches, libstdc++, Ken Matsui

Ping for __remove_pointer built-in.

Sincerely,
Ken Matsui

On Fri, Jul 7, 2023 at 10:29 PM Ken Matsui <kmatsui@gcc.gnu.org> wrote:
>
> This patch implements built-in trait for std::remove_pointer.
>
> gcc/cp/ChangeLog:
>
>         * cp-trait.def: Define __remove_pointer.
>         * semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
>         * g++.dg/ext/remove_pointer.C: New test.
>
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> ---
>  gcc/cp/cp-trait.def                       |  1 +
>  gcc/cp/semantics.cc                       |  5 +++
>  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
>  gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
>  4 files changed, 60 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C
>
> diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> index 8b7fece0cc8..07823e55579 100644
> --- a/gcc/cp/cp-trait.def
> +++ b/gcc/cp/cp-trait.def
> @@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
>  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
>  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
>  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> +DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
>  DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
>  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
>
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 8fb47fd179e..a3b283ce938 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12374,6 +12374,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
>         type1 = TREE_TYPE (type1);
>        return cv_unqualified (type1);
>
> +    case CPTK_REMOVE_POINTER:
> +      if (TYPE_PTR_P (type1))
> +    type1 = TREE_TYPE (type1);
> +      return type1;
> +
>      case CPTK_TYPE_PACK_ELEMENT:
>        return finish_type_pack_element (type1, type2, complain);
>
> diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> index f343e153e56..e21e0a95509 100644
> --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> @@ -146,3 +146,6 @@
>  #if !__has_builtin (__remove_cvref)
>  # error "__has_builtin (__remove_cvref) failed"
>  #endif
> +#if !__has_builtin (__remove_pointer)
> +# error "__has_builtin (__remove_pointer) failed"
> +#endif
> diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> new file mode 100644
> index 00000000000..7b13db93950
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
> @@ -0,0 +1,51 @@
> +// { dg-do compile { target c++11 } }
> +
> +#define SA(X) static_assert((X),#X)
> +
> +SA(__is_same(__remove_pointer(int), int));
> +SA(__is_same(__remove_pointer(int*), int));
> +SA(__is_same(__remove_pointer(int**), int*));
> +
> +SA(__is_same(__remove_pointer(const int*), const int));
> +SA(__is_same(__remove_pointer(const int**), const int*));
> +SA(__is_same(__remove_pointer(int* const), int));
> +SA(__is_same(__remove_pointer(int** const), int*));
> +SA(__is_same(__remove_pointer(int* const* const), int* const));
> +
> +SA(__is_same(__remove_pointer(volatile int*), volatile int));
> +SA(__is_same(__remove_pointer(volatile int**), volatile int*));
> +SA(__is_same(__remove_pointer(int* volatile), int));
> +SA(__is_same(__remove_pointer(int** volatile), int*));
> +SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
> +
> +SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
> +SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
> +SA(__is_same(__remove_pointer(const int* volatile), const int));
> +SA(__is_same(__remove_pointer(volatile int* const), volatile int));
> +SA(__is_same(__remove_pointer(int* const volatile), int));
> +SA(__is_same(__remove_pointer(const int** volatile), const int*));
> +SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
> +SA(__is_same(__remove_pointer(int** const volatile), int*));
> +SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
> +SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
> +SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
> +
> +SA(__is_same(__remove_pointer(int&), int&));
> +SA(__is_same(__remove_pointer(const int&), const int&));
> +SA(__is_same(__remove_pointer(volatile int&), volatile int&));
> +SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
> +
> +SA(__is_same(__remove_pointer(int&&), int&&));
> +SA(__is_same(__remove_pointer(const int&&), const int&&));
> +SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
> +SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
> +
> +SA(__is_same(__remove_pointer(int[3]), int[3]));
> +SA(__is_same(__remove_pointer(const int[3]), const int[3]));
> +SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
> +SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
> +
> +SA(__is_same(__remove_pointer(int(int)), int(int)));
> +SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
> +SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
> +SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
> --
> 2.41.0
>

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

* [PATCH 1/2] c++: implement __remove_pointer built-in trait
@ 2023-03-20 22:22 Ken Matsui
  0 siblings, 0 replies; 13+ messages in thread
From: Ken Matsui @ 2023-03-20 22:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, ppalka, Ken Matsui

This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
	* g++.dg/ext/remove_pointer.C: New test.
---
 gcc/cp/cp-trait.def                       |  1 +
 gcc/cp/semantics.cc                       |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++++++++++++++++++++++
 4 files changed, 59 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index bac593c0094..985b43e0d97 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -90,6 +90,7 @@ DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE,  "__underlying_type", 1)
 
 /* These traits yield a type pack, not a type, and are represented by
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 87c2e8a7111..92db1f670ac 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12273,6 +12273,10 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2)
       if (TYPE_REF_P (type1))
 	type1 = TREE_TYPE (type1);
       return cv_unqualified (type1);
+    case CPTK_REMOVE_POINTER:
+      if (TYPE_PTR_P (type1))
+    type1 = TREE_TYPE (type1);
+      return type1;
 
 #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
     case CPTK_##CODE:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..e21e0a95509 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_pointer)
+# error "__has_builtin (__remove_pointer) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C b/gcc/testsuite/g++.dg/ext/remove_pointer.C
new file mode 100644
index 00000000000..7b13db93950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(__is_same(__remove_pointer(int), int));
+SA(__is_same(__remove_pointer(int*), int));
+SA(__is_same(__remove_pointer(int**), int*));
+
+SA(__is_same(__remove_pointer(const int*), const int));
+SA(__is_same(__remove_pointer(const int**), const int*));
+SA(__is_same(__remove_pointer(int* const), int));
+SA(__is_same(__remove_pointer(int** const), int*));
+SA(__is_same(__remove_pointer(int* const* const), int* const));
+
+SA(__is_same(__remove_pointer(volatile int*), volatile int));
+SA(__is_same(__remove_pointer(volatile int**), volatile int*));
+SA(__is_same(__remove_pointer(int* volatile), int));
+SA(__is_same(__remove_pointer(int** volatile), int*));
+SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
+
+SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
+SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
+SA(__is_same(__remove_pointer(const int* volatile), const int));
+SA(__is_same(__remove_pointer(volatile int* const), volatile int));
+SA(__is_same(__remove_pointer(int* const volatile), int));
+SA(__is_same(__remove_pointer(const int** volatile), const int*));
+SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
+SA(__is_same(__remove_pointer(int** const volatile), int*));
+SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
+SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
+SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const volatile));
+
+SA(__is_same(__remove_pointer(int&), int&));
+SA(__is_same(__remove_pointer(const int&), const int&));
+SA(__is_same(__remove_pointer(volatile int&), volatile int&));
+SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
+
+SA(__is_same(__remove_pointer(int&&), int&&));
+SA(__is_same(__remove_pointer(const int&&), const int&&));
+SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
+SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
+
+SA(__is_same(__remove_pointer(int[3]), int[3]));
+SA(__is_same(__remove_pointer(const int[3]), const int[3]));
+SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
+SA(__is_same(__remove_pointer(const volatile int[3]), const volatile int[3]));
+
+SA(__is_same(__remove_pointer(int(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*volatile)(int)), int(int)));
+SA(__is_same(__remove_pointer(int(*const volatile)(int)), int(int)));
-- 
2.40.0


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

end of thread, other threads:[~2023-09-04 15:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-15 12:21 [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
2023-06-15 12:21 ` [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
2023-06-17 12:35 ` [PATCH 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
2023-06-20 13:20   ` Ken Matsui
2023-06-20 15:21   ` Patrick Palka
2023-06-24 10:07     ` Ken Matsui
2023-06-24 10:12       ` Ken Matsui
2023-06-24 10:12         ` [PATCH 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
2023-07-08  5:29         ` [PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
2023-07-08  5:29           ` [PATCH v2 2/2] libstdc++: use new built-in trait __remove_pointer Ken Matsui
2023-07-12 10:20             ` Jonathan Wakely
2023-09-04 15:00           ` [PING][PATCH v2 1/2] c++: implement __remove_pointer built-in trait Ken Matsui
  -- strict thread matches above, loose matches on Subject: below --
2023-03-20 22:22 [PATCH " Ken Matsui

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