[gcc r15-134] c++: Implement __is_const built-in trait

2024-05-03 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:7dd8c905219b8e2dfe4ec968a03623989f8f0c80

commit r15-134-g7dd8c905219b8e2dfe4ec968a03623989f8f0c80
Author: Ken Matsui 
Date:   Tue Mar 21 09:10:52 2023 -0700

c++: Implement __is_const built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_const.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONST.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_const.C  | 20 
 5 files changed, 31 insertions(+)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 8a3b5d80ba7..eaf17a50877 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3768,6 +3768,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONST:
+  inform (loc, "  %qT is not a const type", t1);
+  break;
 case CPTK_IS_CONSTRUCTIBLE:
   if (!t2)
 inform (loc, "  %qT is not default constructible", t1);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 394f006f20f..36faed9c0b3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -64,6 +64,7 @@ DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
+DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
 DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
 DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index d0fa324fe5c..b4cda21f682 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12532,6 +12532,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_CLASS:
   return NON_UNION_CLASS_TYPE_P (type1);
 
+case CPTK_IS_CONST:
+  return CP_TYPE_CONST_P (type1);
+
 case CPTK_IS_CONSTRUCTIBLE:
   return is_xible (INIT_EXPR, type1, type2);
 
@@ -12814,6 +12817,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_ARRAY:
 case CPTK_IS_BOUNDED_ARRAY:
 case CPTK_IS_CLASS:
+case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
 case CPTK_IS_FUNCTION:
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 02b4b4d745d..e3640faeb96 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -71,6 +71,9 @@
 #if !__has_builtin (__is_class)
 # error "__has_builtin (__is_class) failed"
 #endif
+#if !__has_builtin (__is_const)
+# error "__has_builtin (__is_const) failed"
+#endif
 #if !__has_builtin (__is_constructible)
 # error "__has_builtin (__is_constructible) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_const.C 
b/gcc/testsuite/g++.dg/ext/is_const.C
new file mode 100644
index 000..8a0e8df72a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_const.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+using cClassType = const ClassType;
+using vClassType = volatile ClassType;
+using cvClassType = const volatile ClassType;
+
+// Positive tests.
+SA(__is_const(const int));
+SA(__is_const(const volatile int));
+SA(__is_const(cClassType));
+SA(__is_const(cvClassType));
+
+// Negative tests.
+SA(!__is_const(int));
+SA(!__is_const(volatile int));
+SA(!__is_const(ClassType));
+SA(!__is_const(vClassType));


[gcc r15-135] c++: Implement __is_volatile built-in trait

2024-05-03 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:9b51b3e79e4b0533bd2b37dcf734ed4a0739af3c

commit r15-135-g9b51b3e79e4b0533bd2b37dcf734ed4a0739af3c
Author: Ken Matsui 
Date:   Wed Mar 22 16:26:25 2023 -0700

c++: Implement __is_volatile built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_VOLATILE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_volatile.C   | 20 
 5 files changed, 31 insertions(+)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index eaf17a50877..d9caf546423 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3862,6 +3862,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
+case CPTK_IS_VOLATILE:
+  inform (loc, "  %qT is not a volatile type", t1);
+  break;
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
   inform (loc, "  %qT is not a reference that binds to a temporary "
  "object of type %qT (direct-initialization)", t1, t2);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 36faed9c0b3..e9347453829 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -92,6 +92,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 (IS_VOLATILE, "__is_volatile", 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_CV, "__remove_cv", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index b4cda21f682..634a324aae7 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12618,6 +12618,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_UNION:
   return type_code1 == UNION_TYPE;
 
+case CPTK_IS_VOLATILE:
+  return CP_TYPE_VOLATILE_P (type1);
+
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
   return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
 
@@ -12828,6 +12831,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_IS_VOLATILE:
   break;
 
 case CPTK_IS_LAYOUT_COMPATIBLE:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index e3640faeb96..b2e2f2f694d 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -158,6 +158,9 @@
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
+#if !__has_builtin (__is_volatile)
+# error "__has_builtin (__is_volatile) 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/is_volatile.C 
b/gcc/testsuite/g++.dg/ext/is_volatile.C
new file mode 100644
index 000..80a1cfc880d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_volatile.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+using cClassType = const ClassType;
+using vClassType = volatile ClassType;
+using cvClassType = const volatile ClassType;
+
+// Positive tests.
+SA(__is_volatile(volatile int));
+SA(__is_volatile(const volatile int));
+SA(__is_volatile(vClassType));
+SA(__is_volatile(cvClassType));
+
+// Negative tests.
+SA(!__is_volatile(int));
+SA(!__is_volatile(const int));
+SA(!__is_volatile(ClassType));
+SA(!__is_volatile(cClassType));


[gcc r15-136] c++: Implement __is_pointer built-in trait

2024-05-03 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:cb5d904c775ed7172f8dd7565ec7f5395503d06f

commit r15-136-gcb5d904c775ed7172f8dd7565ec7f5395503d06f
Author: Ken Matsui 
Date:   Sun Jul 9 17:49:08 2023 -0700

c++: Implement __is_pointer built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_pointer.
Arrange the order lexically around __is_pointer.
* g++.dg/ext/is_pointer.C: New test.

Signed-off-by: Ken Matsui 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  9 --
 gcc/testsuite/g++.dg/ext/is_pointer.C| 51 
 5 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d9caf546423..5a8aaa70fa6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3829,6 +3829,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POD:
   inform (loc, "  %qT is not a POD type", t1);
   break;
+case CPTK_IS_POINTER:
+  inform (loc, "  %qT is not a pointer", t1);
+  break;
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e9347453829..18e2d0f3480 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
+DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 634a324aae7..b8c2bf8771f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12588,6 +12588,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_POD:
   return pod_type_p (type1);
 
+case CPTK_IS_POINTER:
+  return TYPE_PTR_P (type1);
+
 case CPTK_IS_POLYMORPHIC:
   return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
 
@@ -12827,6 +12830,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
 case CPTK_IS_OBJECT:
+case CPTK_IS_POINTER:
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index b2e2f2f694d..4cbe6fe8cea 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -119,12 +119,15 @@
 #if !__has_builtin (__is_object)
 # error "__has_builtin (__is_object) failed"
 #endif
-#if !__has_builtin (__is_pointer_interconvertible_base_of)
-# error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
-#endif
 #if !__has_builtin (__is_pod)
 # error "__has_builtin (__is_pod) failed"
 #endif
+#if !__has_builtin (__is_pointer)
+# error "__has_builtin (__is_pointer) failed"
+#endif
+#if !__has_builtin (__is_pointer_interconvertible_base_of)
+# error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
+#endif
 #if !__has_builtin (__is_polymorphic)
 # error "__has_builtin (__is_polymorphic) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_pointer.C
new file mode 100644
index 000..d6e39565950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(!__is_pointer(int));
+SA(__is_pointer(int*));
+SA(__is_pointer(int**));
+
+SA(__is_pointer(const int*));
+SA(__is_pointer(const int**));
+SA(__is_pointer(int* const));
+SA(__is_pointer(int** const));
+SA(__is_pointer(int* const* const));
+
+SA(__is_pointer(volatile int*));
+SA(__is_pointer(volatile int**));
+SA(__is_pointer(int* volatile));
+SA(__is_pointer(int** volatile));
+SA(__is_pointer(int* volatile* volatile));
+
+SA(__is_pointer(const volatile int*));
+SA(__is_pointer(const volatile int**));
+SA(__is_pointer(const int* volatile));
+SA(__is_pointer(volatile int* const));
+SA(__is_pointer(int* const volatile));
+SA(__is_pointer(const int** volatile));
+SA(__is_pointer(volatile int** const));
+SA(__is_pointer(int** const vol

[gcc r15-206] contrib/gcc-changelog/git_check_commit.py: Implement --num-commits

2024-05-06 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:0e12aa6c26a9566f5b1a9b6d111a9e27507e213d

commit r15-206-g0e12aa6c26a9566f5b1a9b6d111a9e27507e213d
Author: Ken Matsui 
Date:   Wed Feb 28 13:00:23 2024 -0800

contrib/gcc-changelog/git_check_commit.py: Implement --num-commits

This patch implements a --num-commits (-n) flag for shorthand for
the range of hash~N..hash commits.

contrib/ChangeLog:

* gcc-changelog/git_check_commit.py: Implement --num-commits.

Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jason Merrill 

Diff:
---
 contrib/gcc-changelog/git_check_commit.py | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/contrib/gcc-changelog/git_check_commit.py 
b/contrib/gcc-changelog/git_check_commit.py
index 8cca9f439a5..22e032e8b38 100755
--- a/contrib/gcc-changelog/git_check_commit.py
+++ b/contrib/gcc-changelog/git_check_commit.py
@@ -22,6 +22,12 @@ import argparse
 
 from git_repository import parse_git_revisions
 
+def nonzero_uint(value):
+ivalue = int(value)
+if ivalue <= 0:
+raise argparse.ArgumentTypeError('%s is not a non-zero positive 
integer' % value)
+return ivalue
+
 parser = argparse.ArgumentParser(description='Check git ChangeLog format '
  'of a commit')
 parser.add_argument('revisions', default='HEAD', nargs='?',
@@ -33,8 +39,17 @@ parser.add_argument('-p', '--print-changelog', 
action='store_true',
 help='Print final changelog entires')
 parser.add_argument('-v', '--verbose', action='store_true',
 help='Print verbose information')
+parser.add_argument('-n', '--num-commits', type=nonzero_uint, default=1,
+help='Number of commits to check (i.e. shorthand for '
+'hash~N..hash)')
 args = parser.parse_args()
 
+if args.num_commits > 1:
+if '..' in args.revisions:
+print('ERR: --num-commits and range of revisions are mutually 
exclusive')
+exit(1)
+args.revisions = '{0}~{1}..{0}'.format(args.revisions, args.num_commits)
+
 retval = 0
 for git_commit in parse_git_revisions(args.git_path, args.revisions):
 res = 'OK' if git_commit.success else 'FAILED'


[gcc r15-368] c++: Implement __is_unbounded_array built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:06d64eb96cd9faf7e725bd4fbe5b859d23c5ecb5

commit r15-368-g06d64eb96cd9faf7e725bd4fbe5b859d23c5ecb5
Author: Ken Matsui 
Date:   Mon Sep 11 13:54:39 2023 -0700

c++: Implement __is_unbounded_array built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_UNBOUNDED_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc  |  3 +++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/semantics.cc   |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +++
 gcc/testsuite/g++.dg/ext/is_unbounded_array.C | 37 +++
 5 files changed, 48 insertions(+)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5a8aaa70fa60..d4cc88504863 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3862,6 +3862,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIALLY_COPYABLE:
   inform (loc, "  %qT is not trivially copyable", t1);
   break;
+case CPTK_IS_UNBOUNDED_ARRAY:
+  inform (loc, "  %qT is not an unbounded array", t1);
+  break;
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 18e2d0f3480c..05514a51c21f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -92,6 +92,7 @@ DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 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_UNBOUNDED_ARRAY, "__is_unbounded_array", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
 DEFTRAIT_EXPR (IS_VOLATILE, "__is_volatile", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 71520dcd4fa9..e49d3e35e8b5 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12620,6 +12620,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_TRIVIALLY_COPYABLE:
   return trivially_copyable_p (type1);
 
+case CPTK_IS_UNBOUNDED_ARRAY:
+  return array_of_unknown_bound_p (type1);
+
 case CPTK_IS_UNION:
   return type_code1 == UNION_TYPE;
 
@@ -12836,6 +12839,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
+case CPTK_IS_UNBOUNDED_ARRAY:
 case CPTK_IS_UNION:
 case CPTK_IS_VOLATILE:
   break;
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4cbe6fe8cea4..1e10c87754a3 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -158,6 +158,9 @@
 #if !__has_builtin (__is_trivially_copyable)
 # error "__has_builtin (__is_trivially_copyable) failed"
 #endif
+#if !__has_builtin (__is_unbounded_array)
+# error "__has_builtin (__is_unbounded_array) failed"
+#endif
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_unbounded_array.C 
b/gcc/testsuite/g++.dg/ext/is_unbounded_array.C
new file mode 100644
index ..283a74e1a0a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_unbounded_array.C
@@ -0,0 +1,37 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+class ClassType { };
+class IncompleteClass;
+union IncompleteUnion;
+
+SA_TEST_CATEGORY(__is_unbounded_array, int[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, int[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, int[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, int[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[], true);
+SA_TES

[gcc r15-369] c++: Implement __add_pointer built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:2763f81e0b93700bc879690ce2a7d258c3989924

commit r15-369-g2763f81e0b93700bc879690ce2a7d258c3989924
Author: Ken Matsui 
Date:   Wed Feb 14 03:40:00 2024 -0800

c++: Implement __add_pointer built-in trait

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.
(object_type_p): New function.
(referenceable_type_p): Likewise.
(trait_expr_value): Use object_type_p.

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 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  | 36 ++---
 gcc/testsuite/g++.dg/ext/add_pointer.C   | 39 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 4 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 05514a51c21f..63f879287ce1 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 e49d3e35e8b5..4920b5627849 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12438,6 +12438,16 @@ fold_builtin_is_corresponding_member (location_t loc, 
int nargs,
   fold_convert (TREE_TYPE (arg1), arg2)));
 }
 
+/* [basic.types] 8.  True iff TYPE is an object type.  */
+
+static bool
+object_type_p (const_tree type)
+{
+  return (TREE_CODE (type) != FUNCTION_TYPE
+  && !TYPE_REF_P (type)
+  && !VOID_TYPE_P (type));
+}
+
 /* Actually evaluates the trait.  */
 
 static bool
@@ -12580,9 +12590,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
   return is_nothrow_convertible (type1, type2);
 
 case CPTK_IS_OBJECT:
-  return (type_code1 != FUNCTION_TYPE
- && type_code1 != REFERENCE_TYPE
- && type_code1 != VOID_TYPE);
+  return object_type_p (type1);
 
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   return pointer_interconvertible_base_of_p (type1, type2);
@@ -12737,6 +12745,18 @@ same_type_ref_bind_p (cp_trait_kind kind, tree type1, 
tree type2)
  (non_reference (to), non_reference (from;
 }
 
+/* [defns.referenceable] True iff TYPE is a referenceable type.  */
+
+static bool
+referenceable_type_p (const_tree type)
+{
+  return (TYPE_REF_P (type)
+ || object_type_p (type)
+ || (FUNC_OR_METHOD_TYPE_P (type)
+ && (type_memfn_quals (type) == TYPE_UNQUALIFIED
+ && type_memfn_rqual (type) == REF_QUAL_NONE)));
+}
+
 /* Process a trait expression.  */
 
 tree
@@ -12904,6 +12924,16 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
 
   switch (kind)
 {
+case CPTK_ADD_POINTER:
+  /* [meta.trans.ptr].  */
+  if (VOID_TYPE_P (type1) || referenceable_type_p (type1))
+   {
+ if (TYPE_REF_P (type1))
+   type1 = TREE_TYPE (type1);
+ return build_pointer_type (type1);
+   }
+  return 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 ..c405cdd0feb5
--- /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_s

[gcc r15-370] c++: Implement __remove_extent built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:e1ca1fa1c7a347088551aa7de521d2a87c1a7863

commit r15-370-ge1ca1fa1c7a347088551aa7de521d2a87c1a7863
Author: Ken Matsui 
Date:   Wed Feb 14 05:49:35 2024 -0800

c++: Implement __remove_extent built-in trait

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 
Reviewed-by: Jason Merrill 

Diff:
---
 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(+)

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 63f879287ce1..577c96d579bf 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -100,6 +100,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 4920b5627849..b2122cedff5e 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12942,6 +12942,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 bd9e064ce3aa..d58e41867049 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -182,6 +182,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 ..6183aca5a487
--- /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));


[gcc r15-371] c++: Implement __remove_all_extents built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:86812be98a129ac9923df5dfb6b457bfe28e9e8c

commit r15-371-g86812be98a129ac9923df5dfb6b457bfe28e9e8c
Author: Ken Matsui 
Date:   Wed Feb 14 22:45:31 2024 -0800

c++: Implement __remove_all_extents built-in trait

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 
Reviewed-by: Jason Merrill 

Diff:
---
 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(+)

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 577c96d579bf..933c8bcbe68e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -98,6 +98,7 @@ DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
 DEFTRAIT_EXPR (IS_VOLATILE, "__is_volatile", 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 b2122cedff5e..c2ab08c56052 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12934,6 +12934,9 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree 
type2,
}
   return 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 d58e41867049..f0b165e28916 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -176,6 +176,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 ..60ade2ade7fc
--- /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));


[gcc r15-372] c++: Implement __add_lvalue_reference built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:c08d1afbf539a672f28100640d964565ac575ff5

commit r15-372-gc08d1afbf539a672f28100640d964565ac575ff5
Author: Ken Matsui 
Date:   Wed Feb 14 23:21:35 2024 -0800

c++: Implement __add_lvalue_reference built-in trait

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 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/semantics.cc |  6 ++
 gcc/testsuite/g++.dg/ext/add_lvalue_reference.C | 21 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 +++
 4 files changed, 31 insertions(+)

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 933c8bcbe68e..9a27dca4ea35 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 c2ab08c56052..a6f795d6336b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12924,6 +12924,12 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
 
   switch (kind)
 {
+case CPTK_ADD_LVALUE_REFERENCE:
+  /* [meta.trans.ref].  */
+  if (referenceable_type_p (type1))
+   return cp_build_reference_type (type1, /*rval=*/false);
+  return type1;
+
 case CPTK_ADD_POINTER:
   /* [meta.trans.ptr].  */
   if (VOID_TYPE_P (type1) || referenceable_type_p (type1))
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 ..8fe1e0300e5a
--- /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 f0b165e28916..a8b2f0fcfd28 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


[gcc r15-373] c++: Implement __add_rvalue_reference built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:85c2ba4244196dcccdf0647ff49f376c52513f65

commit r15-373-g85c2ba4244196dcccdf0647ff49f376c52513f65
Author: Ken Matsui 
Date:   Thu Feb 15 00:48:14 2024 -0800

c++: Implement __add_rvalue_reference built-in trait

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 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/semantics.cc |  6 ++
 gcc/testsuite/g++.dg/ext/add_rvalue_reference.C | 20 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 +++
 4 files changed, 30 insertions(+)

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9a27dca4ea35..173818adf792 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 a6f795d6336b..f6338f77d239 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12940,6 +12940,12 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
}
   return type1;
 
+case CPTK_ADD_RVALUE_REFERENCE:
+  /* [meta.trans.ref].  */
+  if (referenceable_type_p (type1))
+   return cp_build_reference_type (type1, /*rval=*/true);
+  return type1;
+
 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 ..c92fe6bfa17b
--- /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 a8b2f0fcfd28..266cb35a3684 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


[gcc r15-374] c++: Implement __decay built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:142d1d8e057c0e6da7f4e6eba4cc265c556d2dd8

commit r15-374-g142d1d8e057c0e6da7f4e6eba4cc265c556d2dd8
Author: Ken Matsui 
Date:   Thu Feb 15 04:43:41 2024 -0800

c++: Implement __decay built-in trait

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 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  | 12 
 gcc/testsuite/g++.dg/ext/decay.C | 22 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 4 files changed, 38 insertions(+)

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 173818adf792..2d1cb7c227c0 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 f6338f77d239..d499b858057c 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12946,6 +12946,18 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
return cp_build_reference_type (type1, /*rval=*/true);
   return type1;
 
+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 ..8adedfeefe6c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/decay.C
@@ -0,0 +1,22 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+// 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));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 266cb35a3684..d2e6a5b4dcb3 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -32,6 +32,9 @@
 #if !__has_builtin (__builtin_source_location)
 # error "__has_builtin (__builtin_source_location) failed"
 #endif
+#if !__has_builtin (__decay)
+# error "__has_builtin (__decay) failed"
+#endif
 #if !__has_builtin (__has_nothrow_assign)
 # error "__has_builtin (__has_nothrow_assign) failed"
 #endif


[gcc r15-375] c++: Implement __array_rank built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:37fad797adea340307fb33c3d7a0a17652063a33

commit r15-375-g37fad797adea340307fb33c3d7a0a17652063a33
Author: Ken Matsui 
Date:   Thu Feb 15 07:17:31 2024 -0800

c++: Implement __array_rank built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  | 24 +---
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/rank.C  | 24 
 5 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d4cc88504863..c28d7bf428ee 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3871,6 +3871,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_VOLATILE:
   inform (loc, "  %qT is not a volatile type", t1);
   break;
+case CPTK_RANK:
+  inform (loc, "  %qT cannot yield a rank", t1);
+  break;
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
   inform (loc, "  %qT is not a reference that binds to a temporary "
  "object of type %qT (direct-initialization)", t1, t2);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 2d1cb7c227c0..b1c875a6e7d4 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -99,6 +99,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, 
"__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
 DEFTRAIT_EXPR (IS_VOLATILE, "__is_volatile", 1)
+DEFTRAIT_EXPR (RANK, "__array_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 d499b858057c..bde26e4f2bb4 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12646,6 +12646,10 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_DEDUCIBLE:
   return type_targs_deducible_from (type1, type2);
 
+/* __array_rank is handled in finish_trait_expr. */
+case CPTK_RANK:
+  gcc_unreachable ();
+
 #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
 case CPTK_##CODE:
 #include "cp-trait.def"
@@ -12769,7 +12773,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;
@@ -12862,6 +12869,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_UNBOUNDED_ARRAY:
 case CPTK_IS_UNION:
 case CPTK_IS_VOLATILE:
+case CPTK_RANK:
   break;
 
 case CPTK_IS_LAYOUT_COMPATIBLE:
@@ -12893,8 +12901,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 __array_rank = 0;
+  for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
+   ++__array_rank;
+  val = build_int_cst (size_type_node, __array_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 d2e6a5b4dcb3..bcaa56a7bc5c 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 (__array_rank)
+# error "__has_builtin (__array_rank) failed"
+#endif
 #if !__has_builtin (__builtin_addressof)
 # error "__has_builtin (__builtin_addressof) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/rank.C b/gcc/testsuite/g++.dg/ext/rank.C
new file 

[gcc r15-376] c++: Implement __is_invocable built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:7bd33955970202095738e85c4ddf161432ece099

commit r15-376-g7bd33955970202095738e85c4ddf161432ece099
Author: Ken Matsui 
Date:   Mon Feb 19 18:10:16 2024 -0800

c++: Implement __is_invocable built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_invocable.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_INVOCABLE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
* cp-tree.h (build_invoke): New function.
* method.cc (build_invoke): New function.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_invocable.
* g++.dg/ext/is_invocable1.C: New test.
* g++.dg/ext/is_invocable2.C: New test.
* g++.dg/ext/is_invocable3.C: New test.
* g++.dg/ext/is_invocable4.C: New test.

Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc |   6 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-tree.h |   2 +
 gcc/cp/method.cc | 135 
 gcc/cp/semantics.cc  |   5 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_invocable1.C | 349 +++
 gcc/testsuite/g++.dg/ext/is_invocable2.C | 139 
 gcc/testsuite/g++.dg/ext/is_invocable3.C |  51 +
 gcc/testsuite/g++.dg/ext/is_invocable4.C |  33 +++
 10 files changed, 724 insertions(+)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c28d7bf428ee..6d14ef7dcc75 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3792,6 +3792,12 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_FUNCTION:
   inform (loc, "  %qT is not a function", t1);
   break;
+case CPTK_IS_INVOCABLE:
+  if (!t2)
+inform (loc, "  %qT is not invocable", t1);
+  else
+inform (loc, "  %qT is not invocable by %qE", t1, t2);
+  break;
 case CPTK_IS_LAYOUT_COMPATIBLE:
   inform (loc, "  %qT is not layout compatible with %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b1c875a6e7d4..4e420d5390a6 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -75,6 +75,7 @@ DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
 DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_FUNCTION, "__is_function", 1)
+DEFTRAIT_EXPR (IS_INVOCABLE, "__is_invocable", -1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
 DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 07e9632942bb..e68ca1dd5e7b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7341,6 +7341,8 @@ extern tree get_copy_assign   (tree);
 extern tree get_default_ctor   (tree);
 extern tree get_dtor   (tree, tsubst_flags_t);
 extern tree build_stub_object  (tree);
+extern tree build_invoke   (tree, const_tree,
+tsubst_flags_t);
 extern tree strip_inheriting_ctors (tree);
 extern tree inherited_ctor_binfo   (tree);
 extern bool base_ctor_omit_inherited_parms (tree);
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 08a3d34fb016..0b21656ed612 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -1928,6 +1928,141 @@ build_trait_object (tree type)
   return build_stub_object (type);
 }
 
+/* [func.require] Build an expression of INVOKE(FN_TYPE, ARG_TYPES...).  If the
+   given is not invocable, returns error_mark_node.  */
+
+tree
+build_invoke (tree fn_type, const_tree arg_types, tsubst_flags_t complain)
+{
+  if (error_operand_p (fn_type) || error_operand_p (arg_types))
+return error_mark_node;
+
+  gcc_assert (TYPE_P (fn_type));
+  gcc_assert (TREE_CODE (arg_types) == TREE_VEC);
+
+  /* Access check is required to determine if the given is invocable.  */
+  deferring_access_check_sentinel acs (dk_no_deferred);
+
+  /* INVOKE is an unevaluated context.  */
+  cp_unevaluated cp_uneval_guard;
+
+  bool is_ptrdatamem;
+  bool is_ptrmemfunc;
+  if (TREE_CODE (fn_type) == REFERENCE_TYPE)
+{
+  tree non_ref_fn_type = TREE_TYPE (fn_type);
+  is_ptrdatamem = TYPE_PTRDATAMEM_P (non_ref_fn_type);
+  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (non_ref_fn_type);
+
+  /* Dereference fn_type if it is a pointer to member.  */
+  if (is_ptrdatamem || is_ptrmemfunc)
+   fn_type = non_ref_fn_type;
+}
+  else
+{
+  is_ptrdatamem = TYPE_PTRDATAMEM_P (fn_type);
+  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (fn_type);

[gcc r15-377] c++: Implement __is_nothrow_invocable built-in trait

2024-05-10 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:3dab8f8a542aeabfab1a244a7a601b220680c80b

commit r15-377-g3dab8f8a542aeabfab1a244a7a601b220680c80b
Author: Ken Matsui 
Date:   Wed Feb 21 00:46:56 2024 -0800

c++: Implement __is_nothrow_invocable built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_nothrow_invocable.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_NOTHROW_INVOCABLE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/constraint.cc|  6 +++
 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/is_nothrow_invocable.C | 62 +
 5 files changed, 77 insertions(+)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 6d14ef7dcc75..8679d3ce658d 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3825,6 +3825,12 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_NOTHROW_CONVERTIBLE:
  inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
   break;
+case CPTK_IS_NOTHROW_INVOCABLE:
+   if (!t2)
+ inform (loc, "  %qT is not nothrow invocable", t1);
+   else
+ inform (loc, "  %qT is not nothrow invocable by %qE", t1, t2);
+   break;
 case CPTK_IS_OBJECT:
   inform (loc, "  %qT is not an object type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 4e420d5390a6..0721ecdf3f05 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -84,6 +84,7 @@ DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
+DEFTRAIT_EXPR (IS_NOTHROW_INVOCABLE, "__is_nothrow_invocable", -1)
 DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 311e4f472d83..43b175f92fdc 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12592,6 +12592,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_NOTHROW_CONVERTIBLE:
   return is_nothrow_convertible (type1, type2);
 
+case CPTK_IS_NOTHROW_INVOCABLE:
+  return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
+
 case CPTK_IS_OBJECT:
   return object_type_p (type1);
 
@@ -12727,6 +12730,7 @@ same_type_ref_bind_p (cp_trait_kind kind, tree type1, 
tree type2)
 case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
 case CPTK_IS_INVOCABLE:
+case CPTK_IS_NOTHROW_INVOCABLE:
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
 case CPTK_REF_CONVERTS_FROM_TEMPORARY:
   to = type1;
@@ -12832,6 +12836,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_INVOCABLE:
 case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
 case CPTK_IS_NOTHROW_CONVERTIBLE:
+case CPTK_IS_NOTHROW_INVOCABLE:
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
 case CPTK_REF_CONVERTS_FROM_TEMPORARY:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index d1c662678556..65740a118001 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -134,6 +134,9 @@
 #if !__has_builtin (__is_nothrow_convertible)
 # error "__has_builtin (__is_nothrow_convertible) failed"
 #endif
+#if !__has_builtin (__is_nothrow_invocable)
+# error "__has_builtin (__is_nothrow_invocable) failed"
+#endif
 #if !__has_builtin (__is_object)
 # error "__has_builtin (__is_object) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C 
b/gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C
new file mode 100644
index ..2f9b40e5538d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C
@@ -0,0 +1,62 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+using func_type = void(*)();
+SA( ! __is_nothrow_invocable(func_type) );
+
+#if __cpp_noexcept_function_type
+using func_type_nt = void(*)() noexcept;
+SA(   __is_nothrow_invocable(func_type_nt) );
+#endif
+
+struct X { };
+using mem_type = int X::*;
+
+SA( ! __is_nothrow_invocable(mem_t

[gcc r15-437] c++: Avoid using __array_rank as a variable name [PR115061]

2024-05-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:30ff6c55ba0f2262cf292c90d7b9d771005305f0

commit r15-437-g30ff6c55ba0f2262cf292c90d7b9d771005305f0
Author: Ken Matsui 
Date:   Sun May 12 23:43:55 2024 -0700

c++: Avoid using __array_rank as a variable name [PR115061]

This patch fixes a compilation error when building GCC using Clang.
Since __array_rank is used as a built-in trait name, use rank instead.

PR c++/115061

gcc/cp/ChangeLog:

* semantics.cc (finish_trait_expr): Use rank instead of
__array_rank.

Signed-off-by: Ken Matsui 

Diff:
---
 gcc/cp/semantics.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 43b175f92fdc..df62e2d80dbd 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12914,10 +12914,10 @@ finish_trait_expr (location_t loc, cp_trait_kind 
kind, tree type1, tree type2)
   tree val;
   if (kind == CPTK_RANK)
 {
-  size_t __array_rank = 0;
+  size_t rank = 0;
   for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
-   ++__array_rank;
-  val = build_int_cst (size_type_node, __array_rank);
+   ++rank;
+  val = build_int_cst (size_type_node, rank);
 }
   else
 val = (trait_expr_value (kind, type1, type2)


[gcc r15-1245] libstdc++: Optimize std::is_const compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:eea62ce6fbcffb8acc227e5dbed74d2b627ce84d

commit r15-1245-geea62ce6fbcffb8acc227e5dbed74d2b627ce84d
Author: Ken Matsui 
Date:   Tue Mar 21 17:09:34 2023 -0700

libstdc++: Optimize std::is_const compilation performance

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

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_const): Use __is_const built-in
trait.
(is_const_v): Likewise.

Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 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 b441bf9908f7..8df0cf3ac3b8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -835,6 +835,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Type properties.
 
   /// is_const
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+  template
+struct is_const
+: public __bool_constant<__is_const(_Tp)>
+{ };
+#else
   template
 struct is_const
 : public false_type { };
@@ -842,6 +848,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_const<_Tp const>
 : public true_type { };
+#endif
 
   /// is_volatile
   template
@@ -3331,10 +3338,15 @@ template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+template 
+  inline constexpr bool is_const_v = __is_const(_Tp);
+#else
 template 
   inline constexpr bool is_const_v = false;
 template 
   inline constexpr bool is_const_v = true;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
 template 


[gcc r15-1246] libstdc++: Optimize std::is_volatile compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:bb99672e0c49d8b8822664eaabc10cd51a42aab4

commit r15-1246-gbb99672e0c49d8b8822664eaabc10cd51a42aab4
Author: Ken Matsui 
Date:   Wed Mar 22 16:28:06 2023 -0700

libstdc++: Optimize std::is_volatile compilation performance

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

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_volatile): Use __is_volatile
built-in trait.
(is_volatile_v): Likewise.

Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 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 8df0cf3ac3b8..748fa186881d 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -851,6 +851,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_volatile
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+  template
+struct is_volatile
+: public __bool_constant<__is_volatile(_Tp)>
+{ };
+#else
   template
 struct is_volatile
 : public false_type { };
@@ -858,6 +864,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
@@ -3360,10 +3367,15 @@ template 
   inline constexpr bool is_function_v<_Tp&&> = false;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+template 
+  inline constexpr bool is_volatile_v = __is_volatile(_Tp);
+#else
 template 
   inline constexpr bool is_volatile_v = false;
 template 
   inline constexpr bool is_volatile_v = true;
+#endif
 
 template 
   inline constexpr bool is_trivial_v = __is_trivial(_Tp);


[gcc r15-1249] libstdc++: Optimize std::remove_extent compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:d5e994f44653b913e24753351e713befffbf1a01

commit r15-1249-gd5e994f44653b913e24753351e713befffbf1a01
Author: Ken Matsui 
Date:   Wed Feb 14 05:50:49 2024 -0800

libstdc++: Optimize std::remove_extent compilation performance

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 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 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 e179015be934..02d7a3e50171 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2078,6 +2078,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Array modifications.
 
   /// remove_extent
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent)
+  template
+struct remove_extent
+{ using type = __remove_extent(_Tp); };
+#else
   template
 struct remove_extent
 { using type = _Tp; };
@@ -2089,6 +2094,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct remove_extent<_Tp[]>
 { using type = _Tp; };
+#endif
 
   /// remove_all_extents
   template


[gcc r15-1250] libstdc++: Optimize std::remove_all_extents compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:66f5bebd126657ec4b430fa9bc4b8557485f469d

commit r15-1250-g66f5bebd126657ec4b430fa9bc4b8557485f469d
Author: Ken Matsui 
Date:   Wed Feb 14 22:47:05 2024 -0800

libstdc++: Optimize std::remove_all_extents compilation performance

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 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 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 02d7a3e50171..23432ac43ac6 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2097,6 +2097,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// remove_all_extents
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_all_extents)
+  template
+struct remove_all_extents
+{ using type = __remove_all_extents(_Tp); };
+#else
   template
 struct remove_all_extents
 { using type = _Tp; };
@@ -2108,6 +2113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct remove_all_extents<_Tp[]>
 { using type = typename remove_all_extents<_Tp>::type; };
+#endif
 
 #if __cplusplus > 201103L
   /// Alias template for remove_extent


[gcc r15-1251] libstdc++: Optimize std::decay compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:9d0dba02c5452d5906f87e59455a4c38944eb217

commit r15-1251-g9d0dba02c5452d5906f87e59455a4c38944eb217
Author: Ken Matsui 
Date:   Thu Feb 15 04:44:54 2024 -0800

libstdc++: Optimize std::decay compilation performance

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 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 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 23432ac43ac6..3d158f993a8b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2278,6 +2278,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @cond undocumented
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__decay)
+  template
+struct decay
+{ using type = __decay(_Tp); };
+#else
   // Decay trait for arrays and functions, used for perfect forwarding
   // in make_pair, make_tuple, etc.
   template
@@ -2309,6 +2314,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct decay<_Tp&&>
 { using type = typename __decay_selector<_Tp>::type; };
+#endif
 
   /// @cond undocumented


[gcc r15-1254] libstdc++: Optimize std::is_nothrow_invocable compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:3060e9230264d60be349414285c361b7d32f233c

commit r15-1254-g3060e9230264d60be349414285c361b7d32f233c
Author: Ken Matsui 
Date:   Wed Feb 21 00:49:10 2024 -0800

libstdc++: Optimize std::is_nothrow_invocable compilation performance

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

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_nothrow_invocable): Use
__is_nothrow_invocable built-in trait.
* testsuite/20_util/is_nothrow_invocable/incomplete_args_neg.cc:
Handle the new error from __is_nothrow_invocable.
* testsuite/20_util/is_nothrow_invocable/incomplete_neg.cc:
Likewise.

Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 libstdc++-v3/include/std/type_traits  | 4 
 .../testsuite/20_util/is_nothrow_invocable/incomplete_args_neg.cc | 1 +
 libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_neg.cc | 1 +
 3 files changed, 6 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index fcaff88c1932..8c8219b2697c 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3231,8 +3231,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// std::is_nothrow_invocable
   template
 struct is_nothrow_invocable
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
+: public __bool_constant<__is_nothrow_invocable(_Fn, _ArgTypes...)>
+#else
 : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>,
 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
+#endif
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
"_Fn must be a complete class or an unbounded array");
diff --git 
a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_args_neg.cc 
b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_args_neg.cc
index 3c225883eaf2..3f8542dd366d 100644
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_args_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_args_neg.cc
@@ -18,6 +18,7 @@
 // .
 
 // { dg-error "must be a complete class" "" { target *-*-* } 0 }
+// { dg-prune-output "invalid use of incomplete type" }
 
 #include 
 
diff --git 
a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_neg.cc 
b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_neg.cc
index 5a728bfa03ba..d3bdf08448b5 100644
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/incomplete_neg.cc
@@ -18,6 +18,7 @@
 // .
 
 // { dg-error "must be a complete class" "" { target *-*-* } 0 }
+// { dg-prune-output "invalid use of incomplete type" }
 
 #include 


[gcc r15-1289] libstdc++: Optimize std::is_pointer compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:014879ea4c86b3b8ab6b61a1226ee5b31e816c8b

commit r15-1289-g014879ea4c86b3b8ab6b61a1226ee5b31e816c8b
Author: Ken Matsui 
Date:   Wed Jul 12 13:43:44 2023 -0700

libstdc++: Optimize std::is_pointer compilation performance

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

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_pointer): Use
__is_pointer built-in trait.
* include/std/type_traits (is_pointer): Likewise.  Optimize its
implementation.
(is_pointer_v): Likewise.

Co-authored-by: Jonathan Wakely 
Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 libstdc++-v3/include/bits/cpp_type_traits.h |  8 ++
 libstdc++-v3/include/std/type_traits| 44 +++--
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 59f1a1875eb8..679eee99b904 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -363,6 +363,13 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   //
   // Pointer types
   //
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+  template
+struct __is_pointer : __truth_type<_IsPtr>
+{
+  enum { __value = _IsPtr };
+};
+#else
   template
 struct __is_pointer
 {
@@ -376,6 +383,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   enum { __value = 1 };
   typedef __true_type __type;
 };
+#endif
 
   //
   // An arithmetic type is an integer type or a floating point type
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 8c8219b2697c..0ef112926575 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -542,19 +542,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
 #endif
 
-  template
-struct __is_pointer_helper
+  /// is_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+  template
+struct is_pointer
+: public __bool_constant<__is_pointer(_Tp)>
+{ };
+#else
+  template
+struct is_pointer
 : public false_type { };
 
   template
-struct __is_pointer_helper<_Tp*>
+struct is_pointer<_Tp*>
 : public true_type { };
 
-  /// is_pointer
   template
-struct is_pointer
-: public __is_pointer_helper<__remove_cv_t<_Tp>>::type
-{ };
+struct is_pointer<_Tp* const>
+: public true_type { };
+
+  template
+struct is_pointer<_Tp* volatile>
+: public true_type { };
+
+  template
+struct is_pointer<_Tp* const volatile>
+: public true_type { };
+#endif
 
   /// is_lvalue_reference
   template
@@ -3306,8 +3320,22 @@ template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+template 
+  inline constexpr bool is_pointer_v = __is_pointer(_Tp);
+#else
 template 
-  inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
+  inline constexpr bool is_pointer_v = false;
+template 
+  inline constexpr bool is_pointer_v<_Tp*> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* const> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* volatile> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* const volatile> = true;
+#endif
+
 template 
   inline constexpr bool is_lvalue_reference_v = false;
 template 


[gcc r15-1291] libstdc++: Optimize std::add_rvalue_reference compilation performance

2024-06-13 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:3f3eb16743a126ebe6d200ad0091495b6f11962a

commit r15-1291-g3f3eb16743a126ebe6d200ad0091495b6f11962a
Author: Ken Matsui 
Date:   Thu Feb 15 00:49:55 2024 -0800

libstdc++: Optimize std::add_rvalue_reference compilation performance

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_rval_ref_t): Use
__add_rvalue_reference built-in trait.

Signed-off-by: Ken Matsui 
Reviewed-by: Patrick Palka 
Reviewed-by: Jonathan Wakely 

Diff:
---
 libstdc++-v3/include/std/type_traits | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 79983ea980a1..a31de2ee4abb 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1184,6 +1184,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 };
 
   /// @cond undocumented
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
+  template
+using __add_rval_ref_t = __add_rvalue_reference(_Tp);
+#else
   template
 struct __add_rvalue_reference_helper
 { using type = _Tp; };
@@ -1194,6 +1198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type;
+#endif
   /// @endcond
 
   /// is_move_constructible


[gcc r15-4199] libcpp: Use ' instead of %< and %> [PR117039]

2024-10-09 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:f709990333597b30dff54876bfdaada14e9cde30

commit r15-4199-gf709990333597b30dff54876bfdaada14e9cde30
Author: Ken Matsui 
Date:   Wed Oct 9 07:32:20 2024 -0400

libcpp: Use ' instead of %< and %> [PR117039]

PR bootstrap/117039

libcpp/ChangeLog:

* directives.cc (do_pragma_once): Use ' instead of %< and %>.

Signed-off-by: Ken Matsui 

Diff:
---
 libcpp/directives.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcpp/directives.cc b/libcpp/directives.cc
index 95095b08eafe..9c906b390660 100644
--- a/libcpp/directives.cc
+++ b/libcpp/directives.cc
@@ -2075,7 +2075,7 @@ do_pragma_once (cpp_reader *pfile)
 {
   if (_cpp_in_main_source_file (pfile))
 cpp_warning (pfile, CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER,
-"%<#pragma once%> in main file");
+"'#pragma once' in main file");
 
   check_eol (pfile, false);
   _cpp_mark_file_once_only (pfile, pfile->buffer->file);


[gcc r15-4191] gcc, libcpp: Add warning switch for "#pragma once in main file" [PR89808]

2024-10-08 Thread Ken Matsui via Gcc-cvs
https://gcc.gnu.org/g:821d56100e1110ab6a166f50819522254eb30923

commit r15-4191-g821d56100e1110ab6a166f50819522254eb30923
Author: Ken Matsui 
Date:   Fri Mar 1 22:10:55 2024 -0800

gcc, libcpp: Add warning switch for "#pragma once in main file" [PR89808]

This patch adds a warning switch for "#pragma once in main file".  The
warning option name is Wpragma-once-outside-header, which is the same
as Clang provides.

PR preprocessor/89808

gcc/c-family/ChangeLog:

* c.opt (Wpragma_once_outside_header): Define new option.
* c.opt.urls: Regenerate.

gcc/ChangeLog:

* doc/invoke.texi (Warning Options): Document
-Wno-pragma-once-outside-header.

libcpp/ChangeLog:

* include/cpplib.h (cpp_warning_reason): Define
CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER.
* directives.cc (do_pragma_once): Use
CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wno-pragma-once-outside-header.C: New test.
* g++.dg/warn/Wpragma-once-outside-header.C: New test.

Signed-off-by: Ken Matsui 
Reviewed-by: Marek Polacek 

Diff:
---
 gcc/c-family/c.opt |  4 
 gcc/c-family/c.opt.urls|  3 +++
 gcc/doc/invoke.texi| 10 --
 gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C |  5 +
 gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C|  6 ++
 libcpp/directives.cc   |  3 ++-
 libcpp/include/cpplib.h|  3 ++-
 7 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9d1fccadbf99..1f2e72a0bb73 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1214,6 +1214,10 @@ Wpragmas
 C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning
 Warn about misuses of pragmas.
 
+Wpragma-once-outside-header
+C ObjC C++ ObjC++ Var(warn_pragma_once_outside_header) 
CppReason(CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER) Init(1) Warning
+Warn about #pragma once outside of a header.
+
 Wprio-ctor-dtor
 C ObjC C++ ObjC++ Var(warn_prio_ctor_dtor) Init(1) Warning
 Warn if constructor or destructors with priorities from 0 to 100 are used.
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index b77575bc8969..b1593ef41401 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -684,6 +684,9 @@ 
UrlSuffix(gcc/Warning-Options.html#index-Wno-pointer-to-int-cast)
 Wpragmas
 UrlSuffix(gcc/Warning-Options.html#index-Wno-pragmas)
 
+Wpragma-once-outside-header
+UrlSuffix(gcc/Warning-Options.html#index-Wno-pragma-once-outside-header)
+
 Wprio-ctor-dtor
 UrlSuffix(gcc/Warning-Options.html#index-Wno-prio-ctor-dtor)
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b2f16b45eaf4..c0c8bf1c29a9 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -395,8 +395,8 @@ Objective-C and Objective-C++ Dialects}.
 -Wpacked  -Wno-packed-bitfield-compat  -Wpacked-not-aligned  -Wpadded
 -Wparentheses  -Wno-pedantic-ms-format
 -Wpointer-arith  -Wno-pointer-compare  -Wno-pointer-to-int-cast
--Wno-pragmas  -Wno-prio-ctor-dtor  -Wredundant-decls
--Wrestrict  -Wno-return-local-addr  -Wreturn-type
+-Wno-pragmas  -Wno-pragma-once-outside-header  -Wno-prio-ctor-dtor
+-Wredundant-decls  -Wrestrict  -Wno-return-local-addr  -Wreturn-type
 -Wno-scalar-storage-order  -Wsequence-point
 -Wshadow  -Wshadow=global  -Wshadow=local  -Wshadow=compatible-local
 -Wno-shadow-ivar
@@ -8147,6 +8147,12 @@ Do not warn about misuses of pragmas, such as incorrect 
parameters,
 invalid syntax, or conflicts between pragmas.  See also
 @option{-Wunknown-pragmas}.
 
+@opindex Wno-pragma-once-outside-header
+@opindex Wpragma-once-outside-header
+@item -Wno-pragma-once-outside-header
+Do not warn when @code{#pragma once} is used in a file that is not a header
+file, such as a main file.
+
 @opindex Wno-prio-ctor-dtor
 @opindex Wprio-ctor-dtor
 @item -Wno-prio-ctor-dtor
diff --git a/gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C 
b/gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C
new file mode 100644
index ..b5be4d25a9d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C
@@ -0,0 +1,5 @@
+// { dg-do assemble  }
+// { dg-options "-Wno-pragma-once-outside-header" }
+
+#pragma once
+int main() {}
diff --git a/gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C 
b/gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C
new file mode 100644
index ..448e26102919
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C
@@ -0,0 +1,6 @@
+// { dg-do assemble  }
+// { dg-options "-Werror=pragma-once-outside-header" }
+// { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 }
+
+#pragma once  // { dg