public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] c++: Implement __add_pointer built-in trait
@ 2024-02-14 11:44 Ken Matsui
  2024-02-14 11:44 ` [PATCH 2/2] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
  0 siblings, 2 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-14 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 394f006f20f..cec385ee501 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
 #define DEFTRAIT_TYPE_DEFAULTED
 #endif
 
+DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 57840176863..e23693ab57f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12760,6 +12760,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 
   switch (kind)
     {
+    case CPTK_ADD_POINTER:
+      if (TREE_CODE (type1) == FUNCTION_TYPE
+	  && ((TYPE_QUALS (type1) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
+	       || FUNCTION_REF_QUALIFIED (type1)))
+	return type1;
+      if (TYPE_REF_P (type1))
+	type1 = TREE_TYPE (type1);
+      return build_pointer_type (type1);
+
     case CPTK_REMOVE_CV:
       return cv_unqualified (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C
new file mode 100644
index 00000000000..3091510f3b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
@@ -0,0 +1,37 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_pointer(int), int*));
+SA(__is_same(__add_pointer(int*), int**));
+SA(__is_same(__add_pointer(const int), const int*));
+SA(__is_same(__add_pointer(int&), int*));
+SA(__is_same(__add_pointer(ClassType*), ClassType**));
+SA(__is_same(__add_pointer(ClassType), ClassType*));
+SA(__is_same(__add_pointer(void), void*));
+SA(__is_same(__add_pointer(const void), const void*));
+SA(__is_same(__add_pointer(volatile void), volatile void*));
+SA(__is_same(__add_pointer(const volatile void), const volatile void*));
+
+void f1();
+using f1_type = decltype(f1);
+using pf1_type = decltype(&f1);
+SA(__is_same(__add_pointer(f1_type), pf1_type));
+
+void f2() noexcept; // PR libstdc++/78361
+using f2_type = decltype(f2);
+using pf2_type = decltype(&f2);
+SA(__is_same(__add_pointer(f2_type), pf2_type));
+
+using fn_type = void();
+using pfn_type = void(*)();
+SA(__is_same(__add_pointer(fn_type), pfn_type));
+
+SA(__is_same(__add_pointer(void() &), void() &));
+SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
+SA(__is_same(__add_pointer(void() const), void() const));
+SA(__is_same(__add_pointer(void(...) &), void(...) &));
+SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
+SA(__is_same(__add_pointer(void(...) const), void(...) const));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 02b4b4d745d..56e8db7ac32 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
 // { dg-do compile }
 // Verify that __has_builtin gives the correct answer for C++ built-ins.
 
+#if !__has_builtin (__add_pointer)
+# error "__has_builtin (__add_pointer) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH 2/2] libstdc++: Optimize std::add_pointer compilation performance
  2024-02-14 11:44 [PATCH 1/2] c++: Implement __add_pointer built-in trait Ken Matsui
@ 2024-02-14 11:44 ` Ken Matsui
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
  1 sibling, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-14 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::add_pointer
by dispatching to the new __add_pointer built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_pointer): Use __add_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 21402fd8c13..3bde7cb8ba3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2121,6 +2121,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { };
 #endif
 
+  /// add_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer)
+  template<typename _Tp>
+    struct add_pointer
+    { using type = __add_pointer(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_pointer_helper
     { using type = _Tp; };
@@ -2129,7 +2135,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
     { using type = _Tp*; };
 
-  /// add_pointer
   template<typename _Tp>
     struct add_pointer
     : public __add_pointer_helper<_Tp>
@@ -2142,6 +2147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct add_pointer<_Tp&&>
     { using type = _Tp*; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_pointer
-- 
2.43.0


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

* [PATCH v2 1/4] c++: Implement __add_pointer built-in trait
  2024-02-14 11:44 [PATCH 1/2] c++: Implement __add_pointer built-in trait Ken Matsui
  2024-02-14 11:44 ` [PATCH 2/2] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
@ 2024-02-14 13:52 ` Ken Matsui
  2024-02-14 13:52   ` [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
                     ` (4 more replies)
  1 sibling, 5 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-14 13:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 394f006f20f..cec385ee501 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
 #define DEFTRAIT_TYPE_DEFAULTED
 #endif
 
+DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 57840176863..e23693ab57f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12760,6 +12760,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 
   switch (kind)
     {
+    case CPTK_ADD_POINTER:
+      if (TREE_CODE (type1) == FUNCTION_TYPE
+	  && ((TYPE_QUALS (type1) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
+	       || FUNCTION_REF_QUALIFIED (type1)))
+	return type1;
+      if (TYPE_REF_P (type1))
+	type1 = TREE_TYPE (type1);
+      return build_pointer_type (type1);
+
     case CPTK_REMOVE_CV:
       return cv_unqualified (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C
new file mode 100644
index 00000000000..3091510f3b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
@@ -0,0 +1,37 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_pointer(int), int*));
+SA(__is_same(__add_pointer(int*), int**));
+SA(__is_same(__add_pointer(const int), const int*));
+SA(__is_same(__add_pointer(int&), int*));
+SA(__is_same(__add_pointer(ClassType*), ClassType**));
+SA(__is_same(__add_pointer(ClassType), ClassType*));
+SA(__is_same(__add_pointer(void), void*));
+SA(__is_same(__add_pointer(const void), const void*));
+SA(__is_same(__add_pointer(volatile void), volatile void*));
+SA(__is_same(__add_pointer(const volatile void), const volatile void*));
+
+void f1();
+using f1_type = decltype(f1);
+using pf1_type = decltype(&f1);
+SA(__is_same(__add_pointer(f1_type), pf1_type));
+
+void f2() noexcept; // PR libstdc++/78361
+using f2_type = decltype(f2);
+using pf2_type = decltype(&f2);
+SA(__is_same(__add_pointer(f2_type), pf2_type));
+
+using fn_type = void();
+using pfn_type = void(*)();
+SA(__is_same(__add_pointer(fn_type), pfn_type));
+
+SA(__is_same(__add_pointer(void() &), void() &));
+SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
+SA(__is_same(__add_pointer(void() const), void() const));
+SA(__is_same(__add_pointer(void(...) &), void(...) &));
+SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
+SA(__is_same(__add_pointer(void(...) const), void(...) const));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 02b4b4d745d..56e8db7ac32 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
 // { dg-do compile }
 // Verify that __has_builtin gives the correct answer for C++ built-ins.
 
+#if !__has_builtin (__add_pointer)
+# error "__has_builtin (__add_pointer) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
@ 2024-02-14 13:52   ` Ken Matsui
  2024-02-14 20:20     ` Patrick Palka
  2024-02-14 13:52   ` [PATCH v2 3/4] c++: Implement __remove_extent built-in trait Ken Matsui
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 38+ messages in thread
From: Ken Matsui @ 2024-02-14 13:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::add_pointer
by dispatching to the new __add_pointer built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_pointer): Use __add_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 21402fd8c13..3bde7cb8ba3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2121,6 +2121,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { };
 #endif
 
+  /// add_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer)
+  template<typename _Tp>
+    struct add_pointer
+    { using type = __add_pointer(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_pointer_helper
     { using type = _Tp; };
@@ -2129,7 +2135,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
     { using type = _Tp*; };
 
-  /// add_pointer
   template<typename _Tp>
     struct add_pointer
     : public __add_pointer_helper<_Tp>
@@ -2142,6 +2147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct add_pointer<_Tp&&>
     { using type = _Tp*; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_pointer
-- 
2.43.0


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

* [PATCH v2 3/4] c++: Implement __remove_extent built-in trait
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
  2024-02-14 13:52   ` [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
@ 2024-02-14 13:52   ` Ken Matsui
  2024-02-14 20:20     ` Patrick Palka
  2024-02-14 13:52   ` [PATCH v2 4/4] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 38+ messages in thread
From: Ken Matsui @ 2024-02-14 13:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_extent.
	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_EXTENT.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_extent.
	* g++.dg/ext/remove_extent.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_extent.C | 16 ++++++++++++++++
 4 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_extent.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index cec385ee501..3ff5611b60e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -96,6 +96,7 @@ DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_tempo
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1)
 DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index e23693ab57f..bf998377c88 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12777,6 +12777,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return cv_unqualified (type1);
 
+    case CPTK_REMOVE_EXTENT:
+      if (TREE_CODE (type1) == ARRAY_TYPE)
+	type1 = TREE_TYPE (type1);
+      return type1;
+
     case CPTK_REMOVE_POINTER:
       if (TYPE_PTR_P (type1))
 	type1 = TREE_TYPE (type1);
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 56e8db7ac32..4f1094befb9 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -170,6 +170,9 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_extent)
+# error "__has_builtin (__remove_extent) failed"
+#endif
 #if !__has_builtin (__remove_pointer)
 # error "__has_builtin (__remove_pointer) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_extent.C b/gcc/testsuite/g++.dg/ext/remove_extent.C
new file mode 100644
index 00000000000..6183aca5a48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_extent.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__remove_extent(int), int));
+SA(__is_same(__remove_extent(int[2]), int));
+SA(__is_same(__remove_extent(int[2][3]), int[3]));
+SA(__is_same(__remove_extent(int[][3]), int[3]));
+SA(__is_same(__remove_extent(const int[2]), const int));
+SA(__is_same(__remove_extent(ClassType), ClassType));
+SA(__is_same(__remove_extent(ClassType[2]), ClassType));
+SA(__is_same(__remove_extent(ClassType[2][3]), ClassType[3]));
+SA(__is_same(__remove_extent(ClassType[][3]), ClassType[3]));
+SA(__is_same(__remove_extent(const ClassType[2]), const ClassType));
-- 
2.43.0


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

* [PATCH v2 4/4] libstdc++: Optimize std::remove_extent compilation performance
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
  2024-02-14 13:52   ` [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
  2024-02-14 13:52   ` [PATCH v2 3/4] c++: Implement __remove_extent built-in trait Ken Matsui
@ 2024-02-14 13:52   ` Ken Matsui
  2024-02-14 20:21     ` Patrick Palka
  2024-02-14 20:18   ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Patrick Palka
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
  4 siblings, 1 reply; 38+ messages in thread
From: Ken Matsui @ 2024-02-14 13:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::remove_extent
by dispatching to the new __remove_extent built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_extent): Use __remove_extent
	built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 3bde7cb8ba3..0fb1762186c 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2064,6 +2064,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Array modifications.
 
   /// remove_extent
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent)
+  template<typename _Tp>
+    struct remove_extent
+    { using type = __remove_extent(_Tp); };
+#else
   template<typename _Tp>
     struct remove_extent
     { using type = _Tp; };
@@ -2075,6 +2080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct remove_extent<_Tp[]>
     { using type = _Tp; };
+#endif
 
   /// remove_all_extents
   template<typename _Tp>
-- 
2.43.0


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

* Re: [PATCH v2 1/4] c++: Implement __add_pointer built-in trait
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
                     ` (2 preceding siblings ...)
  2024-02-14 13:52   ` [PATCH v2 4/4] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
@ 2024-02-14 20:18   ` Patrick Palka
  2024-02-15  4:17     ` Ken Matsui
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
  4 siblings, 1 reply; 38+ messages in thread
From: Patrick Palka @ 2024-02-14 20:18 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches, libstdc++

On Wed, 14 Feb 2024, Ken Matsui wrote:

> This patch implements built-in trait for std::add_pointer.
> 
> gcc/cp/ChangeLog:
> 
> 	* cp-trait.def: Define __add_pointer.
> 	* semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/has-builtin-1.C: Test existence of __add_pointer.
> 	* g++.dg/ext/add_pointer.C: New test.
> 
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> ---
>  gcc/cp/cp-trait.def                      |  1 +
>  gcc/cp/semantics.cc                      |  9 ++++++
>  gcc/testsuite/g++.dg/ext/add_pointer.C   | 37 ++++++++++++++++++++++++
>  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
>  4 files changed, 50 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/ext/add_pointer.C
> 
> diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> index 394f006f20f..cec385ee501 100644
> --- a/gcc/cp/cp-trait.def
> +++ b/gcc/cp/cp-trait.def
> @@ -48,6 +48,7 @@
>  #define DEFTRAIT_TYPE_DEFAULTED
>  #endif
>  
> +DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
>  DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
>  DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
>  DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 57840176863..e23693ab57f 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12760,6 +12760,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
>  
>    switch (kind)
>      {
> +    case CPTK_ADD_POINTER:
> +      if (TREE_CODE (type1) == FUNCTION_TYPE
> +	  && ((TYPE_QUALS (type1) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
> +	       || FUNCTION_REF_QUALIFIED (type1)))

In other parts of the front end, e.g. the POINTER_TYPE case of tsubst, in
build_trait_object, grokdeclarator and get_typeid, it seems we check for
an unqualified function type with

  (type_memfn_quals (type) != TYPE_UNQUALIFIED
   && type_mem_rqual (type) != REF_QUAL_NONE)

which should be equivalent to your formulation except it also checks
for non-standard qualifiers such as __restrict.

I'm not sure what a __restrict-qualified function type means or if we
care about the semantics of __add_pointer(void () __restrict), but I
reckon we might as well be consistent and use the type_mem_quals/rqual
formulation in new code too?

> +	return type1;
> +      if (TYPE_REF_P (type1))
> +	type1 = TREE_TYPE (type1);
> +      return build_pointer_type (type1);
> +
>      case CPTK_REMOVE_CV:
>        return cv_unqualified (type1);
>  
> diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C
> new file mode 100644
> index 00000000000..3091510f3b5
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
> @@ -0,0 +1,37 @@
> +// { dg-do compile { target c++11 } }
> +
> +#define SA(X) static_assert((X),#X)
> +
> +class ClassType { };
> +
> +SA(__is_same(__add_pointer(int), int*));
> +SA(__is_same(__add_pointer(int*), int**));
> +SA(__is_same(__add_pointer(const int), const int*));
> +SA(__is_same(__add_pointer(int&), int*));
> +SA(__is_same(__add_pointer(ClassType*), ClassType**));
> +SA(__is_same(__add_pointer(ClassType), ClassType*));
> +SA(__is_same(__add_pointer(void), void*));
> +SA(__is_same(__add_pointer(const void), const void*));
> +SA(__is_same(__add_pointer(volatile void), volatile void*));
> +SA(__is_same(__add_pointer(const volatile void), const volatile void*));
> +
> +void f1();
> +using f1_type = decltype(f1);
> +using pf1_type = decltype(&f1);
> +SA(__is_same(__add_pointer(f1_type), pf1_type));
> +
> +void f2() noexcept; // PR libstdc++/78361
> +using f2_type = decltype(f2);
> +using pf2_type = decltype(&f2);
> +SA(__is_same(__add_pointer(f2_type), pf2_type));
> +
> +using fn_type = void();
> +using pfn_type = void(*)();
> +SA(__is_same(__add_pointer(fn_type), pfn_type));
> +
> +SA(__is_same(__add_pointer(void() &), void() &));
> +SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
> +SA(__is_same(__add_pointer(void() const), void() const));
> +SA(__is_same(__add_pointer(void(...) &), void(...) &));
> +SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
> +SA(__is_same(__add_pointer(void(...) const), void(...) const));
> diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> index 02b4b4d745d..56e8db7ac32 100644
> --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> @@ -2,6 +2,9 @@
>  // { dg-do compile }
>  // Verify that __has_builtin gives the correct answer for C++ built-ins.
>  
> +#if !__has_builtin (__add_pointer)
> +# error "__has_builtin (__add_pointer) failed"
> +#endif
>  #if !__has_builtin (__builtin_addressof)
>  # error "__has_builtin (__builtin_addressof) failed"
>  #endif
> -- 
> 2.43.0
> 
> 


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

* Re: [PATCH v2 3/4] c++: Implement __remove_extent built-in trait
  2024-02-14 13:52   ` [PATCH v2 3/4] c++: Implement __remove_extent built-in trait Ken Matsui
@ 2024-02-14 20:20     ` Patrick Palka
  0 siblings, 0 replies; 38+ messages in thread
From: Patrick Palka @ 2024-02-14 20:20 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches, libstdc++

On Wed, 14 Feb 2024, Ken Matsui wrote:

> This patch implements built-in trait for std::remove_extent.
> 
> gcc/cp/ChangeLog:
> 
> 	* cp-trait.def: Define __remove_extent.
> 	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_EXTENT.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_extent.
> 	* g++.dg/ext/remove_extent.C: New test.

LGTM

> 
> 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_extent.C | 16 ++++++++++++++++
>  4 files changed, 25 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/ext/remove_extent.C
> 
> diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> index cec385ee501..3ff5611b60e 100644
> --- a/gcc/cp/cp-trait.def
> +++ b/gcc/cp/cp-trait.def
> @@ -96,6 +96,7 @@ DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_tempo
>  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
>  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
>  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> +DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1)
>  DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
>  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
>  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index e23693ab57f..bf998377c88 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12777,6 +12777,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
>  	type1 = TREE_TYPE (type1);
>        return cv_unqualified (type1);
>  
> +    case CPTK_REMOVE_EXTENT:
> +      if (TREE_CODE (type1) == ARRAY_TYPE)
> +	type1 = TREE_TYPE (type1);
> +      return type1;
> +
>      case CPTK_REMOVE_POINTER:
>        if (TYPE_PTR_P (type1))
>  	type1 = TREE_TYPE (type1);
> diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> index 56e8db7ac32..4f1094befb9 100644
> --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> @@ -170,6 +170,9 @@
>  #if !__has_builtin (__remove_cvref)
>  # error "__has_builtin (__remove_cvref) failed"
>  #endif
> +#if !__has_builtin (__remove_extent)
> +# error "__has_builtin (__remove_extent) failed"
> +#endif
>  #if !__has_builtin (__remove_pointer)
>  # error "__has_builtin (__remove_pointer) failed"
>  #endif
> diff --git a/gcc/testsuite/g++.dg/ext/remove_extent.C b/gcc/testsuite/g++.dg/ext/remove_extent.C
> new file mode 100644
> index 00000000000..6183aca5a48
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/remove_extent.C
> @@ -0,0 +1,16 @@
> +// { dg-do compile { target c++11 } }
> +
> +#define SA(X) static_assert((X),#X)
> +
> +class ClassType { };
> +
> +SA(__is_same(__remove_extent(int), int));
> +SA(__is_same(__remove_extent(int[2]), int));
> +SA(__is_same(__remove_extent(int[2][3]), int[3]));
> +SA(__is_same(__remove_extent(int[][3]), int[3]));
> +SA(__is_same(__remove_extent(const int[2]), const int));
> +SA(__is_same(__remove_extent(ClassType), ClassType));
> +SA(__is_same(__remove_extent(ClassType[2]), ClassType));
> +SA(__is_same(__remove_extent(ClassType[2][3]), ClassType[3]));
> +SA(__is_same(__remove_extent(ClassType[][3]), ClassType[3]));
> +SA(__is_same(__remove_extent(const ClassType[2]), const ClassType));
> -- 
> 2.43.0
> 
> 


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

* Re: [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance
  2024-02-14 13:52   ` [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
@ 2024-02-14 20:20     ` Patrick Palka
  0 siblings, 0 replies; 38+ messages in thread
From: Patrick Palka @ 2024-02-14 20:20 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches, libstdc++

On Wed, 14 Feb 2024, Ken Matsui wrote:

> This patch optimizes the compilation performance of std::add_pointer
> by dispatching to the new __add_pointer built-in trait.
> 
> libstdc++-v3/ChangeLog:
> 
> 	* include/std/type_traits (add_pointer): Use __add_pointer
> 	built-in trait.

LGTM

> 
> 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 21402fd8c13..3bde7cb8ba3 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -2121,6 +2121,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      { };
>  #endif
>  
> +  /// add_pointer
> +#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer)
> +  template<typename _Tp>
> +    struct add_pointer
> +    { using type = __add_pointer(_Tp); };
> +#else
>    template<typename _Tp, typename = void>
>      struct __add_pointer_helper
>      { using type = _Tp; };
> @@ -2129,7 +2135,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
>      { using type = _Tp*; };
>  
> -  /// add_pointer
>    template<typename _Tp>
>      struct add_pointer
>      : public __add_pointer_helper<_Tp>
> @@ -2142,6 +2147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    template<typename _Tp>
>      struct add_pointer<_Tp&&>
>      { using type = _Tp*; };
> +#endif
>  
>  #if __cplusplus > 201103L
>    /// Alias template for remove_pointer
> -- 
> 2.43.0
> 
> 


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

* Re: [PATCH v2 4/4] libstdc++: Optimize std::remove_extent compilation performance
  2024-02-14 13:52   ` [PATCH v2 4/4] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
@ 2024-02-14 20:21     ` Patrick Palka
  0 siblings, 0 replies; 38+ messages in thread
From: Patrick Palka @ 2024-02-14 20:21 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches, libstdc++

On Wed, 14 Feb 2024, Ken Matsui wrote:

> This patch optimizes the compilation performance of std::remove_extent
> by dispatching to the new __remove_extent built-in trait.
> 
> libstdc++-v3/ChangeLog:
> 
> 	* include/std/type_traits (remove_extent): Use __remove_extent
> 	built-in trait.

LGTM

> 
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> ---
>  libstdc++-v3/include/std/type_traits | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
> index 3bde7cb8ba3..0fb1762186c 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -2064,6 +2064,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    // Array modifications.
>  
>    /// remove_extent
> +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent)
> +  template<typename _Tp>
> +    struct remove_extent
> +    { using type = __remove_extent(_Tp); };
> +#else
>    template<typename _Tp>
>      struct remove_extent
>      { using type = _Tp; };
> @@ -2075,6 +2080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    template<typename _Tp>
>      struct remove_extent<_Tp[]>
>      { using type = _Tp; };
> +#endif
>  
>    /// remove_all_extents
>    template<typename _Tp>
> -- 
> 2.43.0
> 
> 


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

* Re: [PATCH v2 1/4] c++: Implement __add_pointer built-in trait
  2024-02-14 20:18   ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Patrick Palka
@ 2024-02-15  4:17     ` Ken Matsui
  0 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15  4:17 UTC (permalink / raw)
  To: Patrick Palka; +Cc: Ken Matsui, gcc-patches, libstdc++

On Wed, Feb 14, 2024 at 12:19 PM Patrick Palka <ppalka@redhat.com> wrote:
>
> On Wed, 14 Feb 2024, Ken Matsui wrote:
>
> > This patch implements built-in trait for std::add_pointer.
> >
> > gcc/cp/ChangeLog:
> >
> >       * cp-trait.def: Define __add_pointer.
> >       * semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * g++.dg/ext/has-builtin-1.C: Test existence of __add_pointer.
> >       * g++.dg/ext/add_pointer.C: New test.
> >
> > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > ---
> >  gcc/cp/cp-trait.def                      |  1 +
> >  gcc/cp/semantics.cc                      |  9 ++++++
> >  gcc/testsuite/g++.dg/ext/add_pointer.C   | 37 ++++++++++++++++++++++++
> >  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
> >  4 files changed, 50 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/ext/add_pointer.C
> >
> > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > index 394f006f20f..cec385ee501 100644
> > --- a/gcc/cp/cp-trait.def
> > +++ b/gcc/cp/cp-trait.def
> > @@ -48,6 +48,7 @@
> >  #define DEFTRAIT_TYPE_DEFAULTED
> >  #endif
> >
> > +DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
> >  DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
> >  DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
> >  DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 57840176863..e23693ab57f 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -12760,6 +12760,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> >
> >    switch (kind)
> >      {
> > +    case CPTK_ADD_POINTER:
> > +      if (TREE_CODE (type1) == FUNCTION_TYPE
> > +       && ((TYPE_QUALS (type1) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
> > +            || FUNCTION_REF_QUALIFIED (type1)))
>
> In other parts of the front end, e.g. the POINTER_TYPE case of tsubst, in
> build_trait_object, grokdeclarator and get_typeid, it seems we check for
> an unqualified function type with
>
>   (type_memfn_quals (type) != TYPE_UNQUALIFIED
>    && type_mem_rqual (type) != REF_QUAL_NONE)
>
> which should be equivalent to your formulation except it also checks
> for non-standard qualifiers such as __restrict.
>
> I'm not sure what a __restrict-qualified function type means or if we
> care about the semantics of __add_pointer(void () __restrict), but I
> reckon we might as well be consistent and use the type_mem_quals/rqual
> formulation in new code too?
>

I see and agree.  Thank you for your review!  I will update this patch.

> > +     return type1;
> > +      if (TYPE_REF_P (type1))
> > +     type1 = TREE_TYPE (type1);
> > +      return build_pointer_type (type1);
> > +
> >      case CPTK_REMOVE_CV:
> >        return cv_unqualified (type1);
> >
> > diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C
> > new file mode 100644
> > index 00000000000..3091510f3b5
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
> > @@ -0,0 +1,37 @@
> > +// { dg-do compile { target c++11 } }
> > +
> > +#define SA(X) static_assert((X),#X)
> > +
> > +class ClassType { };
> > +
> > +SA(__is_same(__add_pointer(int), int*));
> > +SA(__is_same(__add_pointer(int*), int**));
> > +SA(__is_same(__add_pointer(const int), const int*));
> > +SA(__is_same(__add_pointer(int&), int*));
> > +SA(__is_same(__add_pointer(ClassType*), ClassType**));
> > +SA(__is_same(__add_pointer(ClassType), ClassType*));
> > +SA(__is_same(__add_pointer(void), void*));
> > +SA(__is_same(__add_pointer(const void), const void*));
> > +SA(__is_same(__add_pointer(volatile void), volatile void*));
> > +SA(__is_same(__add_pointer(const volatile void), const volatile void*));
> > +
> > +void f1();
> > +using f1_type = decltype(f1);
> > +using pf1_type = decltype(&f1);
> > +SA(__is_same(__add_pointer(f1_type), pf1_type));
> > +
> > +void f2() noexcept; // PR libstdc++/78361
> > +using f2_type = decltype(f2);
> > +using pf2_type = decltype(&f2);
> > +SA(__is_same(__add_pointer(f2_type), pf2_type));
> > +
> > +using fn_type = void();
> > +using pfn_type = void(*)();
> > +SA(__is_same(__add_pointer(fn_type), pfn_type));
> > +
> > +SA(__is_same(__add_pointer(void() &), void() &));
> > +SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
> > +SA(__is_same(__add_pointer(void() const), void() const));
> > +SA(__is_same(__add_pointer(void(...) &), void(...) &));
> > +SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
> > +SA(__is_same(__add_pointer(void(...) const), void(...) const));
> > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > index 02b4b4d745d..56e8db7ac32 100644
> > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > @@ -2,6 +2,9 @@
> >  // { dg-do compile }
> >  // Verify that __has_builtin gives the correct answer for C++ built-ins.
> >
> > +#if !__has_builtin (__add_pointer)
> > +# error "__has_builtin (__add_pointer) failed"
> > +#endif
> >  #if !__has_builtin (__builtin_addressof)
> >  # error "__has_builtin (__builtin_addressof) failed"
> >  #endif
> > --
> > 2.43.0
> >
> >
>

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

* [PATCH v3 1/4] c++: Implement __add_pointer built-in trait
  2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
                     ` (3 preceding siblings ...)
  2024-02-14 20:18   ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Patrick Palka
@ 2024-02-15  4:52   ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 05/12] c++: Implement __remove_all_extents " Ken Matsui
                       ` (8 more replies)
  4 siblings, 9 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15  4:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 394f006f20f..cec385ee501 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
 #define DEFTRAIT_TYPE_DEFAULTED
 #endif
 
+DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 57840176863..8dc975495a8 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12760,6 +12760,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 
   switch (kind)
     {
+    case CPTK_ADD_POINTER:
+      if (FUNC_OR_METHOD_TYPE_P (type1)
+	  && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+	      || type_memfn_rqual (type1) != REF_QUAL_NONE))
+	return type1;
+      if (TYPE_REF_P (type1))
+	type1 = TREE_TYPE (type1);
+      return build_pointer_type (type1);
+
     case CPTK_REMOVE_CV:
       return cv_unqualified (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C
new file mode 100644
index 00000000000..c405cdd0feb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
@@ -0,0 +1,39 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_pointer(int), int*));
+SA(__is_same(__add_pointer(int*), int**));
+SA(__is_same(__add_pointer(const int), const int*));
+SA(__is_same(__add_pointer(int&), int*));
+SA(__is_same(__add_pointer(ClassType*), ClassType**));
+SA(__is_same(__add_pointer(ClassType), ClassType*));
+SA(__is_same(__add_pointer(void), void*));
+SA(__is_same(__add_pointer(const void), const void*));
+SA(__is_same(__add_pointer(volatile void), volatile void*));
+SA(__is_same(__add_pointer(const volatile void), const volatile void*));
+
+void f1();
+using f1_type = decltype(f1);
+using pf1_type = decltype(&f1);
+SA(__is_same(__add_pointer(f1_type), pf1_type));
+
+void f2() noexcept; // PR libstdc++/78361
+using f2_type = decltype(f2);
+using pf2_type = decltype(&f2);
+SA(__is_same(__add_pointer(f2_type), pf2_type));
+
+using fn_type = void();
+using pfn_type = void(*)();
+SA(__is_same(__add_pointer(fn_type), pfn_type));
+
+SA(__is_same(__add_pointer(void() &), void() &));
+SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
+SA(__is_same(__add_pointer(void() const), void() const));
+SA(__is_same(__add_pointer(void(...) &), void(...) &));
+SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
+SA(__is_same(__add_pointer(void(...) const), void(...) const));
+
+SA(__is_same(__add_pointer(void() __restrict), void() __restrict));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 02b4b4d745d..56e8db7ac32 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
 // { dg-do compile }
 // Verify that __has_builtin gives the correct answer for C++ built-ins.
 
+#if !__has_builtin (__add_pointer)
+# error "__has_builtin (__add_pointer) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v4 05/12] c++: Implement __remove_all_extents built-in trait
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 06/12] libstdc++: Optimize std::remove_all_extents compilation performance Ken Matsui
                       ` (7 subsequent siblings)
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_all_extents.
	* semantics.cc (finish_trait_type): Handle
	CPTK_REMOVE_ALL_EXTENTS.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 3ff5611b60e..ce29108bad6 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -94,6 +94,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
+DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
 DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 6ab054b106a..c8ac5167c3c 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12769,6 +12769,9 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return build_pointer_type (type1);
 
+    case CPTK_REMOVE_ALL_EXTENTS:
+      return strip_array_types (type1);
+
     case CPTK_REMOVE_CV:
       return cv_unqualified (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4f1094befb9..9af64173524 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -164,6 +164,9 @@
 #if !__has_builtin (__reference_converts_from_temporary)
 # error "__has_builtin (__reference_converts_from_temporary) failed"
 #endif
+#if !__has_builtin (__remove_all_extents)
+# error "__has_builtin (__remove_all_extents) failed"
+#endif
 #if !__has_builtin (__remove_cv)
 # error "__has_builtin (__remove_cv) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_all_extents.C b/gcc/testsuite/g++.dg/ext/remove_all_extents.C
new file mode 100644
index 00000000000..60ade2ade7f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_all_extents.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__remove_all_extents(int), int));
+SA(__is_same(__remove_all_extents(int[2]), int));
+SA(__is_same(__remove_all_extents(int[2][3]), int));
+SA(__is_same(__remove_all_extents(int[][3]), int));
+SA(__is_same(__remove_all_extents(const int[2][3]), const int));
+SA(__is_same(__remove_all_extents(ClassType), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[2]), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[2][3]), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[][3]), ClassType));
+SA(__is_same(__remove_all_extents(const ClassType[2][3]), const ClassType));
-- 
2.43.0


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

* [PATCH v4 06/12] libstdc++: Optimize std::remove_all_extents compilation performance
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 05/12] c++: Implement __remove_all_extents " Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 07/12] c++: Implement __add_lvalue_reference built-in trait Ken Matsui
                       ` (6 subsequent siblings)
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of
std::remove_all_extents by dispatching to the new __remove_all_extents
built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_all_extents): Use
	__remove_all_extents built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 0fb1762186c..2e1cc1c1d5f 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2083,6 +2083,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// remove_all_extents
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_all_extents)
+  template<typename _Tp>
+    struct remove_all_extents
+    { using type = __remove_all_extents(_Tp); };
+#else
   template<typename _Tp>
     struct remove_all_extents
     { using type = _Tp; };
@@ -2094,6 +2099,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct remove_all_extents<_Tp[]>
     { using type = typename remove_all_extents<_Tp>::type; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_extent
-- 
2.43.0


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

* [PATCH v4 07/12] c++: Implement __add_lvalue_reference built-in trait
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 05/12] c++: Implement __remove_all_extents " Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 06/12] libstdc++: Optimize std::remove_all_extents compilation performance Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 08/12] libstdc++: Optimize std::add_lvalue_reference compilation performance Ken Matsui
                       ` (5 subsequent siblings)
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_lvalue_reference.
	* semantics.cc (finish_trait_type): Handle
	CPTK_ADD_LVALUE_REFERENCE.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index ce29108bad6..7dcc6bbad76 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
 #define DEFTRAIT_TYPE_DEFAULTED
 #endif
 
+DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
 DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index c8ac5167c3c..82fc31d9f9b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12760,6 +12760,14 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 
   switch (kind)
     {
+    case CPTK_ADD_LVALUE_REFERENCE:
+      if (VOID_TYPE_P (type1)
+	  || (FUNC_OR_METHOD_TYPE_P (type1)
+	      && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+		  || type_memfn_rqual (type1) != REF_QUAL_NONE)))
+	return type1;
+      return cp_build_reference_type (type1, /*rval=*/false);
+
     case CPTK_ADD_POINTER:
       if (FUNC_OR_METHOD_TYPE_P (type1)
 	  && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
diff --git a/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C b/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
new file mode 100644
index 00000000000..8fe1e0300e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
@@ -0,0 +1,21 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_lvalue_reference(int), int&));
+SA(__is_same(__add_lvalue_reference(int&), int&));
+SA(__is_same(__add_lvalue_reference(const int), const int&));
+SA(__is_same(__add_lvalue_reference(int*), int*&));
+SA(__is_same(__add_lvalue_reference(ClassType&), ClassType&));
+SA(__is_same(__add_lvalue_reference(ClassType), ClassType&));
+SA(__is_same(__add_lvalue_reference(int(int)), int(&)(int)));
+SA(__is_same(__add_lvalue_reference(int&&), int&));
+SA(__is_same(__add_lvalue_reference(ClassType&&), ClassType&));
+SA(__is_same(__add_lvalue_reference(void), void));
+SA(__is_same(__add_lvalue_reference(const void), const void));
+SA(__is_same(__add_lvalue_reference(bool(int) const), bool(int) const));
+SA(__is_same(__add_lvalue_reference(bool(int) &), bool(int) &));
+SA(__is_same(__add_lvalue_reference(bool(int) const &&), bool(int) const &&));
+SA(__is_same(__add_lvalue_reference(bool(int)), bool(&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 9af64173524..1046ffe7d01 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
 // { dg-do compile }
 // Verify that __has_builtin gives the correct answer for C++ built-ins.
 
+#if !__has_builtin (__add_lvalue_reference)
+# error "__has_builtin (__add_lvalue_reference) failed"
+#endif
 #if !__has_builtin (__add_pointer)
 # error "__has_builtin (__add_pointer) failed"
 #endif
-- 
2.43.0


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

* [PATCH v4 08/12] libstdc++: Optimize std::add_lvalue_reference compilation performance
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
                       ` (2 preceding siblings ...)
  2024-02-15 12:48     ` [PATCH v4 07/12] c++: Implement __add_lvalue_reference built-in trait Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 09/12] c++: Implement __add_rvalue_reference built-in trait Ken Matsui
                       ` (4 subsequent siblings)
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of
std::add_lvalue_reference by dispatching to the new
__add_lvalue_reference built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_lvalue_reference): Use
	__add_lvalue_reference built-in trait.
	(__add_lvalue_reference_helper): Likewise.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 2e1cc1c1d5f..1f4e6db72f4 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1129,6 +1129,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /// @cond undocumented
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference)
+  template<typename _Tp>
+    struct __add_lvalue_reference_helper
+    { using type = __add_lvalue_reference(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_lvalue_reference_helper
     { using type = _Tp; };
@@ -1136,6 +1141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>>
     { using type = _Tp&; };
+#endif
 
   template<typename _Tp>
     using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type;
@@ -1703,9 +1709,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// add_lvalue_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference)
+  template<typename _Tp>
+    struct add_lvalue_reference
+    { using type = __add_lvalue_reference(_Tp); };
+#else
   template<typename _Tp>
     struct add_lvalue_reference
     { using type = __add_lval_ref_t<_Tp>; };
+#endif
 
   /// add_rvalue_reference
   template<typename _Tp>
-- 
2.43.0


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

* [PATCH v4 09/12] c++: Implement __add_rvalue_reference built-in trait
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
                       ` (3 preceding siblings ...)
  2024-02-15 12:48     ` [PATCH v4 08/12] libstdc++: Optimize std::add_lvalue_reference compilation performance Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 10/12] libstdc++: Optimize std::add_rvalue_reference compilation performance Ken Matsui
                       ` (3 subsequent siblings)
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_rvalue_reference.
	* semantics.cc (finish_trait_type): Handle
	CPTK_ADD_RVALUE_REFERENCE.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 7dcc6bbad76..9e8f9eb38b8 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -50,6 +50,7 @@
 
 DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
 DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
+DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 82fc31d9f9b..f437e272ea6 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12777,6 +12777,14 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return build_pointer_type (type1);
 
+    case CPTK_ADD_RVALUE_REFERENCE:
+      if (VOID_TYPE_P (type1)
+	  || (FUNC_OR_METHOD_TYPE_P (type1)
+	      && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+		  || type_memfn_rqual (type1) != REF_QUAL_NONE)))
+	return type1;
+      return cp_build_reference_type (type1, /*rval=*/true);
+
     case CPTK_REMOVE_ALL_EXTENTS:
       return strip_array_types (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C b/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C
new file mode 100644
index 00000000000..c92fe6bfa17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_rvalue_reference(int), int&&));
+SA(__is_same(__add_rvalue_reference(int&&), int&&));
+SA(__is_same(__add_rvalue_reference(int&), int&));
+SA(__is_same(__add_rvalue_reference(const int), const int&&));
+SA(__is_same(__add_rvalue_reference(int*), int*&&));
+SA(__is_same(__add_rvalue_reference(ClassType&&), ClassType&&));
+SA(__is_same(__add_rvalue_reference(ClassType), ClassType&&));
+SA(__is_same(__add_rvalue_reference(int(int)), int(&&)(int)));
+SA(__is_same(__add_rvalue_reference(void), void));
+SA(__is_same(__add_rvalue_reference(const void), const void));
+SA(__is_same(__add_rvalue_reference(bool(int) const), bool(int) const));
+SA(__is_same(__add_rvalue_reference(bool(int) &), bool(int) &));
+SA(__is_same(__add_rvalue_reference(bool(int) const &&), bool(int) const &&));
+SA(__is_same(__add_rvalue_reference(bool(int)), bool(&&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 1046ffe7d01..9d7e59b47fb 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -8,6 +8,9 @@
 #if !__has_builtin (__add_pointer)
 # error "__has_builtin (__add_pointer) failed"
 #endif
+#if !__has_builtin (__add_rvalue_reference)
+# error "__has_builtin (__add_rvalue_reference) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v4 10/12] libstdc++: Optimize std::add_rvalue_reference compilation performance
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
                       ` (4 preceding siblings ...)
  2024-02-15 12:48     ` [PATCH v4 09/12] c++: Implement __add_rvalue_reference built-in trait Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 11/12] c++: Implement __decay built-in trait Ken Matsui
                       ` (2 subsequent siblings)
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of
std::add_rvalue_reference by dispatching to the new
__add_rvalue_reference built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_rvalue_reference): Use
	__add_rvalue_reference built-in trait.
	(__add_rvalue_reference_helper): Likewise.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 1f4e6db72f4..219d36fabba 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1157,6 +1157,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /// @cond undocumented
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
+  template<typename _Tp>
+    struct __add_rvalue_reference_helper
+    { using type = __add_rvalue_reference(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_rvalue_reference_helper
     { using type = _Tp; };
@@ -1164,6 +1169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>>
     { using type = _Tp&&; };
+#endif
 
   template<typename _Tp>
     using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type;
@@ -1720,9 +1726,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// add_rvalue_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
+  template<typename _Tp>
+    struct add_rvalue_reference
+    { using type = __add_rvalue_reference(_Tp); };
+#else
   template<typename _Tp>
     struct add_rvalue_reference
     { using type = __add_rval_ref_t<_Tp>; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_reference
-- 
2.43.0


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

* [PATCH v4 11/12] c++: Implement __decay built-in trait
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
                       ` (5 preceding siblings ...)
  2024-02-15 12:48     ` [PATCH v4 10/12] libstdc++: Optimize std::add_rvalue_reference compilation performance Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 12:48     ` [PATCH v4 12/12] libstdc++: Optimize std::decay compilation performance Ken Matsui
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __decay.
	* semantics.cc (finish_trait_type): Handle CPTK_DECAY.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9e8f9eb38b8..11270f3ae6b 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -51,6 +51,7 @@
 DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
 DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1)
+DEFTRAIT_TYPE (DECAY, "__decay", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index f437e272ea6..256e7ef8166 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12785,6 +12785,18 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	return type1;
       return cp_build_reference_type (type1, /*rval=*/true);
 
+    case CPTK_DECAY:
+      if (TYPE_REF_P (type1))
+	type1 = TREE_TYPE (type1);
+
+      if (TREE_CODE (type1) == ARRAY_TYPE)
+	return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
+				  complain);
+      else if (TREE_CODE (type1) == FUNCTION_TYPE)
+	return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
+      else
+	return cv_unqualified (type1);
+
     case CPTK_REMOVE_ALL_EXTENTS:
       return strip_array_types (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/decay.C b/gcc/testsuite/g++.dg/ext/decay.C
new file mode 100644
index 00000000000..cf224b7452c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/decay.C
@@ -0,0 +1,39 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+// class ClassType { };
+
+// Positive tests.
+using test1_type = __decay(bool);
+SA(__is_same(test1_type, bool));
+
+// NB: DR 705.
+using test2_type = __decay(const int);
+SA(__is_same(test2_type, int));
+
+using test3_type = __decay(int[4]);
+SA(__is_same(test3_type, __remove_extent(int[4])*));
+
+using fn_type = void ();
+using test4_type = __decay(fn_type);
+SA(__is_same(test4_type, __add_pointer(fn_type)));
+
+using cfn_type = void () const;
+using test5_type = __decay(cfn_type);
+SA(__is_same(test5_type, cfn_type));
+
+// SA(__is_same(__add_rvalue_reference(int), int&&));
+// SA(__is_same(__add_rvalue_reference(int&&), int&&));
+// SA(__is_same(__add_rvalue_reference(int&), int&));
+// SA(__is_same(__add_rvalue_reference(const int), const int&&));
+// SA(__is_same(__add_rvalue_reference(int*), int*&&));
+// SA(__is_same(__add_rvalue_reference(ClassType&&), ClassType&&));
+// SA(__is_same(__add_rvalue_reference(ClassType), ClassType&&));
+// SA(__is_same(__add_rvalue_reference(int(int)), int(&&)(int)));
+// SA(__is_same(__add_rvalue_reference(void), void));
+// SA(__is_same(__add_rvalue_reference(const void), const void));
+// SA(__is_same(__add_rvalue_reference(bool(int) const), bool(int) const));
+// SA(__is_same(__add_rvalue_reference(bool(int) &), bool(int) &));
+// SA(__is_same(__add_rvalue_reference(bool(int) const &&), bool(int) const &&));
+// SA(__is_same(__add_rvalue_reference(bool(int)), bool(&&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 9d7e59b47fb..5b590db1cf6 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -11,6 +11,9 @@
 #if !__has_builtin (__add_rvalue_reference)
 # error "__has_builtin (__add_rvalue_reference) failed"
 #endif
+#if !__has_builtin (__decay)
+# error "__has_builtin (__decay) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v4 12/12] libstdc++: Optimize std::decay compilation performance
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
                       ` (6 preceding siblings ...)
  2024-02-15 12:48     ` [PATCH v4 11/12] c++: Implement __decay built-in trait Ken Matsui
@ 2024-02-15 12:48     ` Ken Matsui
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
  8 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::decay
by dispatching to the new __decay built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (decay): Use __decay built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 219d36fabba..90718d772dd 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2288,6 +2288,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @cond undocumented
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__decay)
+  template<typename _Tp>
+    struct decay
+    { using type = __decay(_Tp); };
+#else
   // Decay trait for arrays and functions, used for perfect forwarding
   // in make_pair, make_tuple, etc.
   template<typename _Up>
@@ -2319,6 +2324,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct decay<_Tp&&>
     { using type = typename __decay_selector<_Tp>::type; };
+#endif
 
   /// @cond undocumented
 
-- 
2.43.0


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

* [PATCH v5 01/14] c++: Implement __add_pointer built-in trait
  2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
                       ` (7 preceding siblings ...)
  2024-02-15 12:48     ` [PATCH v4 12/12] libstdc++: Optimize std::decay compilation performance Ken Matsui
@ 2024-02-15 15:20     ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 02/14] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
                         ` (12 more replies)
  8 siblings, 13 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_pointer.
	* semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 394f006f20f..cec385ee501 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
 #define DEFTRAIT_TYPE_DEFAULTED
 #endif
 
+DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 57840176863..8dc975495a8 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12760,6 +12760,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 
   switch (kind)
     {
+    case CPTK_ADD_POINTER:
+      if (FUNC_OR_METHOD_TYPE_P (type1)
+	  && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+	      || type_memfn_rqual (type1) != REF_QUAL_NONE))
+	return type1;
+      if (TYPE_REF_P (type1))
+	type1 = TREE_TYPE (type1);
+      return build_pointer_type (type1);
+
     case CPTK_REMOVE_CV:
       return cv_unqualified (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C
new file mode 100644
index 00000000000..c405cdd0feb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
@@ -0,0 +1,39 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_pointer(int), int*));
+SA(__is_same(__add_pointer(int*), int**));
+SA(__is_same(__add_pointer(const int), const int*));
+SA(__is_same(__add_pointer(int&), int*));
+SA(__is_same(__add_pointer(ClassType*), ClassType**));
+SA(__is_same(__add_pointer(ClassType), ClassType*));
+SA(__is_same(__add_pointer(void), void*));
+SA(__is_same(__add_pointer(const void), const void*));
+SA(__is_same(__add_pointer(volatile void), volatile void*));
+SA(__is_same(__add_pointer(const volatile void), const volatile void*));
+
+void f1();
+using f1_type = decltype(f1);
+using pf1_type = decltype(&f1);
+SA(__is_same(__add_pointer(f1_type), pf1_type));
+
+void f2() noexcept; // PR libstdc++/78361
+using f2_type = decltype(f2);
+using pf2_type = decltype(&f2);
+SA(__is_same(__add_pointer(f2_type), pf2_type));
+
+using fn_type = void();
+using pfn_type = void(*)();
+SA(__is_same(__add_pointer(fn_type), pfn_type));
+
+SA(__is_same(__add_pointer(void() &), void() &));
+SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
+SA(__is_same(__add_pointer(void() const), void() const));
+SA(__is_same(__add_pointer(void(...) &), void(...) &));
+SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
+SA(__is_same(__add_pointer(void(...) const), void(...) const));
+
+SA(__is_same(__add_pointer(void() __restrict), void() __restrict));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 02b4b4d745d..56e8db7ac32 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
 // { dg-do compile }
 // Verify that __has_builtin gives the correct answer for C++ built-ins.
 
+#if !__has_builtin (__add_pointer)
+# error "__has_builtin (__add_pointer) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v5 02/14] libstdc++: Optimize std::add_pointer compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 03/14] c++: Implement __remove_extent built-in trait Ken Matsui
                         ` (11 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::add_pointer
by dispatching to the new __add_pointer built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_pointer): Use __add_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 21402fd8c13..3bde7cb8ba3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2121,6 +2121,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { };
 #endif
 
+  /// add_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer)
+  template<typename _Tp>
+    struct add_pointer
+    { using type = __add_pointer(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_pointer_helper
     { using type = _Tp; };
@@ -2129,7 +2135,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
     { using type = _Tp*; };
 
-  /// add_pointer
   template<typename _Tp>
     struct add_pointer
     : public __add_pointer_helper<_Tp>
@@ -2142,6 +2147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct add_pointer<_Tp&&>
     { using type = _Tp*; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_pointer
-- 
2.43.0


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

* [PATCH v5 03/14] c++: Implement __remove_extent built-in trait
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 02/14] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 04/14] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
                         ` (10 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_extent.
	* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_EXTENT.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/has-builtin-1.C: Test existence of __remove_extent.
	* g++.dg/ext/remove_extent.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_extent.C | 16 ++++++++++++++++
 4 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_extent.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index cec385ee501..3ff5611b60e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -96,6 +96,7 @@ DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_tempo
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1)
 DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8dc975495a8..6ab054b106a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12777,6 +12777,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return cv_unqualified (type1);
 
+    case CPTK_REMOVE_EXTENT:
+      if (TREE_CODE (type1) == ARRAY_TYPE)
+	type1 = TREE_TYPE (type1);
+      return type1;
+
     case CPTK_REMOVE_POINTER:
       if (TYPE_PTR_P (type1))
 	type1 = TREE_TYPE (type1);
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 56e8db7ac32..4f1094befb9 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -170,6 +170,9 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_extent)
+# error "__has_builtin (__remove_extent) failed"
+#endif
 #if !__has_builtin (__remove_pointer)
 # error "__has_builtin (__remove_pointer) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_extent.C b/gcc/testsuite/g++.dg/ext/remove_extent.C
new file mode 100644
index 00000000000..6183aca5a48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_extent.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__remove_extent(int), int));
+SA(__is_same(__remove_extent(int[2]), int));
+SA(__is_same(__remove_extent(int[2][3]), int[3]));
+SA(__is_same(__remove_extent(int[][3]), int[3]));
+SA(__is_same(__remove_extent(const int[2]), const int));
+SA(__is_same(__remove_extent(ClassType), ClassType));
+SA(__is_same(__remove_extent(ClassType[2]), ClassType));
+SA(__is_same(__remove_extent(ClassType[2][3]), ClassType[3]));
+SA(__is_same(__remove_extent(ClassType[][3]), ClassType[3]));
+SA(__is_same(__remove_extent(const ClassType[2]), const ClassType));
-- 
2.43.0


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

* [PATCH v5 04/14] libstdc++: Optimize std::remove_extent compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 02/14] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 03/14] c++: Implement __remove_extent built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 05/14] c++: Implement __remove_all_extents built-in trait Ken Matsui
                         ` (9 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::remove_extent
by dispatching to the new __remove_extent built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_extent): Use __remove_extent
	built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 3bde7cb8ba3..0fb1762186c 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2064,6 +2064,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Array modifications.
 
   /// remove_extent
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent)
+  template<typename _Tp>
+    struct remove_extent
+    { using type = __remove_extent(_Tp); };
+#else
   template<typename _Tp>
     struct remove_extent
     { using type = _Tp; };
@@ -2075,6 +2080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct remove_extent<_Tp[]>
     { using type = _Tp; };
+#endif
 
   /// remove_all_extents
   template<typename _Tp>
-- 
2.43.0


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

* [PATCH v5 05/14] c++: Implement __remove_all_extents built-in trait
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (2 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 04/14] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 06/14] libstdc++: Optimize std::remove_all_extents compilation performance Ken Matsui
                         ` (8 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __remove_all_extents.
	* semantics.cc (finish_trait_type): Handle
	CPTK_REMOVE_ALL_EXTENTS.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 3ff5611b60e..ce29108bad6 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -94,6 +94,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
+DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
 DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 6ab054b106a..c8ac5167c3c 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12769,6 +12769,9 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return build_pointer_type (type1);
 
+    case CPTK_REMOVE_ALL_EXTENTS:
+      return strip_array_types (type1);
+
     case CPTK_REMOVE_CV:
       return cv_unqualified (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4f1094befb9..9af64173524 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -164,6 +164,9 @@
 #if !__has_builtin (__reference_converts_from_temporary)
 # error "__has_builtin (__reference_converts_from_temporary) failed"
 #endif
+#if !__has_builtin (__remove_all_extents)
+# error "__has_builtin (__remove_all_extents) failed"
+#endif
 #if !__has_builtin (__remove_cv)
 # error "__has_builtin (__remove_cv) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_all_extents.C b/gcc/testsuite/g++.dg/ext/remove_all_extents.C
new file mode 100644
index 00000000000..60ade2ade7f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_all_extents.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__remove_all_extents(int), int));
+SA(__is_same(__remove_all_extents(int[2]), int));
+SA(__is_same(__remove_all_extents(int[2][3]), int));
+SA(__is_same(__remove_all_extents(int[][3]), int));
+SA(__is_same(__remove_all_extents(const int[2][3]), const int));
+SA(__is_same(__remove_all_extents(ClassType), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[2]), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[2][3]), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[][3]), ClassType));
+SA(__is_same(__remove_all_extents(const ClassType[2][3]), const ClassType));
-- 
2.43.0


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

* [PATCH v5 06/14] libstdc++: Optimize std::remove_all_extents compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (3 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 05/14] c++: Implement __remove_all_extents built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 07/14] c++: Implement __add_lvalue_reference built-in trait Ken Matsui
                         ` (7 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of
std::remove_all_extents by dispatching to the new __remove_all_extents
built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (remove_all_extents): Use
	__remove_all_extents built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 0fb1762186c..2e1cc1c1d5f 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2083,6 +2083,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// remove_all_extents
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_all_extents)
+  template<typename _Tp>
+    struct remove_all_extents
+    { using type = __remove_all_extents(_Tp); };
+#else
   template<typename _Tp>
     struct remove_all_extents
     { using type = _Tp; };
@@ -2094,6 +2099,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct remove_all_extents<_Tp[]>
     { using type = typename remove_all_extents<_Tp>::type; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_extent
-- 
2.43.0


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

* [PATCH v5 07/14] c++: Implement __add_lvalue_reference built-in trait
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (4 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 06/14] libstdc++: Optimize std::remove_all_extents compilation performance Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 08/14] libstdc++: Optimize std::add_lvalue_reference compilation performance Ken Matsui
                         ` (6 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_lvalue_reference.
	* semantics.cc (finish_trait_type): Handle
	CPTK_ADD_LVALUE_REFERENCE.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index ce29108bad6..7dcc6bbad76 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
 #define DEFTRAIT_TYPE_DEFAULTED
 #endif
 
+DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
 DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index c8ac5167c3c..82fc31d9f9b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12760,6 +12760,14 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 
   switch (kind)
     {
+    case CPTK_ADD_LVALUE_REFERENCE:
+      if (VOID_TYPE_P (type1)
+	  || (FUNC_OR_METHOD_TYPE_P (type1)
+	      && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+		  || type_memfn_rqual (type1) != REF_QUAL_NONE)))
+	return type1;
+      return cp_build_reference_type (type1, /*rval=*/false);
+
     case CPTK_ADD_POINTER:
       if (FUNC_OR_METHOD_TYPE_P (type1)
 	  && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
diff --git a/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C b/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
new file mode 100644
index 00000000000..8fe1e0300e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
@@ -0,0 +1,21 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_lvalue_reference(int), int&));
+SA(__is_same(__add_lvalue_reference(int&), int&));
+SA(__is_same(__add_lvalue_reference(const int), const int&));
+SA(__is_same(__add_lvalue_reference(int*), int*&));
+SA(__is_same(__add_lvalue_reference(ClassType&), ClassType&));
+SA(__is_same(__add_lvalue_reference(ClassType), ClassType&));
+SA(__is_same(__add_lvalue_reference(int(int)), int(&)(int)));
+SA(__is_same(__add_lvalue_reference(int&&), int&));
+SA(__is_same(__add_lvalue_reference(ClassType&&), ClassType&));
+SA(__is_same(__add_lvalue_reference(void), void));
+SA(__is_same(__add_lvalue_reference(const void), const void));
+SA(__is_same(__add_lvalue_reference(bool(int) const), bool(int) const));
+SA(__is_same(__add_lvalue_reference(bool(int) &), bool(int) &));
+SA(__is_same(__add_lvalue_reference(bool(int) const &&), bool(int) const &&));
+SA(__is_same(__add_lvalue_reference(bool(int)), bool(&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 9af64173524..1046ffe7d01 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
 // { dg-do compile }
 // Verify that __has_builtin gives the correct answer for C++ built-ins.
 
+#if !__has_builtin (__add_lvalue_reference)
+# error "__has_builtin (__add_lvalue_reference) failed"
+#endif
 #if !__has_builtin (__add_pointer)
 # error "__has_builtin (__add_pointer) failed"
 #endif
-- 
2.43.0


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

* [PATCH v5 08/14] libstdc++: Optimize std::add_lvalue_reference compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (5 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 07/14] c++: Implement __add_lvalue_reference built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 09/14] c++: Implement __add_rvalue_reference built-in trait Ken Matsui
                         ` (5 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of
std::add_lvalue_reference by dispatching to the new
__add_lvalue_reference built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_lvalue_reference): Use
	__add_lvalue_reference built-in trait.
	(__add_lvalue_reference_helper): Likewise.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 2e1cc1c1d5f..1f4e6db72f4 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1129,6 +1129,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /// @cond undocumented
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference)
+  template<typename _Tp>
+    struct __add_lvalue_reference_helper
+    { using type = __add_lvalue_reference(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_lvalue_reference_helper
     { using type = _Tp; };
@@ -1136,6 +1141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>>
     { using type = _Tp&; };
+#endif
 
   template<typename _Tp>
     using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type;
@@ -1703,9 +1709,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// add_lvalue_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference)
+  template<typename _Tp>
+    struct add_lvalue_reference
+    { using type = __add_lvalue_reference(_Tp); };
+#else
   template<typename _Tp>
     struct add_lvalue_reference
     { using type = __add_lval_ref_t<_Tp>; };
+#endif
 
   /// add_rvalue_reference
   template<typename _Tp>
-- 
2.43.0


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

* [PATCH v5 09/14] c++: Implement __add_rvalue_reference built-in trait
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (6 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 08/14] libstdc++: Optimize std::add_lvalue_reference compilation performance Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 10/14] libstdc++: Optimize std::add_rvalue_reference compilation performance Ken Matsui
                         ` (4 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __add_rvalue_reference.
	* semantics.cc (finish_trait_type): Handle
	CPTK_ADD_RVALUE_REFERENCE.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 7dcc6bbad76..9e8f9eb38b8 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -50,6 +50,7 @@
 
 DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
 DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
+DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 82fc31d9f9b..f437e272ea6 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12777,6 +12777,14 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	type1 = TREE_TYPE (type1);
       return build_pointer_type (type1);
 
+    case CPTK_ADD_RVALUE_REFERENCE:
+      if (VOID_TYPE_P (type1)
+	  || (FUNC_OR_METHOD_TYPE_P (type1)
+	      && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+		  || type_memfn_rqual (type1) != REF_QUAL_NONE)))
+	return type1;
+      return cp_build_reference_type (type1, /*rval=*/true);
+
     case CPTK_REMOVE_ALL_EXTENTS:
       return strip_array_types (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C b/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C
new file mode 100644
index 00000000000..c92fe6bfa17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_rvalue_reference(int), int&&));
+SA(__is_same(__add_rvalue_reference(int&&), int&&));
+SA(__is_same(__add_rvalue_reference(int&), int&));
+SA(__is_same(__add_rvalue_reference(const int), const int&&));
+SA(__is_same(__add_rvalue_reference(int*), int*&&));
+SA(__is_same(__add_rvalue_reference(ClassType&&), ClassType&&));
+SA(__is_same(__add_rvalue_reference(ClassType), ClassType&&));
+SA(__is_same(__add_rvalue_reference(int(int)), int(&&)(int)));
+SA(__is_same(__add_rvalue_reference(void), void));
+SA(__is_same(__add_rvalue_reference(const void), const void));
+SA(__is_same(__add_rvalue_reference(bool(int) const), bool(int) const));
+SA(__is_same(__add_rvalue_reference(bool(int) &), bool(int) &));
+SA(__is_same(__add_rvalue_reference(bool(int) const &&), bool(int) const &&));
+SA(__is_same(__add_rvalue_reference(bool(int)), bool(&&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 1046ffe7d01..9d7e59b47fb 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -8,6 +8,9 @@
 #if !__has_builtin (__add_pointer)
 # error "__has_builtin (__add_pointer) failed"
 #endif
+#if !__has_builtin (__add_rvalue_reference)
+# error "__has_builtin (__add_rvalue_reference) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v5 10/14] libstdc++: Optimize std::add_rvalue_reference compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (7 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 09/14] c++: Implement __add_rvalue_reference built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 11/14] c++: Implement __decay built-in trait Ken Matsui
                         ` (3 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of
std::add_rvalue_reference by dispatching to the new
__add_rvalue_reference built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (add_rvalue_reference): Use
	__add_rvalue_reference built-in trait.
	(__add_rvalue_reference_helper): Likewise.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 1f4e6db72f4..219d36fabba 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1157,6 +1157,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /// @cond undocumented
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
+  template<typename _Tp>
+    struct __add_rvalue_reference_helper
+    { using type = __add_rvalue_reference(_Tp); };
+#else
   template<typename _Tp, typename = void>
     struct __add_rvalue_reference_helper
     { using type = _Tp; };
@@ -1164,6 +1169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>>
     { using type = _Tp&&; };
+#endif
 
   template<typename _Tp>
     using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type;
@@ -1720,9 +1726,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// add_rvalue_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
+  template<typename _Tp>
+    struct add_rvalue_reference
+    { using type = __add_rvalue_reference(_Tp); };
+#else
   template<typename _Tp>
     struct add_rvalue_reference
     { using type = __add_rval_ref_t<_Tp>; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_reference
-- 
2.43.0


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

* [PATCH v5 11/14] c++: Implement __decay built-in trait
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (8 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 10/14] libstdc++: Optimize std::add_rvalue_reference compilation performance Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 12/14] libstdc++: Optimize std::decay compilation performance Ken Matsui
                         ` (2 subsequent siblings)
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __decay.
	* semantics.cc (finish_trait_type): Handle CPTK_DECAY.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9e8f9eb38b8..11270f3ae6b 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -51,6 +51,7 @@
 DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
 DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
 DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1)
+DEFTRAIT_TYPE (DECAY, "__decay", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
 DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index f437e272ea6..256e7ef8166 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12785,6 +12785,18 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
 	return type1;
       return cp_build_reference_type (type1, /*rval=*/true);
 
+    case CPTK_DECAY:
+      if (TYPE_REF_P (type1))
+	type1 = TREE_TYPE (type1);
+
+      if (TREE_CODE (type1) == ARRAY_TYPE)
+	return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
+				  complain);
+      else if (TREE_CODE (type1) == FUNCTION_TYPE)
+	return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
+      else
+	return cv_unqualified (type1);
+
     case CPTK_REMOVE_ALL_EXTENTS:
       return strip_array_types (type1);
 
diff --git a/gcc/testsuite/g++.dg/ext/decay.C b/gcc/testsuite/g++.dg/ext/decay.C
new file mode 100644
index 00000000000..cf224b7452c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/decay.C
@@ -0,0 +1,39 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+// class ClassType { };
+
+// Positive tests.
+using test1_type = __decay(bool);
+SA(__is_same(test1_type, bool));
+
+// NB: DR 705.
+using test2_type = __decay(const int);
+SA(__is_same(test2_type, int));
+
+using test3_type = __decay(int[4]);
+SA(__is_same(test3_type, __remove_extent(int[4])*));
+
+using fn_type = void ();
+using test4_type = __decay(fn_type);
+SA(__is_same(test4_type, __add_pointer(fn_type)));
+
+using cfn_type = void () const;
+using test5_type = __decay(cfn_type);
+SA(__is_same(test5_type, cfn_type));
+
+// SA(__is_same(__add_rvalue_reference(int), int&&));
+// SA(__is_same(__add_rvalue_reference(int&&), int&&));
+// SA(__is_same(__add_rvalue_reference(int&), int&));
+// SA(__is_same(__add_rvalue_reference(const int), const int&&));
+// SA(__is_same(__add_rvalue_reference(int*), int*&&));
+// SA(__is_same(__add_rvalue_reference(ClassType&&), ClassType&&));
+// SA(__is_same(__add_rvalue_reference(ClassType), ClassType&&));
+// SA(__is_same(__add_rvalue_reference(int(int)), int(&&)(int)));
+// SA(__is_same(__add_rvalue_reference(void), void));
+// SA(__is_same(__add_rvalue_reference(const void), const void));
+// SA(__is_same(__add_rvalue_reference(bool(int) const), bool(int) const));
+// SA(__is_same(__add_rvalue_reference(bool(int) &), bool(int) &));
+// SA(__is_same(__add_rvalue_reference(bool(int) const &&), bool(int) const &&));
+// SA(__is_same(__add_rvalue_reference(bool(int)), bool(&&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 9d7e59b47fb..5b590db1cf6 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -11,6 +11,9 @@
 #if !__has_builtin (__add_rvalue_reference)
 # error "__has_builtin (__add_rvalue_reference) failed"
 #endif
+#if !__has_builtin (__decay)
+# error "__has_builtin (__decay) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
-- 
2.43.0


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

* [PATCH v5 12/14] libstdc++: Optimize std::decay compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (9 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 11/14] c++: Implement __decay built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 13/14] c++: Implement __rank built-in trait Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 14/14] libstdc++: Optimize std::rank compilation performance Ken Matsui
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::decay
by dispatching to the new __decay built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (decay): Use __decay built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 219d36fabba..90718d772dd 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2288,6 +2288,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @cond undocumented
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__decay)
+  template<typename _Tp>
+    struct decay
+    { using type = __decay(_Tp); };
+#else
   // Decay trait for arrays and functions, used for perfect forwarding
   // in make_pair, make_tuple, etc.
   template<typename _Up>
@@ -2319,6 +2324,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct decay<_Tp&&>
     { using type = typename __decay_selector<_Tp>::type; };
+#endif
 
   /// @cond undocumented
 
-- 
2.43.0


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

* [PATCH v5 13/14] c++: Implement __rank built-in trait
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (10 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 12/14] libstdc++: Optimize std::decay compilation performance Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  2024-02-15 21:48         ` Patrick Palka
  2024-02-16  2:15         ` [PATCH v6 " Ken Matsui
  2024-02-15 15:20       ` [PATCH v5 14/14] libstdc++: Optimize std::rank compilation performance Ken Matsui
  12 siblings, 2 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __rank.
	* semantics.cc (trait_expr_value): Handle CPTK_RANK.
	(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 11270f3ae6b..3d5a7970563 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -95,6 +95,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
 DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (RANK, "__rank", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 256e7ef8166..4f285909b83 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12538,6 +12538,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_DEDUCIBLE:
       return type_targs_deducible_from (type1, type2);
 
+    /* __rank is handled in finish_trait_expr. */
+    case CPTK_RANK:
+
 #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
     case CPTK_##CODE:
 #include "cp-trait.def"
@@ -12698,6 +12701,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_SAME:
     case CPTK_IS_SCOPED_ENUM:
     case CPTK_IS_UNION:
+    case CPTK_RANK:
       break;
 
     case CPTK_IS_LAYOUT_COMPATIBLE:
@@ -12729,8 +12733,18 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
       gcc_unreachable ();
     }
 
-  tree val = (trait_expr_value (kind, type1, type2)
-	      ? boolean_true_node : boolean_false_node);
+  tree val;
+  if (kind == CPTK_RANK)
+    {
+      size_t rank = 0;
+      for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
+	++rank;
+      val = build_int_cst (size_type_node, rank);
+    }
+  else
+    val = (trait_expr_value (kind, type1, type2)
+	   ? boolean_true_node : boolean_false_node);
+
   return maybe_wrap_with_location (val, loc);
 }
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 5b590db1cf6..a00193c1a81 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -167,6 +167,9 @@
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
+#if !__has_builtin (__rank)
+# error "__has_builtin (__rank) failed"
+#endif
 #if !__has_builtin (__reference_constructs_from_temporary)
 # error "__has_builtin (__reference_constructs_from_temporary) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/rank.C b/gcc/testsuite/g++.dg/ext/rank.C
new file mode 100644
index 00000000000..bab062d776e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/rank.C
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__rank(int) == 0);
+SA(__rank(int[2]) == 1);
+SA(__rank(int[][4]) == 2);
+SA(__rank(int[2][2][4][4][6][6]) == 6);
+SA(__rank(ClassType) == 0);
+SA(__rank(ClassType[2]) == 1);
+SA(__rank(ClassType[][4]) == 2);
+SA(__rank(ClassType[2][2][4][4][6][6]) == 6);
-- 
2.43.0


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

* [PATCH v5 14/14] libstdc++: Optimize std::rank compilation performance
  2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
                         ` (11 preceding siblings ...)
  2024-02-15 15:20       ` [PATCH v5 13/14] c++: Implement __rank built-in trait Ken Matsui
@ 2024-02-15 15:20       ` Ken Matsui
  12 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-15 15:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

This patch optimizes the compilation performance of std::rank
by dispatching to the new __rank built-in trait.

libstdc++-v3/ChangeLog:

	* include/std/type_traits (rank): Use __rank built-in trait.

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

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 90718d772dd..5d2e6eaa2a2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1445,6 +1445,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /// rank
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__rank)
+  template<typename _Tp>
+    struct rank
+    : public integral_constant<std::size_t, __rank(_Tp)> { };
+#else
   template<typename>
     struct rank
     : public integral_constant<std::size_t, 0> { };
@@ -1456,6 +1461,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct rank<_Tp[]>
     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
+#endif
 
   /// extent
   template<typename, unsigned _Uint = 0>
-- 
2.43.0


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

* Re: [PATCH v5 13/14] c++: Implement __rank built-in trait
  2024-02-15 15:20       ` [PATCH v5 13/14] c++: Implement __rank built-in trait Ken Matsui
@ 2024-02-15 21:48         ` Patrick Palka
  2024-02-16  2:14           ` Ken Matsui
  2024-02-16  2:15         ` [PATCH v6 " Ken Matsui
  1 sibling, 1 reply; 38+ messages in thread
From: Patrick Palka @ 2024-02-15 21:48 UTC (permalink / raw)
  To: Ken Matsui; +Cc: gcc-patches, libstdc++

On Thu, 15 Feb 2024, Ken Matsui wrote:

> This patch implements built-in trait for std::rank.
> 
> gcc/cp/ChangeLog:
> 
> 	* cp-trait.def: Define __rank.
> 	* semantics.cc (trait_expr_value): Handle CPTK_RANK.
> 	(finish_trait_expr): Likewise.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/has-builtin-1.C: Test existence of __rank.
> 	* g++.dg/ext/rank.C: New test.
> 
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> ---
>  gcc/cp/cp-trait.def                      |  1 +
>  gcc/cp/semantics.cc                      | 18 ++++++++++++++++--
>  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
>  gcc/testsuite/g++.dg/ext/rank.C          | 14 ++++++++++++++
>  4 files changed, 34 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/ext/rank.C
> 
> diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> index 11270f3ae6b..3d5a7970563 100644
> --- a/gcc/cp/cp-trait.def
> +++ b/gcc/cp/cp-trait.def
> @@ -95,6 +95,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
>  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
>  DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
>  DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> +DEFTRAIT_EXPR (RANK, "__rank", 1)
>  DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
>  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
>  DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 256e7ef8166..4f285909b83 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12538,6 +12538,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
>      case CPTK_IS_DEDUCIBLE:
>        return type_targs_deducible_from (type1, type2);
>  
> +    /* __rank is handled in finish_trait_expr. */
> +    case CPTK_RANK:
> +
>  #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
>      case CPTK_##CODE:
>  #include "cp-trait.def"
> @@ -12698,6 +12701,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
>      case CPTK_IS_SAME:
>      case CPTK_IS_SCOPED_ENUM:
>      case CPTK_IS_UNION:
> +    case CPTK_RANK:
>        break;
>  
>      case CPTK_IS_LAYOUT_COMPATIBLE:
> @@ -12729,8 +12733,18 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
>        gcc_unreachable ();
>      }
>  
> -  tree val = (trait_expr_value (kind, type1, type2)
> -	      ? boolean_true_node : boolean_false_node);
> +  tree val;
> +  if (kind == CPTK_RANK)
> +    {
> +      size_t rank = 0;
> +      for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
> +	++rank;
> +      val = build_int_cst (size_type_node, rank);

So this will be the first expression-yielding trait that's not a bool.
That's no problem conceptually, but I think we hardcode their bool-ness
near the top of finish_trait_expr when returning a templated version of
the trait.  We should instead give templated __rank the type size_type_node.

> +    }
> +  else
> +    val = (trait_expr_value (kind, type1, type2)
> +	   ? boolean_true_node : boolean_false_node);
> +
>    return maybe_wrap_with_location (val, loc);
>  }
>  
> diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> index 5b590db1cf6..a00193c1a81 100644
> --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> @@ -167,6 +167,9 @@
>  #if !__has_builtin (__is_union)
>  # error "__has_builtin (__is_union) failed"
>  #endif
> +#if !__has_builtin (__rank)
> +# error "__has_builtin (__rank) failed"
> +#endif
>  #if !__has_builtin (__reference_constructs_from_temporary)
>  # error "__has_builtin (__reference_constructs_from_temporary) failed"
>  #endif
> diff --git a/gcc/testsuite/g++.dg/ext/rank.C b/gcc/testsuite/g++.dg/ext/rank.C
> new file mode 100644
> index 00000000000..bab062d776e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/rank.C
> @@ -0,0 +1,14 @@
> +// { dg-do compile { target c++11 } }
> +
> +#define SA(X) static_assert((X),#X)
> +
> +class ClassType { };
> +
> +SA(__rank(int) == 0);
> +SA(__rank(int[2]) == 1);
> +SA(__rank(int[][4]) == 2);
> +SA(__rank(int[2][2][4][4][6][6]) == 6);
> +SA(__rank(ClassType) == 0);
> +SA(__rank(ClassType[2]) == 1);
> +SA(__rank(ClassType[][4]) == 2);
> +SA(__rank(ClassType[2][2][4][4][6][6]) == 6);

We should have a test that the __rank inside a template has the correct
type, something like (this should currently fail with your patch as-is
due to the hardcoded bool type):

    template<class T> void f(T) = delete;
    void f(bool);

    template<class T>
    void g() { f(__rank(T)); }

    template void g<int>();

> -- 
> 2.43.0
> 
> 


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

* Re: [PATCH v5 13/14] c++: Implement __rank built-in trait
  2024-02-15 21:48         ` Patrick Palka
@ 2024-02-16  2:14           ` Ken Matsui
  2024-02-16  2:22             ` Ken Matsui
  0 siblings, 1 reply; 38+ messages in thread
From: Ken Matsui @ 2024-02-16  2:14 UTC (permalink / raw)
  To: Patrick Palka; +Cc: Ken Matsui, gcc-patches, libstdc++

On Thu, Feb 15, 2024 at 1:48 PM Patrick Palka <ppalka@redhat.com> wrote:
>
> On Thu, 15 Feb 2024, Ken Matsui wrote:
>
> > This patch implements built-in trait for std::rank.
> >
> > gcc/cp/ChangeLog:
> >
> >       * cp-trait.def: Define __rank.
> >       * semantics.cc (trait_expr_value): Handle CPTK_RANK.
> >       (finish_trait_expr): Likewise.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * g++.dg/ext/has-builtin-1.C: Test existence of __rank.
> >       * g++.dg/ext/rank.C: New test.
> >
> > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > ---
> >  gcc/cp/cp-trait.def                      |  1 +
> >  gcc/cp/semantics.cc                      | 18 ++++++++++++++++--
> >  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
> >  gcc/testsuite/g++.dg/ext/rank.C          | 14 ++++++++++++++
> >  4 files changed, 34 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.dg/ext/rank.C
> >
> > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > index 11270f3ae6b..3d5a7970563 100644
> > --- a/gcc/cp/cp-trait.def
> > +++ b/gcc/cp/cp-trait.def
> > @@ -95,6 +95,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
> >  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
> >  DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
> >  DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> > +DEFTRAIT_EXPR (RANK, "__rank", 1)
> >  DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
> >  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
> >  DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 256e7ef8166..4f285909b83 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -12538,6 +12538,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> >      case CPTK_IS_DEDUCIBLE:
> >        return type_targs_deducible_from (type1, type2);
> >
> > +    /* __rank is handled in finish_trait_expr. */
> > +    case CPTK_RANK:
> > +
> >  #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
> >      case CPTK_##CODE:
> >  #include "cp-trait.def"
> > @@ -12698,6 +12701,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> >      case CPTK_IS_SAME:
> >      case CPTK_IS_SCOPED_ENUM:
> >      case CPTK_IS_UNION:
> > +    case CPTK_RANK:
> >        break;
> >
> >      case CPTK_IS_LAYOUT_COMPATIBLE:
> > @@ -12729,8 +12733,18 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> >        gcc_unreachable ();
> >      }
> >
> > -  tree val = (trait_expr_value (kind, type1, type2)
> > -           ? boolean_true_node : boolean_false_node);
> > +  tree val;
> > +  if (kind == CPTK_RANK)
> > +    {
> > +      size_t rank = 0;
> > +      for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
> > +     ++rank;
> > +      val = build_int_cst (size_type_node, rank);
>
> So this will be the first expression-yielding trait that's not a bool.
> That's no problem conceptually, but I think we hardcode their bool-ness
> near the top of finish_trait_expr when returning a templated version of
> the trait.  We should instead give templated __rank the type size_type_node.
>
> > +    }
> > +  else
> > +    val = (trait_expr_value (kind, type1, type2)
> > +        ? boolean_true_node : boolean_false_node);
> > +
> >    return maybe_wrap_with_location (val, loc);
> >  }
> >
> > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > index 5b590db1cf6..a00193c1a81 100644
> > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > @@ -167,6 +167,9 @@
> >  #if !__has_builtin (__is_union)
> >  # error "__has_builtin (__is_union) failed"
> >  #endif
> > +#if !__has_builtin (__rank)
> > +# error "__has_builtin (__rank) failed"
> > +#endif
> >  #if !__has_builtin (__reference_constructs_from_temporary)
> >  # error "__has_builtin (__reference_constructs_from_temporary) failed"
> >  #endif
> > diff --git a/gcc/testsuite/g++.dg/ext/rank.C b/gcc/testsuite/g++.dg/ext/rank.C
> > new file mode 100644
> > index 00000000000..bab062d776e
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/ext/rank.C
> > @@ -0,0 +1,14 @@
> > +// { dg-do compile { target c++11 } }
> > +
> > +#define SA(X) static_assert((X),#X)
> > +
> > +class ClassType { };
> > +
> > +SA(__rank(int) == 0);
> > +SA(__rank(int[2]) == 1);
> > +SA(__rank(int[][4]) == 2);
> > +SA(__rank(int[2][2][4][4][6][6]) == 6);
> > +SA(__rank(ClassType) == 0);
> > +SA(__rank(ClassType[2]) == 1);
> > +SA(__rank(ClassType[][4]) == 2);
> > +SA(__rank(ClassType[2][2][4][4][6][6]) == 6);
>
> We should have a test that the __rank inside a template has the correct
> type, something like (this should currently fail with your patch as-is
> due to the hardcoded bool type):
>
>     template<class T> void f(T) = delete;
>     void f(bool);
>
>     template<class T>
>     void g() { f(__rank(T)); }
>
>     template void g<int>();
>

Thank you!  I think this test should be the following, to fail with my
patch as-is:

-     void f(bool);
+     void f(size_t);

since we are expecting size_t from __rank.  The current patch passed
this test and failed with a test with change, and my updated patch
failed with this test and passed a test with this change.

I will submit the updated patch soon.  Thank you for pointing this out!

> > --
> > 2.43.0
> >
> >
>

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

* [PATCH v6 13/14] c++: Implement __rank built-in trait
  2024-02-15 15:20       ` [PATCH v5 13/14] c++: Implement __rank built-in trait Ken Matsui
  2024-02-15 21:48         ` Patrick Palka
@ 2024-02-16  2:15         ` Ken Matsui
  1 sibling, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-16  2:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Ken Matsui

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

gcc/cp/ChangeLog:

	* cp-trait.def: Define __rank.
	* semantics.cc (trait_expr_value): Handle CPTK_RANK.
	(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 11270f3ae6b..3d5a7970563 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -95,6 +95,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
 DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (RANK, "__rank", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 256e7ef8166..c3254784fc5 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12538,6 +12538,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_DEDUCIBLE:
       return type_targs_deducible_from (type1, type2);
 
+    /* __rank is handled in finish_trait_expr. */
+    case CPTK_RANK:
+
 #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
     case CPTK_##CODE:
 #include "cp-trait.def"
@@ -12610,7 +12613,10 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
   if (processing_template_decl)
     {
       tree trait_expr = make_node (TRAIT_EXPR);
-      TREE_TYPE (trait_expr) = boolean_type_node;
+      if (kind == CPTK_RANK)
+	TREE_TYPE (trait_expr) = size_type_node;
+      else
+	TREE_TYPE (trait_expr) = boolean_type_node;
       TRAIT_EXPR_TYPE1 (trait_expr) = type1;
       TRAIT_EXPR_TYPE2 (trait_expr) = type2;
       TRAIT_EXPR_KIND (trait_expr) = kind;
@@ -12698,6 +12704,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_SAME:
     case CPTK_IS_SCOPED_ENUM:
     case CPTK_IS_UNION:
+    case CPTK_RANK:
       break;
 
     case CPTK_IS_LAYOUT_COMPATIBLE:
@@ -12729,8 +12736,18 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
       gcc_unreachable ();
     }
 
-  tree val = (trait_expr_value (kind, type1, type2)
-	      ? boolean_true_node : boolean_false_node);
+  tree val;
+  if (kind == CPTK_RANK)
+    {
+      size_t rank = 0;
+      for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
+	++rank;
+      val = build_int_cst (size_type_node, rank);
+    }
+  else
+    val = (trait_expr_value (kind, type1, type2)
+	   ? boolean_true_node : boolean_false_node);
+
   return maybe_wrap_with_location (val, loc);
 }
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 5b590db1cf6..a00193c1a81 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -167,6 +167,9 @@
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
+#if !__has_builtin (__rank)
+# error "__has_builtin (__rank) failed"
+#endif
 #if !__has_builtin (__reference_constructs_from_temporary)
 # error "__has_builtin (__reference_constructs_from_temporary) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/rank.C b/gcc/testsuite/g++.dg/ext/rank.C
new file mode 100644
index 00000000000..28894184387
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/rank.C
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++11 } }
+
+#include <cstddef>
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__rank(int) == 0);
+SA(__rank(int[2]) == 1);
+SA(__rank(int[][4]) == 2);
+SA(__rank(int[2][2][4][4][6][6]) == 6);
+SA(__rank(ClassType) == 0);
+SA(__rank(ClassType[2]) == 1);
+SA(__rank(ClassType[][4]) == 2);
+SA(__rank(ClassType[2][2][4][4][6][6]) == 6);
+
+template<class T> void f(T) = delete;
+void f(size_t);
+
+template<class T>
+void g() { f(__rank(T)); }
+
+template void g<int>();
-- 
2.43.2


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

* Re: [PATCH v5 13/14] c++: Implement __rank built-in trait
  2024-02-16  2:14           ` Ken Matsui
@ 2024-02-16  2:22             ` Ken Matsui
  0 siblings, 0 replies; 38+ messages in thread
From: Ken Matsui @ 2024-02-16  2:22 UTC (permalink / raw)
  To: Patrick Palka; +Cc: Ken Matsui, gcc-patches, libstdc++

On Thu, Feb 15, 2024 at 6:14 PM Ken Matsui <kmatsui@cs.washington.edu> wrote:
>
> On Thu, Feb 15, 2024 at 1:48 PM Patrick Palka <ppalka@redhat.com> wrote:
> >
> > On Thu, 15 Feb 2024, Ken Matsui wrote:
> >
> > > This patch implements built-in trait for std::rank.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >       * cp-trait.def: Define __rank.
> > >       * semantics.cc (trait_expr_value): Handle CPTK_RANK.
> > >       (finish_trait_expr): Likewise.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >       * g++.dg/ext/has-builtin-1.C: Test existence of __rank.
> > >       * g++.dg/ext/rank.C: New test.
> > >
> > > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > > ---
> > >  gcc/cp/cp-trait.def                      |  1 +
> > >  gcc/cp/semantics.cc                      | 18 ++++++++++++++++--
> > >  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
> > >  gcc/testsuite/g++.dg/ext/rank.C          | 14 ++++++++++++++
> > >  4 files changed, 34 insertions(+), 2 deletions(-)
> > >  create mode 100644 gcc/testsuite/g++.dg/ext/rank.C
> > >
> > > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > > index 11270f3ae6b..3d5a7970563 100644
> > > --- a/gcc/cp/cp-trait.def
> > > +++ b/gcc/cp/cp-trait.def
> > > @@ -95,6 +95,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
> > >  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
> > >  DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
> > >  DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> > > +DEFTRAIT_EXPR (RANK, "__rank", 1)
> > >  DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
> > >  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
> > >  DEFTRAIT_TYPE (REMOVE_ALL_EXTENTS, "__remove_all_extents", 1)
> > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > > index 256e7ef8166..4f285909b83 100644
> > > --- a/gcc/cp/semantics.cc
> > > +++ b/gcc/cp/semantics.cc
> > > @@ -12538,6 +12538,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > >      case CPTK_IS_DEDUCIBLE:
> > >        return type_targs_deducible_from (type1, type2);
> > >
> > > +    /* __rank is handled in finish_trait_expr. */
> > > +    case CPTK_RANK:
> > > +
> > >  #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
> > >      case CPTK_##CODE:
> > >  #include "cp-trait.def"
> > > @@ -12698,6 +12701,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > >      case CPTK_IS_SAME:
> > >      case CPTK_IS_SCOPED_ENUM:
> > >      case CPTK_IS_UNION:
> > > +    case CPTK_RANK:
> > >        break;
> > >
> > >      case CPTK_IS_LAYOUT_COMPATIBLE:
> > > @@ -12729,8 +12733,18 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > >        gcc_unreachable ();
> > >      }
> > >
> > > -  tree val = (trait_expr_value (kind, type1, type2)
> > > -           ? boolean_true_node : boolean_false_node);
> > > +  tree val;
> > > +  if (kind == CPTK_RANK)
> > > +    {
> > > +      size_t rank = 0;
> > > +      for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
> > > +     ++rank;
> > > +      val = build_int_cst (size_type_node, rank);
> >
> > So this will be the first expression-yielding trait that's not a bool.
> > That's no problem conceptually, but I think we hardcode their bool-ness
> > near the top of finish_trait_expr when returning a templated version of
> > the trait.  We should instead give templated __rank the type size_type_node.
> >
> > > +    }
> > > +  else
> > > +    val = (trait_expr_value (kind, type1, type2)
> > > +        ? boolean_true_node : boolean_false_node);
> > > +
> > >    return maybe_wrap_with_location (val, loc);
> > >  }
> > >
> > > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > index 5b590db1cf6..a00193c1a81 100644
> > > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > @@ -167,6 +167,9 @@
> > >  #if !__has_builtin (__is_union)
> > >  # error "__has_builtin (__is_union) failed"
> > >  #endif
> > > +#if !__has_builtin (__rank)
> > > +# error "__has_builtin (__rank) failed"
> > > +#endif
> > >  #if !__has_builtin (__reference_constructs_from_temporary)
> > >  # error "__has_builtin (__reference_constructs_from_temporary) failed"
> > >  #endif
> > > diff --git a/gcc/testsuite/g++.dg/ext/rank.C b/gcc/testsuite/g++.dg/ext/rank.C
> > > new file mode 100644
> > > index 00000000000..bab062d776e
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/ext/rank.C
> > > @@ -0,0 +1,14 @@
> > > +// { dg-do compile { target c++11 } }
> > > +
> > > +#define SA(X) static_assert((X),#X)
> > > +
> > > +class ClassType { };
> > > +
> > > +SA(__rank(int) == 0);
> > > +SA(__rank(int[2]) == 1);
> > > +SA(__rank(int[][4]) == 2);
> > > +SA(__rank(int[2][2][4][4][6][6]) == 6);
> > > +SA(__rank(ClassType) == 0);
> > > +SA(__rank(ClassType[2]) == 1);
> > > +SA(__rank(ClassType[][4]) == 2);
> > > +SA(__rank(ClassType[2][2][4][4][6][6]) == 6);
> >
> > We should have a test that the __rank inside a template has the correct
> > type, something like (this should currently fail with your patch as-is
> > due to the hardcoded bool type):
> >
> >     template<class T> void f(T) = delete;
> >     void f(bool);
> >
> >     template<class T>
> >     void g() { f(__rank(T)); }
> >
> >     template void g<int>();
> >
>
> Thank you!  I think this test should be the following, to fail with my
> patch as-is:
>
> -     void f(bool);
> +     void f(size_t);
>
> since we are expecting size_t from __rank.  The current patch passed
> this test and failed with a test with change, and my updated patch
> failed with this test and passed a test with this change.
>

Sorry, the wording was a bit confusing.  Just in case, here is what I meant.

v5
  passed yours (expect bool)
  failed with this change (expect size_t)

v6
  failed with yours (expect bool)
  passed this change (expect size_t)

Again, thank you for your review, Patrick!

> I will submit the updated patch soon.  Thank you for pointing this out!
>
> > > --
> > > 2.43.0
> > >
> > >
> >

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

end of thread, other threads:[~2024-02-16  2:22 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-14 11:44 [PATCH 1/2] c++: Implement __add_pointer built-in trait Ken Matsui
2024-02-14 11:44 ` [PATCH 2/2] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
2024-02-14 13:52 ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Ken Matsui
2024-02-14 13:52   ` [PATCH v2 2/4] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
2024-02-14 20:20     ` Patrick Palka
2024-02-14 13:52   ` [PATCH v2 3/4] c++: Implement __remove_extent built-in trait Ken Matsui
2024-02-14 20:20     ` Patrick Palka
2024-02-14 13:52   ` [PATCH v2 4/4] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
2024-02-14 20:21     ` Patrick Palka
2024-02-14 20:18   ` [PATCH v2 1/4] c++: Implement __add_pointer built-in trait Patrick Palka
2024-02-15  4:17     ` Ken Matsui
2024-02-15  4:52   ` [PATCH v3 " Ken Matsui
2024-02-15 12:48     ` [PATCH v4 05/12] c++: Implement __remove_all_extents " Ken Matsui
2024-02-15 12:48     ` [PATCH v4 06/12] libstdc++: Optimize std::remove_all_extents compilation performance Ken Matsui
2024-02-15 12:48     ` [PATCH v4 07/12] c++: Implement __add_lvalue_reference built-in trait Ken Matsui
2024-02-15 12:48     ` [PATCH v4 08/12] libstdc++: Optimize std::add_lvalue_reference compilation performance Ken Matsui
2024-02-15 12:48     ` [PATCH v4 09/12] c++: Implement __add_rvalue_reference built-in trait Ken Matsui
2024-02-15 12:48     ` [PATCH v4 10/12] libstdc++: Optimize std::add_rvalue_reference compilation performance Ken Matsui
2024-02-15 12:48     ` [PATCH v4 11/12] c++: Implement __decay built-in trait Ken Matsui
2024-02-15 12:48     ` [PATCH v4 12/12] libstdc++: Optimize std::decay compilation performance Ken Matsui
2024-02-15 15:20     ` [PATCH v5 01/14] c++: Implement __add_pointer built-in trait Ken Matsui
2024-02-15 15:20       ` [PATCH v5 02/14] libstdc++: Optimize std::add_pointer compilation performance Ken Matsui
2024-02-15 15:20       ` [PATCH v5 03/14] c++: Implement __remove_extent built-in trait Ken Matsui
2024-02-15 15:20       ` [PATCH v5 04/14] libstdc++: Optimize std::remove_extent compilation performance Ken Matsui
2024-02-15 15:20       ` [PATCH v5 05/14] c++: Implement __remove_all_extents built-in trait Ken Matsui
2024-02-15 15:20       ` [PATCH v5 06/14] libstdc++: Optimize std::remove_all_extents compilation performance Ken Matsui
2024-02-15 15:20       ` [PATCH v5 07/14] c++: Implement __add_lvalue_reference built-in trait Ken Matsui
2024-02-15 15:20       ` [PATCH v5 08/14] libstdc++: Optimize std::add_lvalue_reference compilation performance Ken Matsui
2024-02-15 15:20       ` [PATCH v5 09/14] c++: Implement __add_rvalue_reference built-in trait Ken Matsui
2024-02-15 15:20       ` [PATCH v5 10/14] libstdc++: Optimize std::add_rvalue_reference compilation performance Ken Matsui
2024-02-15 15:20       ` [PATCH v5 11/14] c++: Implement __decay built-in trait Ken Matsui
2024-02-15 15:20       ` [PATCH v5 12/14] libstdc++: Optimize std::decay compilation performance Ken Matsui
2024-02-15 15:20       ` [PATCH v5 13/14] c++: Implement __rank built-in trait Ken Matsui
2024-02-15 21:48         ` Patrick Palka
2024-02-16  2:14           ` Ken Matsui
2024-02-16  2:22             ` Ken Matsui
2024-02-16  2:15         ` [PATCH v6 " Ken Matsui
2024-02-15 15:20       ` [PATCH v5 14/14] libstdc++: Optimize std::rank compilation performance 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).