Re: [PATCH v2] c++: Fix compile-time-hog in cp_fold_immediate_r [PR111660]

2023-10-13 Thread Jason Merrill

On 10/13/23 14:53, Marek Polacek wrote:

On Thu, Oct 12, 2023 at 09:41:43PM -0400, Jason Merrill wrote:

On 10/12/23 17:04, Marek Polacek wrote:

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
My recent patch introducing cp_fold_immediate_r caused exponential
compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
case recursively walks the arms of a COND_EXPR, but after processing
both arms it doesn't end the walk; it proceeds to walk the
sub-expressions of the outermost COND_EXPR, triggering again walking
the arms of the nested COND_EXPR, and so on.  This patch brings the
compile time down to about 0m0.033s.

I've added some debug prints to make sure that the rest of cp_fold_r
is still performed as before.

  PR c++/111660

gcc/cp/ChangeLog:

  * cp-gimplify.cc (cp_fold_immediate_r) : Return
  integer_zero_node instead of break;.
  (cp_fold_immediate): Return true if cp_fold_immediate_r returned
  error_mark_node.

gcc/testsuite/ChangeLog:

  * g++.dg/cpp0x/hog1.C: New test.
---
   gcc/cp/cp-gimplify.cc |  9 ++--
   gcc/testsuite/g++.dg/cpp0x/hog1.C | 77 +++
   2 files changed, 82 insertions(+), 4 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index bdf6e5f98ff..ca622ca169a 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1063,16 +1063,16 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, 
void *data_)
break;
 if (TREE_OPERAND (stmt, 1)
  && cp_walk_tree (_OPERAND (stmt, 1), cp_fold_immediate_r, data,
-  nullptr))
+  nullptr) == error_mark_node)
return error_mark_node;
 if (TREE_OPERAND (stmt, 2)
  && cp_walk_tree (_OPERAND (stmt, 2), cp_fold_immediate_r, data,
-  nullptr))
+  nullptr) == error_mark_node)
return error_mark_node;
 /* We're done here.  Don't clear *walk_subtrees here though: we're 
called
 from cp_fold_r and we must let it recurse on the expression with
 cp_fold.  */
-  break;
+  return integer_zero_node;


I'm concerned this will end up missing something like

1 ? 1 : ((1 ? 1 : 1), immediate())

as the integer_zero_node from the inner ?: will prevent walk_tree from
looking any farther.


You are right.  The line above works as expected, but

   1 ? 1 : ((1 ? 1 : id (42)), id (i));

shows the problem (when the expression isn't used as an initializer).


Maybe we want to handle COND_EXPR in cp_fold_r instead of here?


I hope this version is better.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
My recent patch introducing cp_fold_immediate_r caused exponential
compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
case recursively walks the arms of a COND_EXPR, but after processing
both arms it doesn't end the walk; it proceeds to walk the
sub-expressions of the outermost COND_EXPR, triggering again walking
the arms of the nested COND_EXPR, and so on.  This patch brings the
compile time down to about 0m0.033s.


Is this number still accurate for this version?

This change seems algorithmically better than the current code, but 
still problematic: if we have nested COND_EXPR A/B/C/D/E, it looks like 
we will end up cp_fold_immediate_r walking the arms of E five times, 
once for each COND_EXPR.


What I was thinking by handling COND_EXPR in cp_fold_r was to cp_fold_r 
walk its subtrees (or cp_fold_immediate_r if it's clear from op0 that 
the branch isn't taken) so we can clear *walk_subtrees and we don't 
fold_imm walk a node more than once.



The ff_fold_immediate flag is unused after this patch but since I'm
using it in the P2564 patch, I'm not removing it now.

 PR c++/111660

gcc/cp/ChangeLog:

 * cp-gimplify.cc (cp_fold_immediate_r) : Don't
handle it here.
 (cp_fold_r): Handle COND_EXPR here.

gcc/testsuite/ChangeLog:

 * g++.dg/cpp0x/hog1.C: New test.
* g++.dg/cpp2a/consteval36.C: New test.
---
  gcc/cp/cp-gimplify.cc| 38 +---
  gcc/testsuite/g++.dg/cpp0x/hog1.C| 77 
  gcc/testsuite/g++.dg/cpp2a/consteval36.C | 18 ++
  3 files changed, 111 insertions(+), 22 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/consteval36.C

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index bdf6e5f98ff..801cba141cb 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1052,27 +1052,6 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, 
void *data_)
  
switch (TREE_CODE (stmt))

  {
-/* Unfortunately we must handle code like
-false ? bar () : 42
-   where we have to check bar too.  The cp_fold call in cp_fold_r could
-   

Re: [PATCH v2] c++: implement P2564, consteval needs to propagate up [PR107687]

2023-10-13 Thread Jason Merrill

On 10/10/23 13:20, Marek Polacek wrote:

Thanks for looking into this.  It's kept me occupied for quite a while.


Thanks, nice work.


On Tue, Aug 29, 2023 at 03:26:46PM -0400, Jason Merrill wrote:

On 8/23/23 15:49, Marek Polacek wrote:

+struct A {
+  int x;
+  int y = id(x);
+};
+
+template
+constexpr int k(int) {  // k is not an immediate function because 
A(42) is a
+  return A(42).y;   // constant expression and thus not 
immediate-escalating
+}


Needs use(s) of k to test the comment.


True, and that revealed what I think is a bug in the standard.
In the test I'm saying:

// ??? [expr.const]#example-9 says:
//   k is not an immediate function because A(42) is a
//   constant expression and thus not immediate-escalating
// But I think the call to id(x) is *not* a constant expression and thus
// it is an immediate-escalating expression.  Therefore k *is*
// an immediate function.  So we get the error below.  clang++ agrees.
  
id(x) is not a constant expression because x isn't constant.


Not when considering id(x) by itself, but in the evaluation of A(42), 
the member x has just been initialized to constant 42.  And A(42) is 
constant-evaluated because "An aggregate initialization is an immediate 
invocation if it evaluates a default member initializer that has a 
subexpression that is an immediate-escalating expression."


I assume clang doesn't handle this passage properly yet because it was 
added during core review of the paper, for parity between aggregate 
initialization and constructor escalation.


This can be a follow-up patch.


So.  I think we want to refrain from instantiating things early
given how many problems that caused.  On the other hand, stashing
all the immediate-escalating decls into immediate_escalating_decls
and walking their bodies isn't going to be cheap.  I've checked
how big the vectors can get, but our testsuite isn't the best litmus
test because it's mostly smallish testcases without many #includes.
The worst offender is uninit-pr105562.C with

(gdb) p immediate_escalating_decls->length()
$2 = 2204
(gdb) p deferred_escalating_exprs->length()
$3 = 501

Compiling uninit-pr105562.C with g++13 and g++14 with this patch:
real 7.51 real 7.67
user 7.32 user 7.49
sys 0.15  sys 0.14

I've made sure not to walk the same bodies twice.  But there's room
for further optimization; I suppose we could escalate instantiated
functions right away rather than putting them into
immediate_escalating_decls and waiting till later.


Absolutely; if we see a call to a known consteval function, we should 
escalate...immediately.  As the patch seems to do already?



I'm not certain
if I can just look at DECL_TEMPLATE_INSTANTIATED.


I'm not sure what you mean, but a constexpr function being instantiated 
doesn't necessarily imply that everything it calls has been 
instantiated, so we might not know yet if it needs to escalate.



I suppose some
functions cannot possibly be promoted because they don't contain
any CALL_EXPRs.  So we may be able to rule them out while doing
cp_fold_r early.


Yes.  Or, the only immediate-escalating functions referenced have 
already been checked.


We can also do some escalation during constexpr evaluation: all the 
functions involved need to be instantiated for the evaluation, and if we 
encounter an immediate-escalating expression while evaluating a call to 
an immediate-escalating function, we can promote it then.  Though we 
can't necessarily mark it as not needing promotion, as there might be 
i-e exprs in branches that the particular evaluation doesn't take.



If a function is trivial, can it ever be promoted?


This might be a question for CWG.  clang thinks so:

struct A {
  consteval A() = default;
  consteval A(const A&) = default;
  int i;
};
struct B : A { }; // B constructors promote to consteval
B b; // ok, constant-initialization
B b2(b); // error, immediate invocation isn't constant


And so on.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This patch implements P2564, described at , whereby
certain functions are promoted to consteval.  For example:

   consteval int id(int i) { return i; }

   template 
   constexpr int f(T t)
   {
 return t + id(t); // id causes f to be promoted to consteval
   }

   void g(int i)
   {
 f (3);
   }

now compiles.  Previously the code was ill-formed: we would complain
that 't' in 'f' is not a constant expression.  Since 'f' is now
consteval, it means that the call to id(t) is in an immediate context,
so doesn't have to produce a constant -- this is how we allow consteval
functions composition.  But making 'f' consteval also means that
the call to 'f' in 'g' must yield a constant; failure to do so results
in an error.  I made the effort to have cc1plus explain to us what's
going on.  For example, calling f(i) produces this neat diagnostic:

w.C:11:11: error: call to consteval function 'f(i)' is not a constant 

[Committed] RISC-V: Remove redundant iterators.

2023-10-13 Thread Juzhe-Zhong
These iterators are redundant, removed and commmitted.
gcc/ChangeLog:

* config/riscv/vector-iterators.md: Remove redundant iterators.

---
 gcc/config/riscv/vector-iterators.md | 110 ---
 1 file changed, 110 deletions(-)

diff --git a/gcc/config/riscv/vector-iterators.md 
b/gcc/config/riscv/vector-iterators.md
index 96ddd34c958..6800f8d3d76 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -295,83 +295,6 @@
   RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
 ])
 
-(define_mode_iterator VLMULEXT2 [
-  RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
-
-  RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
-
-  (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") (RVVM2HF "TARGET_VECTOR_ELEN_FP_16")
-  (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16")
-  (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
-
-  RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32")
-
-  (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") (RVVM2SF "TARGET_VECTOR_ELEN_FP_32")
-  (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && 
TARGET_MIN_VLEN > 32")
-
-  (RVVM4DI "TARGET_VECTOR_ELEN_64") (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI 
"TARGET_VECTOR_ELEN_64")
-
-  (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") 
(RVVM1DF "TARGET_VECTOR_ELEN_FP_64")
-])
-
-(define_mode_iterator VLMULEXT4 [
-  RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
-
-  RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
-
-  (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") 
(RVVMF2HF "TARGET_VECTOR_ELEN_FP_16")
-  (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
-
-  RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32")
-
-  (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") 
(RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
-
-  (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
-
-  (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64")
-])
-
-(define_mode_iterator VLMULEXT8 [
-  RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
-
-  RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
-
-  (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16")
-  (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
-
-  RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32")
-
-  (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && 
TARGET_MIN_VLEN > 32")
-
-  (RVVM1DI "TARGET_VECTOR_ELEN_64")
-
-  (RVVM1DF "TARGET_VECTOR_ELEN_FP_64")
-])
-
-(define_mode_iterator VLMULEXT16 [
-  RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
-
-  RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
-
-  (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && 
TARGET_MIN_VLEN > 32")
-
-  (RVVMF2SI "TARGET_MIN_VLEN > 32")
-
-  (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
-])
-
-(define_mode_iterator VLMULEXT32 [
-  RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
-
-  (RVVMF4HI "TARGET_MIN_VLEN > 32")
-
-  (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN > 32")
-])
-
-(define_mode_iterator VLMULEXT64 [
-  (RVVMF8QI "TARGET_MIN_VLEN > 32")
-])
-
 (define_mode_iterator VEI16 [
   RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32")
 
@@ -1579,39 +1502,6 @@
   RVVM4x2QI
 ])
 
-(define_mode_iterator VQI [
-  RVVM8QI RVVM4QI RVVM2QI RVVM1QI RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN 
> 32")
-])
-
-(define_mode_iterator VHI [
-  RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32")
-])
-
-(define_mode_iterator VSI [
-  RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_MIN_VLEN > 32")
-])
-
-(define_mode_iterator VDI [
-  (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64")
-  (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
-])
-
-(define_mode_iterator VHF [
-  (RVVM8HF "TARGET_ZVFH") (RVVM4HF "TARGET_ZVFH") (RVVM2HF "TARGET_ZVFH")
-  (RVVM1HF "TARGET_ZVFH") (RVVMF2HF "TARGET_ZVFH")
-  (RVVMF4HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
-])
-
-(define_mode_iterator VSF [
-  (RVVM8SF "TARGET_VECTOR_ELEN_FP_32") (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") 
(RVVM2SF "TARGET_VECTOR_ELEN_FP_32")
-  (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && 
TARGET_MIN_VLEN > 32")
-])
-
-(define_mode_iterator VDF [
-  (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64")
-  (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64")
-])
-
 (define_mode_attr V_LMUL1 [
   (RVVM8QI "RVVM1QI") (RVVM4QI "RVVM1QI") (RVVM2QI "RVVM1QI") (RVVM1QI 
"RVVM1QI") (RVVMF2QI "RVVM1QI") (RVVMF4QI "RVVM1QI") (RVVMF8QI "RVVM1QI")
 
-- 
2.36.3



[PATCH] MATCH: [PR111432] Simplify `a & (x | CST)` to a when we know that (a & ~CST) == 0

2023-10-13 Thread Andrew Pinski
This adds the simplification `a & (x | CST)` to a when we know that
`(a & ~CST) == 0`. In a similar fashion as `a & CST` is handle.

I looked into handling `a | (x & CST)` but that I don't see any decent
simplifications happening.

OK? Bootstrapped and tested on x86_linux-gnu with no regressions.

PR tree-optimization/111432

gcc/ChangeLog:

* match.pd (`a & (x | CST)`): New pattern.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/bitops-7.c: New test.
---
 gcc/match.pd |  8 
 gcc/testsuite/gcc.dg/tree-ssa/bitops-7.c | 24 
 2 files changed, 32 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bitops-7.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 51e5065d086..45624f3dcb4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1550,6 +1550,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
   && wi::bit_and_not (get_nonzero_bits (@0), wi::to_wide (@1)) == 0)
   @0))
+
+/* `a & (x | CST)` -> a if we know that (a & ~CST) == 0   */
+(simplify
+ (bit_and:c SSA_NAME@0 (bit_ior @1 INTEGER_CST@2))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+  && wi::bit_and_not (get_nonzero_bits (@0), wi::to_wide (@2)) == 0)
+  @0))
+
 /* x | C -> C if we know that x & ~C == 0.  */
 (simplify
  (bit_ior SSA_NAME@0 INTEGER_CST@1)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-7.c 
b/gcc/testsuite/gcc.dg/tree-ssa/bitops-7.c
new file mode 100644
index 000..7fb18db3a11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-7.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/111432 */
+
+int
+foo3(int c, int bb)
+{
+  if ((bb & ~3)!=0) __builtin_unreachable();
+  return (bb & (c|3));
+}
+
+int
+foo_bool(int c, _Bool bb)
+{
+  return (bb & (c|7));
+}
+
+/* Both of these functions should be able to remove the `IOR` and `AND`
+   as the only bits that are non-zero for bb is set on the other side
+   of the `AND`.
+ */
+
+/* { dg-final { scan-tree-dump-not   "bit_ior_expr, "   "optimized" } } */
+/* { dg-final { scan-tree-dump-not   "bit_and_expr, "   "optimized" } } */
-- 
2.39.3



[PATCH] Power10: Add options to disable load and store vector pair.

2023-10-13 Thread Michael Meissner
In working on some future patches that involve utilizing vector pair
instructions, I wanted to be able to tune my program to enable or disable using
the vector pair load or store operations while still keeping the other
operations on the vector pair.

This patch adds two undocumented tuning options.  The -mno-load-vector-pair
option would tell GCC to generate two load vector instructions instead of a
single load vector pair.  The -mno-store-vector-pair option would tell GCC to
generate two store vector instructions instead of a single store vector pair.

If either -mno-load-vector-pair is used, GCC will not generate the indexed
stxvpx instruction.  Similarly if -mno-store-vector-pair is used, GCC will not
generate the indexed lxvpx instruction.  The reason for this is to enable
splitting the {,p}lxvp or {,p}stxvp instructions after reload without needing a
scratch GPR register.

The default for -mcpu=power10 is that both load vector pair and store vector
pair are enabled.

I decided that if the user explicitly used the __builtin_vsx_lxvp or the
__builtin_vsx_stxvp built-in functions to load or store a vector pair, that
those functions would always generate a vector pair instruction.

I added code so that the user code can modify these settings using either a
'#pragma GCC target' directive or used __attribute__((__target__(...))) in the
function declaration.

I added tests for the switches, #pragma, and attribute options.

I have built this on both little endian power10 systems and big endian power9
systems doing the normal bootstrap and test.  There were no regressions in any
of the tests, and the new tests passed.  Can I check this patch into the master
branch?

2023-10-13  Michael Meissner  

gcc/

* config/rs6000/mma.md (movoo): Add support for -mload-vector-pair and
-mstore-vector-pair.
* config/rs6000/rs6000-cpus.def (OTHER_POWER10_MASKS): Likewise.
(POWERPC_MASKS): Likewise.
* config/rs6000/rs6000.md (rs6000_setup_reg_addr_masks): If either load
vector pair or store vector pair instructions are not being generated,
don't allow lxvpx or stxvpx to be generated.
(rs6000_option_override_internal): Add warnings if either
-mload-vector-pair or -mstore-vector-pair is used without having MMA
instructions.
(rs6000_opt_masks): Allow user to override -mload-vector-pair or
-mstore-vector-pair via #pragma or attribute.
* config/rs6000/rs6000.opt (-mload-vector-pair): New option.
(-mstore-vector-pair): Likewise.

gcc/testsuite/

* gcc.target/powerpc/vector-pair-attribute.c: New test.
* gcc.target/powerpc/vector-pair-pragma.c: New test.
* gcc.target/powerpc/vector-pair-switch1.c: New test.
* gcc.target/powerpc/vector-pair-switch2.c: New test.
* gcc.target/powerpc/vector-pair-switch3.c: New test.
* gcc.target/powerpc/vector-pair-switch4.c: New test.
---
 gcc/config/rs6000/mma.md  | 44 +++
 gcc/config/rs6000/rs6000-builtin.cc   | 46 +---
 gcc/config/rs6000/rs6000-builtins.def |  6 ++
 gcc/config/rs6000/rs6000-cpus.def |  8 ++-
 gcc/config/rs6000/rs6000.cc   | 30 +-
 gcc/config/rs6000/rs6000.opt  |  8 +++
 .../powerpc/vector-pair-attribute.c   | 39 +
 .../gcc.target/powerpc/vector-pair-builtin.c  | 40 ++
 .../gcc.target/powerpc/vector-pair-pragma.c   | 55 +++
 .../gcc.target/powerpc/vector-pair-switch1.c  | 16 ++
 .../gcc.target/powerpc/vector-pair-switch2.c  | 17 ++
 .../gcc.target/powerpc/vector-pair-switch3.c  | 17 ++
 .../gcc.target/powerpc/vector-pair-switch4.c  | 17 ++
 13 files changed, 331 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-attribute.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-builtin.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-pragma.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-switch1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-switch2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-switch3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vector-pair-switch4.c

diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index 575751d477e..fc7e95bc167 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -91,6 +91,7 @@ (define_c_enum "unspec"
UNSPEC_MMA_XVI8GER4SPP
UNSPEC_MMA_XXMFACC
UNSPEC_MMA_XXMTACC
+   UNSPEC_MMA_VECTOR_PAIR_MEMORY
   ])
 
 (define_c_enum "unspecv"
@@ -298,6 +299,49 @@ (define_insn_and_split "*movoo"
   "TARGET_MMA
&& (gpc_reg_operand (operands[0], OOmode)
|| gpc_reg_operand (operands[1], OOmode))"
+{
+  if (MEM_P (operands[0]))
+return TARGET_STORE_VECTOR_PAIR ? "stxvp%X0 %x1,%0" : "#";
+
+  if (MEM_P (operands[1]))
+return 

[PATCH] libstdc++: Workaround for LLVM-61763 in ranges

2023-10-13 Thread Benjamin Brock
This is my first time submitting a patch, so my apologies if I'm
submitting incorrectly or missing something.

Clang is unable to compile parts of libstdc++'s ranges implementation
due to LLVM-61763, a Clang frontend compiler bug in handling the
declarations of constrained friends.  The problem areas are zip_view,
zip_transform_view, and adjacent_transform_view.

A simple ranges program like the following fails to compile using
Clang trunk and libstdc++.

  std::vector v = {1, 2, 3, 4};
  int sum = 0;
  for (auto&& [i, j] : std::ranges::views::zip(v, v))
sum += i * j;

In file included from :1:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/ranges:4655:14:
error: type constraint differs in template redeclaration
 4655 | template
  |  ^
. . . . . .

Godbolt: https://godbolt.org/z/Ynbs15aGh

This patch adds a small workaround that avoids declaring constrained
friends when compiling with Clang, instead making some members public.
MSVC's standard library has implemented a similar workaround.

Scanning through libstdc++, there do appear to be other workarounds
for Clang, e.g. in complex and experimental/simd.  Hopefully this kind
of workaround is acceptable---while the core issue is a Clang compiler
bug, it may take a while to fix, and it would be very useful for
libstdc++ ranges to work with Clang in the meantime.

2023-10-13  Benjamin Brock 

libstdc++-v3/ChangeLog:

* include/std/ranges: implement workaround for LLVM-61763 in
  zip_view and adjacency_view

---

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 1d529a886be..7893e3a84c9 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -4632,6 +4632,9 @@ namespace views::__adaptor
   class zip_view<_Vs...>::_Iterator
 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
   {
+#ifdef __clang__ // LLVM-61763 workaround
+  public:
+#endif
 __detail::__tuple_or_pair_t>...> _M_current;

 constexpr explicit
@@ -4652,11 +4655,13 @@ namespace views::__adaptor
return input_iterator_tag{};
 }

+#ifndef __clang__ // LLVM-61763 workaround
 template
   requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
&& regular_invocable<_Fp&, range_reference_t<_Ws>...>
&& std::__detail::__can_reference...>>
   friend class zip_transform_view;
+#endif

   public:
 // iterator_category defined in __zip_view_iter_cat
@@ -5327,6 +5332,9 @@ namespace views::__adaptor
   template
   class adjacent_view<_Vp, _Nm>::_Iterator
   {
+#ifdef __clang__ // LLVM-61763 workaround
+  public:
+#endif
 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
 array, _Nm> _M_current = array, _Nm>();

@@ -5367,12 +5375,14 @@ namespace views::__adaptor

 friend class adjacent_view;

+#ifndef __clang__ // LLVM-61763 workaround
 template
   requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
 && regular_invocable<__detail::__unarize<_Fp&, _Mm>,
range_reference_t<_Wp>>
 && 
std::__detail::__can_reference,

range_reference_t<_Wp>>>
   friend class adjacent_transform_view;
+#endif

   public:
 using iterator_category = input_iterator_tag;


[PATCH v19 10/40] c++: Implement __is_unbounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_unbounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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 
---
 gcc/cp/constraint.cc  |  3 ++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 42 ++-
 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 
 7 files changed, 71 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unbounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e30a4a907a..751ac61b25a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,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 99bc05360b9..4e02f68e4a9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index fb162cac164..a894fc8c74c 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -63,6 +63,7 @@ struct cp_trait {
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
+"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
 "__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 526e63dec42..47060ffbbef 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 48,
+  TOTAL_KEYWORDS = 49,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,30 +125,32 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 76 "../../gcc/cp/cp-trait.gperf"
+#line 77 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 71 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
 #line 62 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_volatile", CPTK_IS_VOLATILE, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
+#line 66 "../../gcc/cp/cp-trait.gperf"
+  

[PATCH v19 29/40] c++: Implement __is_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.
* g++.dg/ext/is_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 155 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_pointer.C|  51 
 7 files changed, 141 insertions(+), 77 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 99a7e7247ce..c9d627fa782 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,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 2add97ae749..c60724e869e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, 
"__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 8fbd67788d5..5d40e04f91c 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -61,6 +61,7 @@ struct cp_trait {
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false
 "__is_pod", CPTK_IS_POD, 1, false
+"__is_pointer", CPTK_IS_POINTER, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ad2c2a2d250..ab783b161c7 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  40,   5,  40,
-   50,   0,  55,  10, 116,   0, 116, 116,   5,  25,
-   30,   0,   5, 116,  10,  15,   5,   0,  25, 116,
-  116,  20, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 

[PATCH v19 22/40] c++: Implement __is_reference built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_reference.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_reference.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_REFERENCE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 113 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_reference.C  |  34 +++
 7 files changed, 104 insertions(+), 55 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_reference.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 98b1f004a68..5cdb59d174e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
+case CPTK_IS_REFERENCE:
+  inform (loc, "  %qT is not a reference", t1);
+  break;
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 11fd70b3964..e867d9c4c47 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
+DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 32199a1fe9a..5989b84727f 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -61,6 +61,7 @@ struct cp_trait {
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false
 "__is_pod", CPTK_IS_POD, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
+"__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 799fe2b792f..f0b4f96d4a9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 94, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 40,  5, 40,
-  40,  0, 25, 10, 96,  0, 96, 96,  5, 25,
-  30,  0,  5, 96, 10, 15,  5,  0, 25, 96,
-  96, 20, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
+   40,   0, 

[PATCH v19 19/40] libstdc++: Optimize is_member_function_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_function_pointer trait
by dispatching to the new __is_member_function_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_function_pointer): Use
__is_member_function_pointer built-in trait.
(is_member_function_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 16 
 1 file changed, 16 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index d7f89cf7c06..e1b10240dc2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -588,6 +588,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+  /// is_member_function_pointer
+  template
+struct is_member_function_pointer
+: public __bool_constant<__is_member_function_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_function_pointer_helper
 : public false_type { };
@@ -601,6 +608,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_function_pointer
 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   /// is_enum
   template
@@ -3222,9 +3230,17 @@ template 
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+template 
+  inline constexpr bool is_member_function_pointer_v =
+__is_member_function_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_function_pointer_v =
 is_member_function_pointer<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_enum_v = __is_enum(_Tp);
 template 
-- 
2.42.0



[PATCH v19 14/40] c++: Implement __is_scoped_enum built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scoped_enum.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scoped_enum.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCOPED_ENUM.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 161 +++---
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C |  67 +
 7 files changed, 160 insertions(+), 80 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scoped_enum.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d09252a56b6..1c0b2e0f178 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3781,6 +3781,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCOPED_ENUM:
+  inform (loc, "  %qT is not a scoped enum", t1);
+  break;
 case CPTK_IS_STD_LAYOUT:
   inform (loc, "  %qT is not an standard layout type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 6d6dff7a4c3..e0e3fe1d23f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -79,6 +79,7 @@ DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertib
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 90fcdc01de6..f3fd82ba549 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -59,6 +59,7 @@ struct cp_trait {
 "__is_pod", CPTK_IS_POD, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
 "__is_trivial", CPTK_IS_TRIVIAL, 1, false
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f22a6e93618..9c18165eb68 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
-   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
-  116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 

[PATCH v19 34/40] libstdc++: Optimize is_compound trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_compound trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_compound): Do not use __not_.
(is_compound_v): Use is_fundamental_v instead.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 88171e1a672..48d630a1478 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_compound
   template
 struct is_compound
-: public __not_>::type { };
+: public __bool_constant::value> { };
 
   /// is_member_pointer
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
@@ -3387,7 +3387,7 @@ template 
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-  inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+  inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
 template 
-- 
2.42.0



[PATCH v19 06/40] c++: Implement __is_volatile built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_volatile.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/cp-trait.gperf|  1 +
 gcc/cp/cp-trait.h| 38 +---
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_volatile.C   | 19 
 7 files changed, 51 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 567dd35fe0a..f031e022541 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,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 9e4e6d798a0..d786f47e60c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 47a5ec9ee6f..ea7abda6c75 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -63,6 +63,7 @@ struct cp_trait {
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
+"__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
 "__remove_cv", CPTK_REMOVE_CV, 1, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index c9005eee1ff..f462794d5db 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
   40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0, 96, 96,
+  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
   96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 46,
+  TOTAL_KEYWORDS = 47,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,27 +125,29 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
 #line 65 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 68 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 69 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 70 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 48 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
 #line 61 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
+#line 71 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 

[PATCH v19 37/40] c++: Implement __is_signed built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_signed.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_signed.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 211 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_signed.C |  47 +
 7 files changed, 165 insertions(+), 105 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_signed.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c28dad702c3..b161c9b2c9e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SIGNED:
+  inform (loc, "  %qT is not a signed type", t1);
+  break;
 case CPTK_IS_SCOPED_ENUM:
   inform (loc, "  %qT is not a scoped enum", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 0603b4a230f..b0faa4c8937 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ 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)
+DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 90d05bca5c1..de0ba162e7a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
 "__is_trivial", CPTK_IS_TRIVIAL, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 75ab2b5edfa..6d1078de2fe 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 129, duplicates = 0 */
+/* maximum key range = 119, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136,  20, 136,  45,  35,  40,
-   60,   0,  55,   0, 136,   0, 136, 136,  10,  15,
-   35,   0,  10, 136,  10,  15,   5,  15,   0, 136,
-  136,  20, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 

[PATCH v19 40/40] libstdc++: Optimize is_scalar trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_scalar trait by dispatching to
the new __is_scalar built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scalar): Use __is_scalar built-in
trait.
(is_scalar_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7e93923f44b..eb16a642575 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -775,11 +775,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_pointer;
 
   /// is_scalar
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+  template
+struct is_scalar
+: public __bool_constant<__is_scalar(_Tp)>
+{ };
+#else
   template
 struct is_scalar
 : public __or_, is_enum<_Tp>, is_pointer<_Tp>,
is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
 { };
+#endif
 
   /// is_compound
   template
@@ -3398,8 +3405,14 @@ template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+template 
+  inline constexpr bool is_scalar_v = __is_scalar(_Tp);
+#else
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
-- 
2.42.0



[PATCH v19 32/40] libstdc++: Optimize is_arithmetic trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_arithmetic trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_arithmetic): Use __is_arithmetic
built-in trait.
(is_arithmetic_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 3acd843f2f2..cc466e0f606 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -726,10 +726,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_arithmetic
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_arithmetic
+: public __bool_constant<__is_arithmetic(_Tp)>
+{ };
+#else
   template
 struct is_arithmetic
 : public __or_, is_floating_point<_Tp>>::type
 { };
+#endif
 
   /// is_fundamental
   template
@@ -3344,8 +3351,14 @@ template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+template 
+  inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+#else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
 
-- 
2.42.0



[PATCH v19 09/40] libstdc++: Optimize is_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_array trait by dispatching to
the new __is_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_array): Use __is_array built-in trait.
(is_array_v): Likewise.

Signed-off-by: Ken Matsui 
---
 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 c01f65df22b..4e8165e5af5 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -523,6 +523,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_array
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+  template
+struct is_array
+: public __bool_constant<__is_array(_Tp)>
+{ };
+#else
   template
 struct is_array
 : public false_type { };
@@ -534,6 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_array<_Tp[]>
 : public true_type { };
+#endif
 
   template
 struct __is_pointer_helper
@@ -3183,12 +3190,17 @@ template 
 template 
   inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+template 
+  inline constexpr bool is_array_v = __is_array(_Tp);
+#else
 template 
   inline constexpr bool is_array_v = false;
 template 
   inline constexpr bool is_array_v<_Tp[]> = true;
 template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
+#endif
 
 template 
   inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
-- 
2.42.0



[PATCH v19 33/40] libstdc++: Optimize is_fundamental trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_fundamental trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_fundamental_v): Use __is_arithmetic
built-in trait.
(is_fundamental): Likewise. Optimize the original implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index cc466e0f606..88171e1a672 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -739,11 +739,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_fundamental
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_fundamental
+: public __bool_constant<__is_arithmetic(_Tp)
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
+{ };
+#else
   template
 struct is_fundamental
-: public __or_, is_void<_Tp>,
-  is_null_pointer<_Tp>>::type
+: public __bool_constant::value
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
 { };
+#endif
 
   /// is_object
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
@@ -3354,13 +3364,15 @@ template 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
 template 
   inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+template 
+  inline constexpr bool is_fundamental_v
+= __is_arithmetic(_Tp) || is_void_v<_Tp> || is_null_pointer_v<_Tp>;
 #else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
-#endif
-
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
  && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
-- 
2.42.0



[PATCH v19 04/40] c++: Implement __is_const built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_const.

gcc/cp/ChangeLog:

* Make-lang.in: Update key positions for gperf, based on
automatically computed values.
* cp-trait.def: Define __is_const.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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 
---
 gcc/cp/Make-lang.in  |   2 +-
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 202 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_const.C  |  19 +++
 8 files changed, 135 insertions(+), 100 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C

diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index a67d1c3e9f3..7479e7dc00b 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -195,7 +195,7 @@ $(srcdir)/cp/cp-trait.h: $(srcdir)/cp/cp-trait.gperf
 else
 $(srcdir)/cp/cp-trait.h: | $(srcdir)/cp/cp-trait.gperf
 endif
-   gperf -o -C -E -k '8' -D -N 'find' -L C++ \
+   gperf -o -C -E -k '6,8' -D -N 'find' -L C++ \
$(srcdir)/cp/cp-trait.gperf --output-file 
$(srcdir)/cp/cp-trait.h
 
 # The cp-trait.gperf file itself is generated from
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 722fc334e6f..567dd35fe0a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,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 0e48e64b8dd..9e4e6d798a0 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 47e3c1af499..47a5ec9ee6f 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
+"__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
 "__is_convertible", CPTK_IS_CONVERTIBLE, 2, false
 "__is_empty", CPTK_IS_EMPTY, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 97ba8492d15..c9005eee1ff 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -1,5 +1,5 @@
 /* C++ code produced by gperf version 3.1 */
-/* Command-line: gperf -o -C -E -k 8 -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
+/* Command-line: gperf -o -C -E -k 6,8 -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
   && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 79, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86,  1, 86, 86,
-   0, 35, 86,  0, 86,  0, 86, 86, 10, 10,
-  50, 15, 55, 86, 30,  5, 15,  0, 86, 86,
-  86, 20, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 

[PATCH v19 20/40] c++: Implement __is_member_object_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_object_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_object_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_OBJECT_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_member_object_pointer.
* g++.dg/ext/is_member_object_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 +
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 62 ++-
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +
 .../g++.dg/ext/is_member_object_pointer.C | 30 +
 7 files changed, 74 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_object_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d0464dd4f6a..98b1f004a68 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3759,6 +3759,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
   inform (loc, "  %qT is not a member function pointer", t1);
   break;
+case CPTK_IS_MEMBER_OBJECT_POINTER:
+  inform (loc, "  %qT is not a member object pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 897b96630f2..11fd70b3964 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -73,6 +73,7 @@ DEFTRAIT_EXPR (IS_FINAL, "__is_final", 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)
+DEFTRAIT_EXPR (IS_MEMBER_OBJECT_POINTER, "__is_member_object_pointer", 1)
 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index b28efbab322..32199a1fe9a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -53,6 +53,7 @@ struct cp_trait {
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
+"__is_member_object_pointer", CPTK_IS_MEMBER_OBJECT_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index d3d4bdf9799..799fe2b792f 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 53,
+  TOTAL_KEYWORDS = 54,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,57 +125,57 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 75 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 76 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 77 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 79 "../../gcc/cp/cp-trait.gperf"
+#line 80 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
 #line 45 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   

[PATCH v19 30/40] libstdc++: Optimize is_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_pointer trait 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 
---
 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 4312f32a4e0..cd5ce45951f 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 __has_builtin(__is_pointer)
+  template
+struct __is_pointer : __truth_type<__is_pointer(_Tp)>
+{
+  enum { __value = __is_pointer(_Tp) };
+};
+#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 9c56d15c0b7..3acd843f2f2 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
@@ -3254,8 +3268,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 
-- 
2.42.0



[PATCH v19 35/40] c++: Implement __is_unsigned built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_unsigned.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unsigned.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNSIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 118 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_unsigned.C   |  47 +
 7 files changed, 120 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unsigned.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 3a7f968eae8..c28dad702c3 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_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
+case CPTK_IS_UNSIGNED:
+  inform (loc, "  %qT is not an unsigned type", t1);
+  break;
 case CPTK_IS_VOLATILE:
   inform (loc, "  %qT is not a volatile type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b2be7b7bbd7..0603b4a230f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -94,6 +94,7 @@ 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_UNSIGNED, "__is_unsigned", 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 9050c36f105..90d05bca5c1 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -74,6 +74,7 @@ struct cp_trait {
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
 "__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
+"__is_unsigned", CPTK_IS_UNSIGNED, 1, false
 "__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 31fd5075f2d..75ab2b5edfa 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 97, duplicates = 0 */
+/* maximum key range = 129, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
-5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
-   35,   0,  10, 104,  10,  15,   5,   0,  20, 104,
-  104,  20, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 

[PATCH v19 27/40] c++: Implement __remove_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 32 +++---
 gcc/cp/semantics.cc   |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++
 6 files changed, 78 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index fa79bc0c68c..2add97ae749 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -97,6 +97,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_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 771242a7f45..8fbd67788d5 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -77,6 +77,7 @@ struct cp_trait {
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
 "__remove_cv", CPTK_REMOVE_CV, 1, true
 "__remove_cvref", CPTK_REMOVE_CVREF, 1, true
+"__remove_pointer", CPTK_REMOVE_POINTER, 1, true
 "__remove_reference", CPTK_REMOVE_REFERENCE, 1, true
 "__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true
 "__underlying_type", CPTK_UNDERLYING_TYPE, 1, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index b6db58e93c9..ad2c2a2d250 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 56,
+  TOTAL_KEYWORDS = 57,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,7 +125,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 84 "../../gcc/cp/cp-trait.gperf"
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
@@ -137,17 +137,19 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
+#line 80 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
 #line 69 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 80 "../../gcc/cp/cp-trait.gperf"
+#line 81 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
 #line 45 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
 #line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false},
@@ -235,21 +237,21 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__is_final", CPTK_IS_FINAL, 1, false},
 #line 53 "../../gcc/cp/cp-trait.gperf"
   {"__is_function", CPTK_IS_FUNCTION, 1, false},
-#line 83 "../../gcc/cp/cp-trait.gperf"
+#line 84 "../../gcc/cp/cp-trait.gperf"
   {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false}
 };
 
   static const signed char lookup[] =
 {
   -1, -1, -1, -1, -1, -1, -1,  0, -1,  1,  2,  3, -1, -1,
-   4,  5, -1,  6,  7,  8, -1, -1,  9, 10, 11, 12, 13, 14,
-  15, -1, 16, 17, 18, 19, -1, 20, -1, 21, 22, -1, 23, -1,
-  24, 25, 26, 27, -1, 28, 29, 30, 31, -1, 32, -1, 33, 34,
-  -1, -1, 35, 36, 37, 38, -1, 39, 40, -1, -1, -1, 41, 42,
-  43, -1, -1, -1, -1, 44, 45, -1, 46, 47, 48, -1, -1, -1,
-  -1, 49, 50, -1, 51, -1, 52, -1, -1, -1, -1, 53, -1, -1,
-  54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, 55
+   4,  5,  6,  

[PATCH v19 16/40] c++: Implement __is_member_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_MEMBER_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_member_pointer.
* g++.dg/ext/is_member_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 153 ++-
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_member_pointer.C |  30 
 7 files changed, 120 insertions(+), 75 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 1c0b2e0f178..f0d3f89464c 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_POINTER:
+  inform (loc, "  %qT is not a member pointer", t1);
+  break;
 case CPTK_IS_NOTHROW_ASSIGNABLE:
   inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e0e3fe1d23f..26087da3bdf 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index f3fd82ba549..3775b11283d 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 9c18165eb68..dfd60cec6e6 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 111, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99,  0,  5, 50,
-  30,  0, 40, 15, 99,  0, 99, 99,  5, 10,
-  30,  0,  5, 99, 10, 50,  5,  0, 35, 99,
-  99,  5, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 

[PATCH v19 15/40] libstdc++: Optimize is_scoped_enum trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_scoped_enum trait
by dispatching to the new __is_scoped_enum built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scoped_enum): Use
__is_scoped_enum built-in trait.
(is_scoped_enum_v): Likewise.

Signed-off-by: Ken Matsui 
---
 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 d306073a797..7fd29d8d9f2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3633,6 +3633,12 @@ template
   /// True if the type is a scoped enumeration type.
   /// @since C++23
 
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+struct is_scoped_enum
+: bool_constant<__is_scoped_enum(_Tp)>
+{ };
+# else
   template
 struct is_scoped_enum
 : false_type
@@ -3644,11 +3650,17 @@ template
 struct is_scoped_enum<_Tp>
 : bool_constant
 { };
+# endif
 
   /// @ingroup variable_templates
   /// @since C++23
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
+# else
   template
 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+# endif
 #endif
 
 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && 
ref_{converts,constructs}_from_temp
-- 
2.42.0



[PATCH v19 24/40] c++: Implement __is_function built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_function.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_function.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_FUNCTION.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 143 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_function.C   |  58 +
 7 files changed, 143 insertions(+), 70 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_function.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5cdb59d174e..99a7e7247ce 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3750,6 +3750,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_FINAL:
   inform (loc, "  %qT is not a final class", t1);
   break;
+case CPTK_IS_FUNCTION:
+  inform (loc, "  %qT is not a function", t1);
+  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 e867d9c4c47..fa79bc0c68c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -70,6 +70,7 @@ DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 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_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-trait.gperf b/gcc/cp/cp-trait.gperf
index 5989b84727f..771242a7f45 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -50,6 +50,7 @@ struct cp_trait {
 "__is_empty", CPTK_IS_EMPTY, 1, false
 "__is_enum", CPTK_IS_ENUM, 1, false
 "__is_final", CPTK_IS_FINAL, 1, false
+"__is_function", CPTK_IS_FUNCTION, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f0b4f96d4a9..b6db58e93c9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 94, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
-   40,   0,  60,  10, 101,   0, 101, 101,   5,  25,
-   30,   0,   5, 101,  10,  15,   5,   0,  25, 101,
-  101,  20, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 

[PATCH v19 13/40] libstdc++: Optimize is_bounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_bounded_array trait by
dispatching to the new __is_bounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_bounded_array_v): Use __is_bounded_array
built-in trait.

Signed-off-by: Ken Matsui 
---
 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 cb3d9e238fa..d306073a797 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3532,11 +3532,16 @@ template
   /// True for a type that is an array of known bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
+  template
+inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
+# else
   template
 inline constexpr bool is_bounded_array_v = false;
 
   template
 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
+# endif
 
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
-- 
2.42.0



[PATCH v19 26/40] libstdc++: Optimize is_object trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_object trait by dispatching to
the new __is_function and __is_reference built-in traits.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use __is_function and
__is_reference built-in traits.
(is_object_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index bd57488824b..674d398c075 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_object
+: public __bool_constant::value)>
+{ };
+#else
   template
 struct is_object
 : public __not_<__or_, is_reference<_Tp>,
   is_void<_Tp>>>::type
 { };
+#endif
 
   template
 struct is_member_pointer;
@@ -3305,8 +3314,17 @@ template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_object_v
+= !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
+#else
 template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v19 18/40] c++: Implement __is_member_function_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_function_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_function_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_FUNCTION_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_member_function_pointer.
* g++.dg/ext/is_member_function_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 176 +-
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 .../g++.dg/ext/is_member_function_pointer.C   |  31 +++
 7 files changed, 131 insertions(+), 88 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_function_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f0d3f89464c..d0464dd4f6a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
+  inform (loc, "  %qT is not a member function pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 26087da3bdf..897b96630f2 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 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)
 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 3775b11283d..b28efbab322 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index dfd60cec6e6..d3d4bdf9799 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 111, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118,  20, 118,   0,  55,  50,
-   40,   0,  40,  20, 118,   0, 118, 118,   5,   5,
-   30,   0,   5, 118,  10,  50,   5,   0,   5, 118,
-  118,   5, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 

[PATCH v19 31/40] c++: Implement __is_arithmetic built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 184 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_arithmetic.C |  33 
 7 files changed, 138 insertions(+), 91 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9d627fa782..3a7f968eae8 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
 case CPTK_IS_ARRAY:
   inform (loc, "  %qT is not an array", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index c60724e869e..b2be7b7bbd7 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 5d40e04f91c..9050c36f105 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_arithmetic", CPTK_IS_ARITHMETIC, 1, false
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ab783b161c7..31fd5075f2d 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 97, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99, 40, 45, 40,
-   5,  0, 55, 10, 99,  0, 99, 99, 10, 25,
-  30,  0, 10, 99, 10, 15,  5,  0, 20, 99,
-  99, 10, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
+5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
+   35,   

[PATCH v19 17/40] libstdc++: Optimize is_member_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_pointer trait
by dispatching to the new __is_member_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_pointer): Use __is_member_pointer
built-in trait.
(is_member_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7fd29d8d9f2..d7f89cf7c06 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -716,6 +716,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_compound
 : public __not_>::type { };
 
+  /// is_member_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+  template
+struct is_member_pointer
+: public __bool_constant<__is_member_pointer(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template
 struct __is_member_pointer_helper
@@ -726,11 +733,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
   /// @endcond
 
-  /// is_member_pointer
   template
 struct is_member_pointer
 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   template
 struct is_same;
@@ -3242,8 +3249,14 @@ template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+template 
+  inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
 template 
-- 
2.42.0



[PATCH v19 23/40] libstdc++: Optimize is_reference trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_reference trait by dispatching
to the new __is_reference built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in
trait.
(is_reference_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 792213ebfe8..36ad9814047 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -682,6 +682,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Composite type categories.
 
   /// is_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_reference
+: public __bool_constant<__is_reference(_Tp)>
+{ };
+#else
   template
 struct is_reference
 : public false_type
@@ -696,6 +702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_reference<_Tp&&>
 : public true_type
 { };
+#endif
 
   /// is_arithmetic
   template
@@ -3264,12 +3271,19 @@ template 
   inline constexpr bool is_class_v = __is_class(_Tp);
 template 
   inline constexpr bool is_function_v = is_function<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_reference_v = __is_reference(_Tp);
+#else
 template 
   inline constexpr bool is_reference_v = false;
 template 
   inline constexpr bool is_reference_v<_Tp&> = true;
 template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
+#endif
+
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v19 12/40] c++: Implement __is_bounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_bounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_bounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_BOUNDED_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_bounded_array.
* g++.dg/ext/is_bounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|  3 +
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/cp-trait.gperf   |  1 +
 gcc/cp/cp-trait.h   | 86 +++--
 gcc/cp/semantics.cc |  4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 +
 gcc/testsuite/g++.dg/ext/is_bounded_array.C | 38 +
 7 files changed, 94 insertions(+), 42 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_bounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 751ac61b25a..d09252a56b6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
+case CPTK_IS_BOUNDED_ARRAY:
+  inform (loc, "  %qT is not a bounded array", t1);
+  break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 4e02f68e4a9..6d6dff7a4c3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index a894fc8c74c..90fcdc01de6 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
+"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false
 "__is_class", CPTK_IS_CLASS, 1, false
 "__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 47060ffbbef..f22a6e93618 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
   116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 49,
+  TOTAL_KEYWORDS = 50,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,54 +125,56 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 50 "../../gcc/cp/cp-trait.gperf"
+#line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 72 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
-#line 49 "../../gcc/cp/cp-trait.gperf"
+#line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 62 "../../gcc/cp/cp-trait.gperf"
+#line 63 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", 

[PATCH v19 07/40] libstdc++: Optimize is_volatile trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_volatile trait 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 
---
 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 686e38e47c3..c01f65df22b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -800,6 +800,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 { };
@@ -807,6 +813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
@@ -3236,10 +3243,15 @@ template 
   inline constexpr bool is_const_v = true;
 #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);
-- 
2.42.0



[PATCH v19 08/40] c++: Implement __is_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_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_array.
* g++.dg/ext/is_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 148 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_array.C  |  28 +
 7 files changed, 116 insertions(+), 72 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f031e022541..5e30a4a907a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARRAY:
+  inform (loc, "  %qT is not an array", t1);
+  break;
 case CPTK_IS_ASSIGNABLE:
   inform (loc, "  %qT is not assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index d786f47e60c..99bc05360b9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index ea7abda6c75..fb162cac164 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f462794d5db..526e63dec42 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
-  40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
-  96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
+   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
+   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+ 

[PATCH v19 21/40] libstdc++: Optimize is_member_object_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_object_pointer trait
by dispatching to the new __is_member_object_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_object_pointer): Use
__is_member_object_pointer built-in trait.
(is_member_object_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index e1b10240dc2..792213ebfe8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -574,6 +574,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_rvalue_reference<_Tp&&>
 : public true_type { };
 
+  /// is_member_object_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+  template
+struct is_member_object_pointer
+: public __bool_constant<__is_member_object_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_object_pointer_helper
 : public false_type { };
@@ -582,11 +589,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __is_member_object_pointer_helper<_Tp _Cp::*>
 : public __not_>::type { };
 
-  /// is_member_object_pointer
+
   template
 struct is_member_object_pointer
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
   /// is_member_function_pointer
@@ -3227,9 +3235,16 @@ template 
   inline constexpr bool is_rvalue_reference_v = false;
 template 
   inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+template 
+  inline constexpr bool is_member_object_pointer_v =
+__is_member_object_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
 template 
-- 
2.42.0



[PATCH v19 11/40] libstdc++: Optimize is_unbounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unbounded_array trait by
dispatching to the new __is_unbounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unbounded_array_v): Use
__is_unbounded_array built-in trait.

Signed-off-by: Ken Matsui 
---
 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 4e8165e5af5..cb3d9e238fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3541,11 +3541,16 @@ template
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
+  template
+inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
+# else
   template
 inline constexpr bool is_unbounded_array_v = false;
 
   template
 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+# endif
 
   /// True for a type that is an array of known bound.
   /// @since C++20
-- 
2.42.0



[PATCH v19 25/40] libstdc++: Optimize is_function trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_function trait by dispatching
to the new __is_function built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_function): Use __is_function built-in
trait.
(is_function_v): Likewise. Optimize its implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 36ad9814047..bd57488824b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -637,6 +637,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_function
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+  template
+struct is_function
+: public __bool_constant<__is_function(_Tp)>
+{ };
+#else
   template
 struct is_function
 : public __bool_constant::value> { };
@@ -648,6 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_function<_Tp&&>
 : public false_type { };
+#endif
 
 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
   /// is_null_pointer (LWG 2247).
@@ -3269,8 +3276,18 @@ template 
   inline constexpr bool is_union_v = __is_union(_Tp);
 template 
   inline constexpr bool is_class_v = __is_class(_Tp);
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
 template 
-  inline constexpr bool is_function_v = is_function<_Tp>::value;
+  inline constexpr bool is_function_v = __is_function(_Tp);
+#else
+template 
+  inline constexpr bool is_function_v = !is_const_v;
+template 
+  inline constexpr bool is_function_v<_Tp&> = false;
+template 
+  inline constexpr bool is_function_v<_Tp&&> = false;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
 template 
-- 
2.42.0



[PATCH v19 05/40] libstdc++: Optimize is_const trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_const trait 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 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 677cd934b94..686e38e47c3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,6 +784,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 { };
@@ -791,6 +797,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_const<_Tp const>
 : public true_type { };
+#endif
 
   /// is_volatile
   template
@@ -3218,10 +3225,17 @@ template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+
+#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
+
 template 
   inline constexpr bool is_volatile_v = false;
 template 
-- 
2.42.0



[PATCH v19 39/40] c++: Implement __is_scalar built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scalar.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scalar.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCALAR.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 186 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_scalar.C |  31 
 7 files changed, 137 insertions(+), 92 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scalar.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b161c9b2c9e..78f100d2745 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCALAR:
+  inform (loc, "  %qT is not a scalar type", t1);
+  break;
 case CPTK_IS_SIGNED:
   inform (loc, "  %qT is not a signed type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b0faa4c8937..08a2780c929 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ 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)
+DEFTRAIT_EXPR (IS_SCALAR, "__is_scalar", 1)
 DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index de0ba162e7a..ef51c713c58 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scalar", CPTK_IS_SCALAR, 1, false
 "__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 6d1078de2fe..8c68af420f9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -78,10 +78,10 @@ cp_trait_lookup::hash (const char *str, size_t len)
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-  126, 126, 126, 126, 126,  20, 126,  40,  45,  50,
-   55,   0,   5,  15, 126,   0, 126, 126,  35,  10,
-   35,   0,  10, 126,  30,   5,   5,  16,  30, 126,
-  126,  10, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126,  40, 126,  25,  21,  50,
+0,   0,  30,  10, 126,   0, 126, 126,  25,   5,
+   50,   0,  61, 126,  10,  10,   5,   0,  15, 126,
+  126,   5, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 61,
+  TOTAL_KEYWORDS = 62,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,141 +125,143 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 89 "../../gcc/cp/cp-trait.gperf"
+#line 90 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 52 "../../gcc/cp/cp-trait.gperf"
+  {"__is_enum", CPTK_IS_ENUM, 1, false},
+#line 78 "../../gcc/cp/cp-trait.gperf"
+  {"__is_union", CPTK_IS_UNION, 1, false},
 #line 83 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 84 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+#line 89 "../../gcc/cp/cp-trait.gperf"
+  {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false},
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"

[PATCH v19 38/40] libstdc++: Optimize is_signed trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_signed trait by dispatching to
the new __is_signed built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_signed): Use __is_signed built-in trait.
(is_signed_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index f7d3815f332..7e93923f44b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -982,6 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __bool_constant<__is_abstract(_Tp)>
 { };
 
+  /// is_signed
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+  template
+struct is_signed
+: public __bool_constant<__is_signed(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template::value>
@@ -994,11 +1001,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
   /// @endcond
 
-  /// is_signed
   template
 struct is_signed
 : public __is_signed_helper<_Tp>::type
 { };
+#endif
 
   /// is_unsigned
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
@@ -3445,8 +3452,13 @@ template 
 template 
   inline constexpr bool is_final_v = __is_final(_Tp);
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+template 
+  inline constexpr bool is_signed_v = __is_signed(_Tp);
+#else
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
 template 
-- 
2.42.0



[PATCH v19 36/40] libstdc++: Optimize is_unsigned trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unsigned trait by dispatching
to the new __is_unsigned built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unsigned): Use __is_unsigned built-in
trait.
(is_unsigned_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 48d630a1478..f7d3815f332 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1001,10 +1001,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_unsigned
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+  template
+struct is_unsigned
+: public __bool_constant<__is_unsigned(_Tp)>
+{ };
+#else
   template
 struct is_unsigned
 : public __and_, __not_>>::type
 { };
+#endif
 
   /// @cond undocumented
   template
@@ -3440,8 +3447,14 @@ template 
 
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+template 
+  inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+#else
 template 
   inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+#endif
 
 template 
   inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
-- 
2.42.0



[PATCH v19 28/40] libstdc++: Optimize remove_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the remove_pointer trait by
dispatching to the new remove_pointer built-in trait.

libstdc++-v3/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 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 674d398c075..9c56d15c0b7 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2105,6 +2105,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
+  template
+struct remove_pointer
+{ using type = __remove_pointer(_Tp); };
+#else
   template
 struct __remove_pointer_helper
 { using type = _Tp; };
@@ -2113,11 +2119,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __remove_pointer_helper<_Tp, _Up*>
 { using type = _Up; };
 
-  /// remove_pointer
   template
 struct remove_pointer
 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
 { };
+#endif
 
   template
 struct __add_pointer_helper
-- 
2.42.0



[PATCH v19 03/40] c++: Accept the use of built-in trait identifiers

2023-10-13 Thread Ken Matsui
This patch accepts the use of built-in trait identifiers when they are
actually not used as traits.  Specifically, we check if the subsequent token
is '(' for ordinary built-in traits or is '<' only for the special
__type_pack_element built-in trait.  If those identifiers are used
differently, the parser treats them as normal identifiers.  This allows
us to accept code like: struct __is_pointer {};.

gcc/cp/ChangeLog:

* parser.cc (cp_lexer_lookup_trait): Rename to ...
(cp_lexer_peek_trait): ... this.  Handle a subsequent token for
the corresponding built-in trait.
(cp_lexer_lookup_trait_expr): Rename to ...
(cp_lexer_peek_trait_expr): ... this.
(cp_lexer_lookup_trait_type): Rename to ...
(cp_lexer_peek_trait_type): ... this.
(cp_lexer_next_token_is_decl_specifier_keyword): Call
cp_lexer_peek_trait_type.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_primary_expression): Call cp_lexer_peek_trait_expr.

Signed-off-by: Ken Matsui 
---
 gcc/cp/parser.cc | 48 ++--
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 39952893ffa..59015eac596 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -247,12 +247,12 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static const cp_trait *cp_lexer_lookup_trait
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_expr
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_type
-  (const cp_token *);
+static const cp_trait *cp_lexer_peek_trait
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_expr
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_type
+  (cp_lexer *lexer, const cp_token *);
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -1183,21 +1183,33 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
 }
 }
 
-/* Look ups the corresponding built-in trait if a given token is
+/* Peeks the corresponding built-in trait if a given token is
a built-in trait.  Otherwise, returns nullptr.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait (const cp_token *token)
+cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
 {
-  tree id = token->u.value;
+  tree id = token1->u.value;
 
-  if (token->type == CPP_NAME
+  if (token1->type == CPP_NAME
   && TREE_CODE (id) == IDENTIFIER_NODE
   && IDENTIFIER_TRAIT_P (id))
 {
   const char *id_str = IDENTIFIER_POINTER (id);
   const int id_len = IDENTIFIER_LENGTH (id);
-  return cp_trait_lookup::find (id_str, id_len);
+  const cp_trait *trait = cp_trait_lookup::find (id_str, id_len);
+
+  /* Check if the subsequent token is a `<' token to
+ __type_pack_element or is a `(' token to everything else.  */
+  const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
+  if (trait->kind == CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_LESS)
+   return nullptr;
+  if (trait->kind != CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_OPEN_PAREN)
+   return nullptr;
+
+  return trait;
 }
   return nullptr;
 }
@@ -1206,9 +1218,9 @@ cp_lexer_lookup_trait (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_expr (const cp_token *token)
+cp_lexer_peek_trait_expr (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && !trait->type)
 return trait;
 
@@ -1219,9 +1231,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_type (const cp_token *token)
+cp_lexer_peek_trait_type (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && trait->type)
 return trait;
 
@@ -1236,7 +1248,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
*lexer)
   cp_token *token;
 
   token = cp_lexer_peek_token (lexer);
-  if (cp_lexer_lookup_trait_type (token))
+  if (cp_lexer_peek_trait_type (lexer, token))
 return true;
   return cp_keyword_starts_decl_specifier_p (token->keyword);
 }
@@ -6108,7 +6120,7 @@ cp_parser_primary_expression (cp_parser *parser,
 keyword.  */
 case CPP_NAME:
   {
-   const cp_trait* trait = cp_lexer_lookup_trait_expr (token);
+   const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer, token);
if (trait)
  return cp_parser_trait (parser, trait);
   }
@@ -20117,7 +20129,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 }
 
   /* If token is a type-yielding built-in traits, 

[PATCH v19 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-13 Thread Ken Matsui
Since RID_MAX soon reaches 255 and all built-in traits are used approximately
once in a C++ translation unit, this patch removes all RID values for built-in
traits and uses gperf to look up the specific trait.  Rather than holding
traits as keywords, we set all trait identifiers as cik_trait, which is a new
cp_identifier_kind.  As cik_reserved_for_udlit was unused and
cp_identifier_kind is 3 bits, we replaced the unused field with the new
cik_trait.  Also, the later patch handles a subsequent token to the built-in
identifier so that we accept the use of non-function-like built-in trait
identifiers.

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Remove all mappings of
built-in traits.
* c-common.h (enum rid): Remove all RID values for built-in traits.

gcc/cp/ChangeLog:

* Make-lang.in: Add targets to generate cp-trait.gperf and
cp-trait.h.
* cp-objcp-common.cc (names_builtin_p): Remove all RID value
cases for built-in traits.  Check for built-in traits via
the new cik_trait identifier.
* cp-tree.h (cik_reserved_for_udlit): Rename to ...
(cik_trait): ... this.
(IDENTIFIER_ANY_OP_P): Exclude cik_trait.
(IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
* lex.cc (init_cp_traits): New function to set cik_trait for all
built-in trait identifiers.
(cxx_init): Call init_cp_traits function.
* parser.cc (cp_lexer_lookup_trait): New function to look up a
built-in trait from a token by gperf.
(cp_lexer_lookup_trait_expr): Likewise, look up an
expression-yielding built-in trait.
(cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
built-in trait.
(cp_keyword_starts_decl_specifier_p): Remove all RID value cases
for built-in traits.
(cp_lexer_next_token_is_decl_specifier_keyword): Handle
type-yielding built-in traits.
(cp_parser_primary_expression): Remove all RID value cases for
built-in traits.  Handle expression-yielding built-in traits.
(cp_parser_trait): Handle cp_trait instead of enum rid.
(cp_parser_simple_type_specifier): Remove all RID value cases
for built-in traits.  Handle type-yielding built-in traits.
* cp-trait-head.in: New file.
* cp-trait.gperf: New file.
* cp-trait.h: New file.

Co-authored-by: Patrick Palka 
Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |   7 --
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 +
 gcc/cp/cp-trait.gperf |  74 
 gcc/cp/cp-trait.h | 247 ++
 gcc/cp/cp-tree.h  |  14 ++-
 gcc/cp/lex.cc |  19 +++
 gcc/cp/parser.cc  | 132 
 10 files changed, 492 insertions(+), 70 deletions(-)
 create mode 100644 gcc/cp/cp-trait-head.in
 create mode 100644 gcc/cp/cp-trait.gperf
 create mode 100644 gcc/cp/cp-trait.h

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index f044db5b797..21fd333ef57 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
   { "wchar_t", RID_WCHAR,  D_CXXONLY },
   { "while",   RID_WHILE,  0 },
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  { NAME,  RID_##CODE, D_CXXONLY },
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-  /* An alias for __is_same.  */
-  { "__is_same_as",RID_IS_SAME,D_CXXONLY },
-
   /* C++ transactional memory.  */
   { "synchronized",RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1fdba7ef3ea..051a442e0f4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -168,11 +168,6 @@ enum rid
   RID_BUILTIN_LAUNDER,
   RID_BUILTIN_BIT_CAST,
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  RID_##CODE,
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-
   /* C++11 */
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
 
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 2727fb7f8cc..a67d1c3e9f3 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -34,6 +34,8 @@
 # - the compiler proper (eg: cc1plus)
 # - define the names for selecting the language in LANGUAGES.
 
+AWK = @AWK@
+
 # Actual names to use when installing a native compiler.
 CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
 GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
@@ -186,6 +188,30 @@ endif
 # This is the file that depends on the generated header file.
 cp/name-lookup.o: $(srcdir)/cp/std-name-hint.h
 
+# We always need the dependency on the .gperf file
+# because it itself is generated.
+ifeq 

[PATCH v19 01/40] c++: Sort built-in traits alphabetically

2023-10-13 Thread Ken Matsui
This patch sorts built-in traits alphabetically for better code
readability.

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Sort built-in traits
alphabetically.
* cp-trait.def: Likewise.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(finish_trait_type): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc | 68 -
 gcc/cp/cp-trait.def  | 10 +--
 gcc/cp/semantics.cc  | 94 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +-
 4 files changed, 121 insertions(+), 121 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9e4e7043cd..722fc334e6f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
   inform (loc, "  %qT is not trivially destructible", t1);
   break;
+case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+  inform (loc, "  %qT does not have unique object representations", t1);
+  break;
 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
   inform (loc, "  %qT does not have a virtual destructor", t1);
   break;
 case CPTK_IS_ABSTRACT:
   inform (loc, "  %qT is not an abstract class", t1);
   break;
+case CPTK_IS_AGGREGATE:
+  inform (loc, "  %qT is not an aggregate", t1);
+  break;
+case CPTK_IS_ASSIGNABLE:
+  inform (loc, "  %qT is not assignable from %qT", t1, t2);
+  break;
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONSTRUCTIBLE:
+  if (!t2)
+inform (loc, "  %qT is not default constructible", t1);
+  else
+inform (loc, "  %qT is not constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_CONVERTIBLE:
+  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_EMPTY:
   inform (loc, "  %qT is not an empty class", t1);
   break;
@@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_NOTHROW_ASSIGNABLE:
+  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+  if (!t2)
+   inform (loc, "  %qT is not nothrow default constructible", t1);
+  else
+   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   inform (loc, "  %qT is not pointer-interconvertible base of %qT",
  t1, t2);
@@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIAL:
   inform (loc, "  %qT is not a trivial type", t1);
   break;
-case CPTK_IS_UNION:
-  inform (loc, "  %qT is not a union", t1);
-  break;
-case CPTK_IS_AGGREGATE:
-  inform (loc, "  %qT is not an aggregate", t1);
-  break;
-case CPTK_IS_TRIVIALLY_COPYABLE:
-  inform (loc, "  %qT is not trivially copyable", t1);
-  break;
-case CPTK_IS_ASSIGNABLE:
-  inform (loc, "  %qT is not assignable from %qT", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
   inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
   break;
-case CPTK_IS_NOTHROW_ASSIGNABLE:
-  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
-  break;
-case CPTK_IS_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not default constructible", t1);
-  else
-   inform (loc, "  %qT is not constructible from %qE", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
   if (!t2)
inform (loc, "  %qT is not trivially default constructible", t1);
   else
inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
   break;
-case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not nothrow default constructible", t1);
-  else
-   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
-  break;
-case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
-  inform (loc, "  %qT does not have unique object representations", t1);
-  break;
-case CPTK_IS_CONVERTIBLE:
-  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+case CPTK_IS_TRIVIALLY_COPYABLE:
+  inform (loc, "  %qT is not trivially copyable", t1);
   break;
-case CPTK_IS_NOTHROW_CONVERTIBLE:
-   

[PATCH v19 00/40] Optimize type traits performance

2023-10-13 Thread Ken Matsui
This patch series optimizes type traits performance by implementing
built-in type traits and using them in libstdc++.

Changes in v19:

* Fixed a typo.
* Rebased on top of trunk.
* Improved clarity of the commit message.

Changes in v18:

* Removed all RID values for built-in traits and used cik_trait
instead.
* Improved to handle the use of non-function-like built-in trait
identifiers.
* Reverted all changes to conflicted identifiers with new built-ins
in the existing code base.

Changes in v17:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in.
* Made ridpointers for RID_TRAIT_EXPR and RID_TRAIT_TYPE empty.

Changes in v16:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in and gperf struct.
* Supply -k option to gperf to support older versions than 2.8.

Changes in v15:

* Rebased on top of trunk.
* Use gperf to look up traits instead of enum rid.

Changes in v14:

* Added padding calculation to the commit message.

Changes in v13:

* Fixed ambiguous commit message and comment.

Changes in v12:

* Evaluated all paddings affected by the enum rid change.

Changes in v11:

* Merged all patches into one patch series.
* Rebased on top of trunk.
* Unified commit message style.
* Used _GLIBCXX_USE_BUILTIN_TRAIT.

Ken Matsui (40):
  c++: Sort built-in traits alphabetically
  c-family, c++: Look up built-in traits through gperf
  c++: Accept the use of built-in trait identifiers
  c++: Implement __is_const built-in trait
  libstdc++: Optimize is_const trait performance
  c++: Implement __is_volatile built-in trait
  libstdc++: Optimize is_volatile trait performance
  c++: Implement __is_array built-in trait
  libstdc++: Optimize is_array trait performance
  c++: Implement __is_unbounded_array built-in trait
  libstdc++: Optimize is_unbounded_array trait performance
  c++: Implement __is_bounded_array built-in trait
  libstdc++: Optimize is_bounded_array trait performance
  c++: Implement __is_scoped_enum built-in trait
  libstdc++: Optimize is_scoped_enum trait performance
  c++: Implement __is_member_pointer built-in trait
  libstdc++: Optimize is_member_pointer trait performance
  c++: Implement __is_member_function_pointer built-in trait
  libstdc++: Optimize is_member_function_pointer trait performance
  c++: Implement __is_member_object_pointer built-in trait
  libstdc++: Optimize is_member_object_pointer trait performance
  c++: Implement __is_reference built-in trait
  libstdc++: Optimize is_reference trait performance
  c++: Implement __is_function built-in trait
  libstdc++: Optimize is_function trait performance
  libstdc++: Optimize is_object trait performance
  c++: Implement __remove_pointer built-in trait
  libstdc++: Optimize remove_pointer trait performance
  c++: Implement __is_pointer built-in trait
  libstdc++: Optimize is_pointer trait performance
  c++: Implement __is_arithmetic built-in trait
  libstdc++: Optimize is_arithmetic trait performance
  libstdc++: Optimize is_fundamental trait performance
  libstdc++: Optimize is_compound trait performance
  c++: Implement __is_unsigned built-in trait
  libstdc++: Optimize is_unsigned trait performance
  c++: Implement __is_signed built-in trait
  libstdc++: Optimize is_signed trait performance
  c++: Implement __is_scalar built-in trait
  libstdc++: Optimize is_scalar trait performance

 gcc/c-family/c-common.cc  |   7 -
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 ++
 gcc/cp/constraint.cc  | 112 +--
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 ++
 gcc/cp/cp-trait.def   |  27 +-
 gcc/cp/cp-trait.gperf |  91 ++
 gcc/cp/cp-trait.h | 285 ++
 gcc/cp/cp-tree.h  |  14 +-
 gcc/cp/lex.cc |  19 ++
 gcc/cp/parser.cc  | 144 ++---
 gcc/cp/semantics.cc   | 157 +++---
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  | 117 +--
 gcc/testsuite/g++.dg/ext/is_arithmetic.C  |  33 ++
 gcc/testsuite/g++.dg/ext/is_array.C   |  28 ++
 gcc/testsuite/g++.dg/ext/is_bounded_array.C   |  38 +++
 gcc/testsuite/g++.dg/ext/is_const.C   |  19 ++
 gcc/testsuite/g++.dg/ext/is_function.C|  58 
 .../g++.dg/ext/is_member_function_pointer.C   |  31 ++
 .../g++.dg/ext/is_member_object_pointer.C |  30 ++
 gcc/testsuite/g++.dg/ext/is_member_pointer.C  |  30 ++
 gcc/testsuite/g++.dg/ext/is_pointer.C |  51 
 gcc/testsuite/g++.dg/ext/is_reference.C   |  34 

[PATCH] c++: fix truncated diagnostic in C++23 [PR111272]

2023-10-13 Thread Marek Polacek
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
In C++23, since P2448, a constexpr function F that calls a non-constexpr
function N is OK as long as we don't actually call F in a constexpr
context.  So instead of giving an error in maybe_save_constexpr_fundef,
we only give an error when evaluating the call.  Unfortunately, as shown
in this PR, the diagnostic can be truncated:

z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function 
because:
   10 |   constexpr Jam() { ft(); }
  | ^~~

...because what?  With this patch, we say:

z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function 
because:
   10 |   constexpr Jam() { ft(); }
  | ^~~
z.C:10:23: error: call to non-'constexpr' function 'int Jam::ft()'
   10 |   constexpr Jam() { ft(); }
  | ~~^~
z.C:8:7: note: 'int Jam::ft()' declared here
8 |   int ft() { return 42; }
  |   ^~

Like maybe_save_constexpr_fundef, explain_invalid_constexpr_fn should
also check the body of a constructor, not just the mem-initializer.

PR c++/111272

gcc/cp/ChangeLog:

* constexpr.cc (explain_invalid_constexpr_fn): Also check the body of
a constructor in C++14 and up.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-diag1.C: New test.
---
 gcc/cp/constexpr.cc  | 10 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C | 21 
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 0f948db7c2d..dde4fec4a44 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1098,7 +1098,15 @@ explain_invalid_constexpr_fn (tree fun)
  body = massage_constexpr_body (fun, body);
  require_potential_rvalue_constant_expression (body);
  if (DECL_CONSTRUCTOR_P (fun))
-   cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
+   {
+ cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
+ if (cxx_dialect > cxx11)
+   {
+ /* Also check the body, not just the ctor-initializer.  */
+ body = DECL_SAVED_TREE (fun);
+ require_potential_rvalue_constant_expression (body);
+   }
+   }
}
 }
 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C
new file mode 100644
index 000..0e2909e83ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C
@@ -0,0 +1,21 @@
+// PR c++/111272
+// { dg-do compile { target c++14 } }
+// { dg-options "-Werror=invalid-constexpr" }
+// { dg-prune-output "some warnings being treated as errors" }
+
+struct Jam
+{
+  // constexpr  // n.b.
+  int ft() { return 42; } // { dg-message "declared here" }
+
+  constexpr Jam() { ft(); } // { dg-error "call to non-.constexpr. function" }
+// { dg-message "declared here" "" { target c++20_down } .-1 }
+};
+
+constexpr bool test()
+{
+  Jam j; // { dg-error "called in a constant expression" }
+  return true;
+}
+
+static_assert(test(), ""); // { dg-error "non-constant condition" }

base-commit: d78fef5371759849944966dec65d9e987efba509
-- 
2.41.0



Re: Continued (Non)mutlib and stub header issue (was Re: [PATCH v2] RISC-V: Use stdint-gcc.h in rvv testsuite)

2023-10-13 Thread Kito Cheng
> When looking around, I stumbled upon commit
>  d0bbecb1c41 "RISC-V: Add riscv_vector.h wrapper in testsuite to
> prevent pull in stdint.h from C library"
>work
> Which seems like a step in a right direction, but how does one ensure
> that the wrapper riscv_vector.h (containing stdint-gcc.h) is included by
> test vs. the default riscv_vector.h (which is more user facing and thus
> needs to include the system stdint.h)

IIRC it rely on #include "" vs #include <>, the former will
search the same folder first, then the header search path,
so...made a dummy one, and put into test folder, then it will use our
own version now :P

but I guess maybe the right way (or simpler way) is just adding an
extra header search path to CFLAG and making a dummy stdint.h as well?

>
> P.S. I couldn't find the posting for above commit on gcc-patches ?

Here is the mail:
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603140.html

>
> Thx,
> -Vineet


[PATCH v18 40/40] libstdc++: Optimize is_scalar trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_scalar trait by dispatching to
the new __is_scalar built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scalar): Use __is_scalar built-in
trait.
(is_scalar_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7e93923f44b..eb16a642575 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -775,11 +775,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_pointer;
 
   /// is_scalar
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+  template
+struct is_scalar
+: public __bool_constant<__is_scalar(_Tp)>
+{ };
+#else
   template
 struct is_scalar
 : public __or_, is_enum<_Tp>, is_pointer<_Tp>,
is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
 { };
+#endif
 
   /// is_compound
   template
@@ -3398,8 +3405,14 @@ template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+template 
+  inline constexpr bool is_scalar_v = __is_scalar(_Tp);
+#else
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
-- 
2.42.0



[PATCH v18 39/40] c++: Implement __is_scalar built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scalar.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scalar.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCALAR.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 186 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_scalar.C |  31 
 7 files changed, 137 insertions(+), 92 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scalar.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b161c9b2c9e..78f100d2745 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCALAR:
+  inform (loc, "  %qT is not a scalar type", t1);
+  break;
 case CPTK_IS_SIGNED:
   inform (loc, "  %qT is not a signed type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b0faa4c8937..08a2780c929 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ 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)
+DEFTRAIT_EXPR (IS_SCALAR, "__is_scalar", 1)
 DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index de0ba162e7a..ef51c713c58 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scalar", CPTK_IS_SCALAR, 1, false
 "__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 6d1078de2fe..8c68af420f9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -78,10 +78,10 @@ cp_trait_lookup::hash (const char *str, size_t len)
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-  126, 126, 126, 126, 126,  20, 126,  40,  45,  50,
-   55,   0,   5,  15, 126,   0, 126, 126,  35,  10,
-   35,   0,  10, 126,  30,   5,   5,  16,  30, 126,
-  126,  10, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126,  40, 126,  25,  21,  50,
+0,   0,  30,  10, 126,   0, 126, 126,  25,   5,
+   50,   0,  61, 126,  10,  10,   5,   0,  15, 126,
+  126,   5, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 61,
+  TOTAL_KEYWORDS = 62,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,141 +125,143 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 89 "../../gcc/cp/cp-trait.gperf"
+#line 90 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 52 "../../gcc/cp/cp-trait.gperf"
+  {"__is_enum", CPTK_IS_ENUM, 1, false},
+#line 78 "../../gcc/cp/cp-trait.gperf"
+  {"__is_union", CPTK_IS_UNION, 1, false},
 #line 83 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 84 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+#line 89 "../../gcc/cp/cp-trait.gperf"
+  {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false},
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"

[PATCH v18 38/40] libstdc++: Optimize is_signed trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_signed trait by dispatching to
the new __is_signed built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_signed): Use __is_signed built-in trait.
(is_signed_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index f7d3815f332..7e93923f44b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -982,6 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __bool_constant<__is_abstract(_Tp)>
 { };
 
+  /// is_signed
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+  template
+struct is_signed
+: public __bool_constant<__is_signed(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template::value>
@@ -994,11 +1001,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
   /// @endcond
 
-  /// is_signed
   template
 struct is_signed
 : public __is_signed_helper<_Tp>::type
 { };
+#endif
 
   /// is_unsigned
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
@@ -3445,8 +3452,13 @@ template 
 template 
   inline constexpr bool is_final_v = __is_final(_Tp);
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+template 
+  inline constexpr bool is_signed_v = __is_signed(_Tp);
+#else
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
 template 
-- 
2.42.0



[PATCH v18 37/40] c++: Implement __is_signed built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_signed.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_signed.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 211 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_signed.C |  47 +
 7 files changed, 165 insertions(+), 105 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_signed.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c28dad702c3..b161c9b2c9e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SIGNED:
+  inform (loc, "  %qT is not a signed type", t1);
+  break;
 case CPTK_IS_SCOPED_ENUM:
   inform (loc, "  %qT is not a scoped enum", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 0603b4a230f..b0faa4c8937 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ 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)
+DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 90d05bca5c1..de0ba162e7a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
 "__is_trivial", CPTK_IS_TRIVIAL, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 75ab2b5edfa..6d1078de2fe 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 129, duplicates = 0 */
+/* maximum key range = 119, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136,  20, 136,  45,  35,  40,
-   60,   0,  55,   0, 136,   0, 136, 136,  10,  15,
-   35,   0,  10, 136,  10,  15,   5,  15,   0, 136,
-  136,  20, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 

[PATCH v18 36/40] libstdc++: Optimize is_unsigned trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unsigned trait by dispatching
to the new __is_unsigned built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unsigned): Use __is_unsigned built-in
trait.
(is_unsigned_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 48d630a1478..f7d3815f332 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1001,10 +1001,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_unsigned
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+  template
+struct is_unsigned
+: public __bool_constant<__is_unsigned(_Tp)>
+{ };
+#else
   template
 struct is_unsigned
 : public __and_, __not_>>::type
 { };
+#endif
 
   /// @cond undocumented
   template
@@ -3440,8 +3447,14 @@ template 
 
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+template 
+  inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+#else
 template 
   inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+#endif
 
 template 
   inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
-- 
2.42.0



[PATCH v18 34/40] libstdc++: Optimize is_compound trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_compound trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_compound): Do not use __not_.
(is_compound_v): Use is_fundamental_v instead.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 88171e1a672..48d630a1478 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_compound
   template
 struct is_compound
-: public __not_>::type { };
+: public __bool_constant::value> { };
 
   /// is_member_pointer
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
@@ -3387,7 +3387,7 @@ template 
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-  inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+  inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
 template 
-- 
2.42.0



[PATCH v18 35/40] c++: Implement __is_unsigned built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_unsigned.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unsigned.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNSIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 118 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_unsigned.C   |  47 +
 7 files changed, 120 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unsigned.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 3a7f968eae8..c28dad702c3 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_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
+case CPTK_IS_UNSIGNED:
+  inform (loc, "  %qT is not an unsigned type", t1);
+  break;
 case CPTK_IS_VOLATILE:
   inform (loc, "  %qT is not a volatile type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b2be7b7bbd7..0603b4a230f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -94,6 +94,7 @@ 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_UNSIGNED, "__is_unsigned", 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 9050c36f105..90d05bca5c1 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -74,6 +74,7 @@ struct cp_trait {
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
 "__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
+"__is_unsigned", CPTK_IS_UNSIGNED, 1, false
 "__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 31fd5075f2d..75ab2b5edfa 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 97, duplicates = 0 */
+/* maximum key range = 129, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
-5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
-   35,   0,  10, 104,  10,  15,   5,   0,  20, 104,
-  104,  20, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 

[PATCH v18 33/40] libstdc++: Optimize is_fundamental trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_fundamental trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_fundamental_v): Use __is_arithmetic
built-in trait.
(is_fundamental): Likewise. Optimize the original implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index cc466e0f606..88171e1a672 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -739,11 +739,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_fundamental
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_fundamental
+: public __bool_constant<__is_arithmetic(_Tp)
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
+{ };
+#else
   template
 struct is_fundamental
-: public __or_, is_void<_Tp>,
-  is_null_pointer<_Tp>>::type
+: public __bool_constant::value
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
 { };
+#endif
 
   /// is_object
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
@@ -3354,13 +3364,15 @@ template 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
 template 
   inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+template 
+  inline constexpr bool is_fundamental_v
+= __is_arithmetic(_Tp) || is_void_v<_Tp> || is_null_pointer_v<_Tp>;
 #else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
-#endif
-
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
  && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
-- 
2.42.0



[PATCH v18 32/40] libstdc++: Optimize is_arithmetic trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_arithmetic trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_arithmetic): Use __is_arithmetic
built-in trait.
(is_arithmetic_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 3acd843f2f2..cc466e0f606 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -726,10 +726,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_arithmetic
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_arithmetic
+: public __bool_constant<__is_arithmetic(_Tp)>
+{ };
+#else
   template
 struct is_arithmetic
 : public __or_, is_floating_point<_Tp>>::type
 { };
+#endif
 
   /// is_fundamental
   template
@@ -3344,8 +3351,14 @@ template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+template 
+  inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+#else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
 
-- 
2.42.0



[PATCH v18 31/40] c++: Implement __is_arithmetic built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 184 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_arithmetic.C |  33 
 7 files changed, 138 insertions(+), 91 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9d627fa782..3a7f968eae8 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
 case CPTK_IS_ARRAY:
   inform (loc, "  %qT is not an array", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index c60724e869e..b2be7b7bbd7 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 5d40e04f91c..9050c36f105 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_arithmetic", CPTK_IS_ARITHMETIC, 1, false
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ab783b161c7..31fd5075f2d 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 97, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99, 40, 45, 40,
-   5,  0, 55, 10, 99,  0, 99, 99, 10, 25,
-  30,  0, 10, 99, 10, 15,  5,  0, 20, 99,
-  99, 10, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
+5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
+   35,   

[PATCH v18 30/40] libstdc++: Optimize is_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_pointer trait 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 
---
 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 4312f32a4e0..cd5ce45951f 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 __has_builtin(__is_pointer)
+  template
+struct __is_pointer : __truth_type<__is_pointer(_Tp)>
+{
+  enum { __value = __is_pointer(_Tp) };
+};
+#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 9c56d15c0b7..3acd843f2f2 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
@@ -3254,8 +3268,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 
-- 
2.42.0



[PATCH v18 29/40] c++: Implement __is_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.
* g++.dg/ext/is_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 155 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_pointer.C|  51 
 7 files changed, 141 insertions(+), 77 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 99a7e7247ce..c9d627fa782 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,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 2add97ae749..c60724e869e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, 
"__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 8fbd67788d5..5d40e04f91c 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -61,6 +61,7 @@ struct cp_trait {
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false
 "__is_pod", CPTK_IS_POD, 1, false
+"__is_pointer", CPTK_IS_POINTER, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ad2c2a2d250..ab783b161c7 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  40,   5,  40,
-   50,   0,  55,  10, 116,   0, 116, 116,   5,  25,
-   30,   0,   5, 116,  10,  15,   5,   0,  25, 116,
-  116,  20, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 

[PATCH v18 28/40] libstdc++: Optimize remove_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the remove_pointer trait by
dispatching to the new remove_pointer built-in trait.

libstdc++-v3/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 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 674d398c075..9c56d15c0b7 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2105,6 +2105,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
+  template
+struct remove_pointer
+{ using type = __remove_pointer(_Tp); };
+#else
   template
 struct __remove_pointer_helper
 { using type = _Tp; };
@@ -2113,11 +2119,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __remove_pointer_helper<_Tp, _Up*>
 { using type = _Up; };
 
-  /// remove_pointer
   template
 struct remove_pointer
 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
 { };
+#endif
 
   template
 struct __add_pointer_helper
-- 
2.42.0



[PATCH v18 27/40] c++: Implement __remove_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 32 +++---
 gcc/cp/semantics.cc   |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++
 6 files changed, 78 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index fa79bc0c68c..2add97ae749 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -97,6 +97,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_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 771242a7f45..8fbd67788d5 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -77,6 +77,7 @@ struct cp_trait {
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
 "__remove_cv", CPTK_REMOVE_CV, 1, true
 "__remove_cvref", CPTK_REMOVE_CVREF, 1, true
+"__remove_pointer", CPTK_REMOVE_POINTER, 1, true
 "__remove_reference", CPTK_REMOVE_REFERENCE, 1, true
 "__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true
 "__underlying_type", CPTK_UNDERLYING_TYPE, 1, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index b6db58e93c9..ad2c2a2d250 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 56,
+  TOTAL_KEYWORDS = 57,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,7 +125,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 84 "../../gcc/cp/cp-trait.gperf"
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
@@ -137,17 +137,19 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
+#line 80 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
 #line 69 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 80 "../../gcc/cp/cp-trait.gperf"
+#line 81 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
 #line 45 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
 #line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false},
@@ -235,21 +237,21 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__is_final", CPTK_IS_FINAL, 1, false},
 #line 53 "../../gcc/cp/cp-trait.gperf"
   {"__is_function", CPTK_IS_FUNCTION, 1, false},
-#line 83 "../../gcc/cp/cp-trait.gperf"
+#line 84 "../../gcc/cp/cp-trait.gperf"
   {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false}
 };
 
   static const signed char lookup[] =
 {
   -1, -1, -1, -1, -1, -1, -1,  0, -1,  1,  2,  3, -1, -1,
-   4,  5, -1,  6,  7,  8, -1, -1,  9, 10, 11, 12, 13, 14,
-  15, -1, 16, 17, 18, 19, -1, 20, -1, 21, 22, -1, 23, -1,
-  24, 25, 26, 27, -1, 28, 29, 30, 31, -1, 32, -1, 33, 34,
-  -1, -1, 35, 36, 37, 38, -1, 39, 40, -1, -1, -1, 41, 42,
-  43, -1, -1, -1, -1, 44, 45, -1, 46, 47, 48, -1, -1, -1,
-  -1, 49, 50, -1, 51, -1, 52, -1, -1, -1, -1, 53, -1, -1,
-  54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, 55
+   4,  5,  6,  

[PATCH v18 26/40] libstdc++: Optimize is_object trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_object trait by dispatching to
the new __is_function and __is_reference built-in traits.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use __is_function and
__is_reference built-in traits.
(is_object_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index bd57488824b..674d398c075 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_object
+: public __bool_constant::value)>
+{ };
+#else
   template
 struct is_object
 : public __not_<__or_, is_reference<_Tp>,
   is_void<_Tp>>>::type
 { };
+#endif
 
   template
 struct is_member_pointer;
@@ -3305,8 +3314,17 @@ template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_object_v
+= !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
+#else
 template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v18 24/40] c++: Implement __is_function built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_function.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_function.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_FUNCTION.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 143 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_function.C   |  58 +
 7 files changed, 143 insertions(+), 70 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_function.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5cdb59d174e..99a7e7247ce 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3750,6 +3750,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_FINAL:
   inform (loc, "  %qT is not a final class", t1);
   break;
+case CPTK_IS_FUNCTION:
+  inform (loc, "  %qT is not a function", t1);
+  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 e867d9c4c47..fa79bc0c68c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -70,6 +70,7 @@ DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 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_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-trait.gperf b/gcc/cp/cp-trait.gperf
index 5989b84727f..771242a7f45 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -50,6 +50,7 @@ struct cp_trait {
 "__is_empty", CPTK_IS_EMPTY, 1, false
 "__is_enum", CPTK_IS_ENUM, 1, false
 "__is_final", CPTK_IS_FINAL, 1, false
+"__is_function", CPTK_IS_FUNCTION, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f0b4f96d4a9..b6db58e93c9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 94, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
-   40,   0,  60,  10, 101,   0, 101, 101,   5,  25,
-   30,   0,   5, 101,  10,  15,   5,   0,  25, 101,
-  101,  20, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 

[PATCH v18 25/40] libstdc++: Optimize is_function trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_function trait by dispatching
to the new __is_function built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_function): Use __is_function built-in
trait.
(is_function_v): Likewise. Optimize its implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 36ad9814047..bd57488824b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -637,6 +637,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_function
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+  template
+struct is_function
+: public __bool_constant<__is_function(_Tp)>
+{ };
+#else
   template
 struct is_function
 : public __bool_constant::value> { };
@@ -648,6 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_function<_Tp&&>
 : public false_type { };
+#endif
 
 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
   /// is_null_pointer (LWG 2247).
@@ -3269,8 +3276,18 @@ template 
   inline constexpr bool is_union_v = __is_union(_Tp);
 template 
   inline constexpr bool is_class_v = __is_class(_Tp);
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
 template 
-  inline constexpr bool is_function_v = is_function<_Tp>::value;
+  inline constexpr bool is_function_v = __is_function(_Tp);
+#else
+template 
+  inline constexpr bool is_function_v = !is_const_v;
+template 
+  inline constexpr bool is_function_v<_Tp&> = false;
+template 
+  inline constexpr bool is_function_v<_Tp&&> = false;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
 template 
-- 
2.42.0



ping: [PATCH] preprocessor: c++: Support `#pragma GCC target' macros [PR87299]

2023-10-13 Thread Lewis Hyatt
On Tue, Sep 12, 2023 at 04:09:21PM -0400, Lewis Hyatt wrote:
> On Tue, Aug 8, 2023 at 5:53 PM Jason Merrill  wrote:
> >
> > On 7/31/23 22:22, Lewis Hyatt via Gcc-patches wrote:
> > > `#pragma GCC target' is not currently handled in preprocess-only mode 
> > > (e.g.,
> > > when running gcc -E or gcc -save-temps). As noted in the PR, this means 
> > > that
> > > if the target pragma defines any macros, those macros are not effective in
> > > preprocess-only mode. Similarly, such macros are not effective when
> > > compiling with C++ (even when compiling without -save-temps), because C++
> > > does not process the pragma until after all tokens have been obtained from
> > > libcpp, at which point it is too late for macro expansion to take place.
> > >
> > > Since r13-1544 and r14-2893, there is a general mechanism to handle 
> > > pragmas
> > > under these conditions as well, so resolve the PR by using the new "early
> > > pragma" support.
> > >
> > > toplev.cc required some changes because the target-specific handlers for
> > > `#pragma GCC target' may call target_reinit(), and toplev.cc was not 
> > > expecting
> > > that function to be called in preprocess-only mode.
> > >
> > > I added some additional testcases from the PR for x86. The other targets
> > > that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
> > > already had tests verifying that the pragma sets macros as expected; here 
> > > I
> > > have added -save-temps to some of them, to test that it now works in
> > > preprocess-only mode as well.
> > >
> > > gcc/c-family/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * c-pragma.cc (init_pragma): Register `#pragma GCC target' and
> > >   related pragmas in preprocess-only mode, and enable early handling.
> > >   (c_reset_target_pragmas): New function refactoring code from...
> > >   (handle_pragma_reset_options): ...here.
> > >   * c-pragma.h (c_reset_target_pragmas): Declare.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * parser.cc (cp_lexer_new_main): Call c_reset_target_pragmas ()
> > >   after preprocessing is complete, before starting compilation.
> > >
> > > gcc/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * toplev.cc (no_backend): New static global.
> > >   (finalize): Remove argument no_backend, which is now a
> > >   static global.
> > >   (process_options): Likewise.
> > >   (do_compile): Likewise.
> > >   (target_reinit): Don't do anything in preprocess-only mode.
> > >   (toplev::main): Adapt to no_backend change.
> > >   (toplev::finalize): Likewise.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * c-c++-common/pragma-target-1.c: New test.
> > >   * c-c++-common/pragma-target-2.c: New test.
> > >   * g++.target/i386/pr87299-1.C: New test.
> > >   * g++.target/i386/pr87299-2.C: New test.
> > >   * gcc.target/i386/pr87299-1.c: New test.
> > >   * gcc.target/i386/pr87299-2.c: New test.
> > >   * gcc.target/s390/target-attribute/tattr-2.c: Add -save-temps to the
> > >   options, to test preprocess-only mode as well.
> > >   * gcc.target/aarch64/pragma_cpp_predefs_1.c: Likewise.
> > >   * gcc.target/arm/pragma_arch_attribute.c: Likewise.
> > >   * gcc.target/nios2/custom-fp-2.c: Likewise.
> > >   * gcc.target/powerpc/float128-3.c: Likewise.
> > > ---
> > >
> > > Notes:
> > >  Hello-
> > >
> > >  This patch fixes the PR by enabling early pragma handling for 
> > > `#pragma GCC
> > >  target' and related pragmas such as `#pragma GCC push_options'. I 
> > > did not
> > >  need to touch any target-specific code, however I did need to make a 
> > > change
> > >  to toplev.cc, affecting all targets, to make it safe to call 
> > > target_reinit()
> > >  in preprocess-only mode. (Otherwise, it would be necessary to modify 
> > > the
> > >  implementation of target pragmas in every target, to avoid this code 
> > > path.)
> > >  That was the only complication I ran into.
> > >
> > >  Regarding testing, I did: (thanks to GCC compile farm for the non-x86
> > >  targets)
> > >
> > >  bootstrap + regtest all languages - x86_64-pc-linux-gnu
> > >  bootstrap + regtest c/c++ - powerpc64le-unknown-linux-gnu,
> > >  aarch64-unknown-linux-gnu
> > >
> > >  The following backends also implement this pragma so ought to be 
> > > tested:
> > >  arm
> > >  nios2
> > >  s390
> > >
> > >  I am not able to test those directly. I did add coverage to their 
> > > testsuites
> > >  (basically, adding -save-temps to any existing test, causes it to 
> > > test the
> > >  pragma in preprocess-only mode.) Then, I verified on x86_64 with a 
> > > cross
> > >  compiler, that the modified testcases fail before the patch and pass
> > >  afterwards. nios2 is an exception, it does not 

[PATCH v18 23/40] libstdc++: Optimize is_reference trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_reference trait by dispatching
to the new __is_reference built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in
trait.
(is_reference_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 792213ebfe8..36ad9814047 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -682,6 +682,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Composite type categories.
 
   /// is_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_reference
+: public __bool_constant<__is_reference(_Tp)>
+{ };
+#else
   template
 struct is_reference
 : public false_type
@@ -696,6 +702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_reference<_Tp&&>
 : public true_type
 { };
+#endif
 
   /// is_arithmetic
   template
@@ -3264,12 +3271,19 @@ template 
   inline constexpr bool is_class_v = __is_class(_Tp);
 template 
   inline constexpr bool is_function_v = is_function<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_reference_v = __is_reference(_Tp);
+#else
 template 
   inline constexpr bool is_reference_v = false;
 template 
   inline constexpr bool is_reference_v<_Tp&> = true;
 template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
+#endif
+
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v18 22/40] c++: Implement __is_reference built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_reference.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_reference.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_REFERENCE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 113 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_reference.C  |  34 +++
 7 files changed, 104 insertions(+), 55 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_reference.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 98b1f004a68..5cdb59d174e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
+case CPTK_IS_REFERENCE:
+  inform (loc, "  %qT is not a reference", t1);
+  break;
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 11fd70b3964..e867d9c4c47 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
+DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 32199a1fe9a..5989b84727f 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -61,6 +61,7 @@ struct cp_trait {
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false
 "__is_pod", CPTK_IS_POD, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
+"__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 799fe2b792f..f0b4f96d4a9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 94, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 40,  5, 40,
-  40,  0, 25, 10, 96,  0, 96, 96,  5, 25,
-  30,  0,  5, 96, 10, 15,  5,  0, 25, 96,
-  96, 20, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
+   40,   0, 

[PATCH v18 20/40] c++: Implement __is_member_object_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_object_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_object_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_OBJECT_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_member_object_pointer.
* g++.dg/ext/is_member_object_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 +
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 62 ++-
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +
 .../g++.dg/ext/is_member_object_pointer.C | 30 +
 7 files changed, 74 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_object_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d0464dd4f6a..98b1f004a68 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3759,6 +3759,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
   inform (loc, "  %qT is not a member function pointer", t1);
   break;
+case CPTK_IS_MEMBER_OBJECT_POINTER:
+  inform (loc, "  %qT is not a member object pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 897b96630f2..11fd70b3964 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -73,6 +73,7 @@ DEFTRAIT_EXPR (IS_FINAL, "__is_final", 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)
+DEFTRAIT_EXPR (IS_MEMBER_OBJECT_POINTER, "__is_member_object_pointer", 1)
 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index b28efbab322..32199a1fe9a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -53,6 +53,7 @@ struct cp_trait {
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
+"__is_member_object_pointer", CPTK_IS_MEMBER_OBJECT_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index d3d4bdf9799..799fe2b792f 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 53,
+  TOTAL_KEYWORDS = 54,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,57 +125,57 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 75 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 76 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 77 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 79 "../../gcc/cp/cp-trait.gperf"
+#line 80 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
 #line 45 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   

[PATCH v18 21/40] libstdc++: Optimize is_member_object_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_object_pointer trait
by dispatching to the new __is_member_object_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_object_pointer): Use
__is_member_object_pointer built-in trait.
(is_member_object_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index e1b10240dc2..792213ebfe8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -574,6 +574,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_rvalue_reference<_Tp&&>
 : public true_type { };
 
+  /// is_member_object_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+  template
+struct is_member_object_pointer
+: public __bool_constant<__is_member_object_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_object_pointer_helper
 : public false_type { };
@@ -582,11 +589,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __is_member_object_pointer_helper<_Tp _Cp::*>
 : public __not_>::type { };
 
-  /// is_member_object_pointer
+
   template
 struct is_member_object_pointer
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
   /// is_member_function_pointer
@@ -3227,9 +3235,16 @@ template 
   inline constexpr bool is_rvalue_reference_v = false;
 template 
   inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+template 
+  inline constexpr bool is_member_object_pointer_v =
+__is_member_object_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
 template 
-- 
2.42.0



[PATCH v18 18/40] c++: Implement __is_member_function_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_function_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_function_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_FUNCTION_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_member_function_pointer.
* g++.dg/ext/is_member_function_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 176 +-
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 .../g++.dg/ext/is_member_function_pointer.C   |  31 +++
 7 files changed, 131 insertions(+), 88 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_function_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f0d3f89464c..d0464dd4f6a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
+  inform (loc, "  %qT is not a member function pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 26087da3bdf..897b96630f2 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 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)
 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 3775b11283d..b28efbab322 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index dfd60cec6e6..d3d4bdf9799 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 111, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118,  20, 118,   0,  55,  50,
-   40,   0,  40,  20, 118,   0, 118, 118,   5,   5,
-   30,   0,   5, 118,  10,  50,   5,   0,   5, 118,
-  118,   5, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 

[PATCH v18 19/40] libstdc++: Optimize is_member_function_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_function_pointer trait
by dispatching to the new __is_member_function_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_function_pointer): Use
__is_member_function_pointer built-in trait.
(is_member_function_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 16 
 1 file changed, 16 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index d7f89cf7c06..e1b10240dc2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -588,6 +588,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+  /// is_member_function_pointer
+  template
+struct is_member_function_pointer
+: public __bool_constant<__is_member_function_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_function_pointer_helper
 : public false_type { };
@@ -601,6 +608,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_function_pointer
 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   /// is_enum
   template
@@ -3222,9 +3230,17 @@ template 
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+template 
+  inline constexpr bool is_member_function_pointer_v =
+__is_member_function_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_function_pointer_v =
 is_member_function_pointer<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_enum_v = __is_enum(_Tp);
 template 
-- 
2.42.0



[PATCH v18 17/40] libstdc++: Optimize is_member_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_pointer trait
by dispatching to the new __is_member_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_pointer): Use __is_member_pointer
built-in trait.
(is_member_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7fd29d8d9f2..d7f89cf7c06 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -716,6 +716,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_compound
 : public __not_>::type { };
 
+  /// is_member_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+  template
+struct is_member_pointer
+: public __bool_constant<__is_member_pointer(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template
 struct __is_member_pointer_helper
@@ -726,11 +733,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
   /// @endcond
 
-  /// is_member_pointer
   template
 struct is_member_pointer
 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   template
 struct is_same;
@@ -3242,8 +3249,14 @@ template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+template 
+  inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
 template 
-- 
2.42.0



[PATCH v18 15/40] libstdc++: Optimize is_scoped_enum trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_scoped_enum trait
by dispatching to the new __is_scoped_enum built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scoped_enum): Use
__is_scoped_enum built-in trait.
(is_scoped_enum_v): Likewise.

Signed-off-by: Ken Matsui 
---
 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 d306073a797..7fd29d8d9f2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3633,6 +3633,12 @@ template
   /// True if the type is a scoped enumeration type.
   /// @since C++23
 
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+struct is_scoped_enum
+: bool_constant<__is_scoped_enum(_Tp)>
+{ };
+# else
   template
 struct is_scoped_enum
 : false_type
@@ -3644,11 +3650,17 @@ template
 struct is_scoped_enum<_Tp>
 : bool_constant
 { };
+# endif
 
   /// @ingroup variable_templates
   /// @since C++23
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
+# else
   template
 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+# endif
 #endif
 
 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && 
ref_{converts,constructs}_from_temp
-- 
2.42.0



[PATCH v18 16/40] c++: Implement __is_member_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_MEMBER_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_member_pointer.
* g++.dg/ext/is_member_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 153 ++-
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_member_pointer.C |  30 
 7 files changed, 120 insertions(+), 75 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 1c0b2e0f178..f0d3f89464c 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_POINTER:
+  inform (loc, "  %qT is not a member pointer", t1);
+  break;
 case CPTK_IS_NOTHROW_ASSIGNABLE:
   inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e0e3fe1d23f..26087da3bdf 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index f3fd82ba549..3775b11283d 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 9c18165eb68..dfd60cec6e6 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 111, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99,  0,  5, 50,
-  30,  0, 40, 15, 99,  0, 99, 99,  5, 10,
-  30,  0,  5, 99, 10, 50,  5,  0, 35, 99,
-  99,  5, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 

[PATCH v18 14/40] c++: Implement __is_scoped_enum built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scoped_enum.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scoped_enum.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCOPED_ENUM.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 161 +++---
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C |  67 +
 7 files changed, 160 insertions(+), 80 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scoped_enum.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d09252a56b6..1c0b2e0f178 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3781,6 +3781,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCOPED_ENUM:
+  inform (loc, "  %qT is not a scoped enum", t1);
+  break;
 case CPTK_IS_STD_LAYOUT:
   inform (loc, "  %qT is not an standard layout type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 6d6dff7a4c3..e0e3fe1d23f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -79,6 +79,7 @@ DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertib
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 90fcdc01de6..f3fd82ba549 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -59,6 +59,7 @@ struct cp_trait {
 "__is_pod", CPTK_IS_POD, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
 "__is_trivial", CPTK_IS_TRIVIAL, 1, false
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f22a6e93618..9c18165eb68 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
-   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
-  116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 

[PATCH v18 13/40] libstdc++: Optimize is_bounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_bounded_array trait by
dispatching to the new __is_bounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_bounded_array_v): Use __is_bounded_array
built-in trait.

Signed-off-by: Ken Matsui 
---
 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 cb3d9e238fa..d306073a797 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3532,11 +3532,16 @@ template
   /// True for a type that is an array of known bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
+  template
+inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
+# else
   template
 inline constexpr bool is_bounded_array_v = false;
 
   template
 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
+# endif
 
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
-- 
2.42.0



[PATCH v18 11/40] libstdc++: Optimize is_unbounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unbounded_array trait by
dispatching to the new __is_unbounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unbounded_array_v): Use
__is_unbounded_array built-in trait.

Signed-off-by: Ken Matsui 
---
 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 4e8165e5af5..cb3d9e238fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3541,11 +3541,16 @@ template
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
+  template
+inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
+# else
   template
 inline constexpr bool is_unbounded_array_v = false;
 
   template
 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+# endif
 
   /// True for a type that is an array of known bound.
   /// @since C++20
-- 
2.42.0



[PATCH v18 12/40] c++: Implement __is_bounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_bounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_bounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_BOUNDED_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_bounded_array.
* g++.dg/ext/is_bounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|  3 +
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/cp-trait.gperf   |  1 +
 gcc/cp/cp-trait.h   | 86 +++--
 gcc/cp/semantics.cc |  4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 +
 gcc/testsuite/g++.dg/ext/is_bounded_array.C | 38 +
 7 files changed, 94 insertions(+), 42 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_bounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 751ac61b25a..d09252a56b6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
+case CPTK_IS_BOUNDED_ARRAY:
+  inform (loc, "  %qT is not a bounded array", t1);
+  break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 4e02f68e4a9..6d6dff7a4c3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index a894fc8c74c..90fcdc01de6 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
+"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false
 "__is_class", CPTK_IS_CLASS, 1, false
 "__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 47060ffbbef..f22a6e93618 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
   116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 49,
+  TOTAL_KEYWORDS = 50,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,54 +125,56 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 50 "../../gcc/cp/cp-trait.gperf"
+#line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 72 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
-#line 49 "../../gcc/cp/cp-trait.gperf"
+#line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 62 "../../gcc/cp/cp-trait.gperf"
+#line 63 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", 

[PATCH v18 09/40] libstdc++: Optimize is_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_array trait by dispatching to
the new __is_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_array): Use __is_array built-in trait.
(is_array_v): Likewise.

Signed-off-by: Ken Matsui 
---
 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 c01f65df22b..4e8165e5af5 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -523,6 +523,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_array
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+  template
+struct is_array
+: public __bool_constant<__is_array(_Tp)>
+{ };
+#else
   template
 struct is_array
 : public false_type { };
@@ -534,6 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_array<_Tp[]>
 : public true_type { };
+#endif
 
   template
 struct __is_pointer_helper
@@ -3183,12 +3190,17 @@ template 
 template 
   inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+template 
+  inline constexpr bool is_array_v = __is_array(_Tp);
+#else
 template 
   inline constexpr bool is_array_v = false;
 template 
   inline constexpr bool is_array_v<_Tp[]> = true;
 template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
+#endif
 
 template 
   inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
-- 
2.42.0



[PATCH v18 08/40] c++: Implement __is_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_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_array.
* g++.dg/ext/is_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 148 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_array.C  |  28 +
 7 files changed, 116 insertions(+), 72 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f031e022541..5e30a4a907a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARRAY:
+  inform (loc, "  %qT is not an array", t1);
+  break;
 case CPTK_IS_ASSIGNABLE:
   inform (loc, "  %qT is not assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index d786f47e60c..99bc05360b9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index ea7abda6c75..fb162cac164 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f462794d5db..526e63dec42 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
-  40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
-  96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
+   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
+   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+ 

[PATCH v18 10/40] c++: Implement __is_unbounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_unbounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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 
---
 gcc/cp/constraint.cc  |  3 ++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 42 ++-
 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 
 7 files changed, 71 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unbounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e30a4a907a..751ac61b25a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,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 99bc05360b9..4e02f68e4a9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index fb162cac164..a894fc8c74c 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -63,6 +63,7 @@ struct cp_trait {
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
+"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
 "__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 526e63dec42..47060ffbbef 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 48,
+  TOTAL_KEYWORDS = 49,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,30 +125,32 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 76 "../../gcc/cp/cp-trait.gperf"
+#line 77 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 71 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
 #line 62 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_volatile", CPTK_IS_VOLATILE, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
+#line 66 "../../gcc/cp/cp-trait.gperf"
+  

[PATCH v18 05/40] libstdc++: Optimize is_const trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_const trait 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 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 677cd934b94..686e38e47c3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,6 +784,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 { };
@@ -791,6 +797,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_const<_Tp const>
 : public true_type { };
+#endif
 
   /// is_volatile
   template
@@ -3218,10 +3225,17 @@ template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+
+#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
+
 template 
   inline constexpr bool is_volatile_v = false;
 template 
-- 
2.42.0



[PATCH v18 06/40] c++: Implement __is_volatile built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_volatile.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/cp-trait.gperf|  1 +
 gcc/cp/cp-trait.h| 38 +---
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_volatile.C   | 19 
 7 files changed, 51 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 567dd35fe0a..f031e022541 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,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 9e4e6d798a0..d786f47e60c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 47a5ec9ee6f..ea7abda6c75 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -63,6 +63,7 @@ struct cp_trait {
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
+"__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
 "__remove_cv", CPTK_REMOVE_CV, 1, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index c9005eee1ff..f462794d5db 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
   40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0, 96, 96,
+  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
   96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 46,
+  TOTAL_KEYWORDS = 47,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,27 +125,29 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
 #line 65 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 68 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 69 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 70 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 48 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
 #line 61 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
+#line 71 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 

[PATCH v18 07/40] libstdc++: Optimize is_volatile trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_volatile trait 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 
---
 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 686e38e47c3..c01f65df22b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -800,6 +800,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 { };
@@ -807,6 +813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
@@ -3236,10 +3243,15 @@ template 
   inline constexpr bool is_const_v = true;
 #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);
-- 
2.42.0



[PATCH v18 04/40] c++: Implement __is_const built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_const.

gcc/cp/ChangeLog:

* Make-lang.in: Update key positions for gperf, based on
automatically computed values.
* cp-trait.def: Define __is_const.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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 
---
 gcc/cp/Make-lang.in  |   2 +-
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 202 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_const.C  |  19 +++
 8 files changed, 135 insertions(+), 100 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C

diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index a67d1c3e9f3..7479e7dc00b 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -195,7 +195,7 @@ $(srcdir)/cp/cp-trait.h: $(srcdir)/cp/cp-trait.gperf
 else
 $(srcdir)/cp/cp-trait.h: | $(srcdir)/cp/cp-trait.gperf
 endif
-   gperf -o -C -E -k '8' -D -N 'find' -L C++ \
+   gperf -o -C -E -k '6,8' -D -N 'find' -L C++ \
$(srcdir)/cp/cp-trait.gperf --output-file 
$(srcdir)/cp/cp-trait.h
 
 # The cp-trait.gperf file itself is generated from
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 722fc334e6f..567dd35fe0a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,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 0e48e64b8dd..9e4e6d798a0 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 47e3c1af499..47a5ec9ee6f 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
+"__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
 "__is_convertible", CPTK_IS_CONVERTIBLE, 2, false
 "__is_empty", CPTK_IS_EMPTY, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 97ba8492d15..c9005eee1ff 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -1,5 +1,5 @@
 /* C++ code produced by gperf version 3.1 */
-/* Command-line: gperf -o -C -E -k 8 -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
+/* Command-line: gperf -o -C -E -k 6,8 -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
   && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 79, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86,  1, 86, 86,
-   0, 35, 86,  0, 86,  0, 86, 86, 10, 10,
-  50, 15, 55, 86, 30,  5, 15,  0, 86, 86,
-  86, 20, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 

[PATCH v18 03/40] c++: Accept the use of non-function-like built-in trait identifiers

2023-10-13 Thread Ken Matsui
This patch accepts the use of non-function-like built-in trait
identifiers.  Specifically, we check if the subsequent token is '(' for
ordinary built-in traits or is '<' only for the special __type_pack_element
built-in trait.  If the same identifiers are used in other cases, the
parser treats them as normal identifiers.  This allows us to accept code
like:

struct __is_pointer {};

gcc/cp/ChangeLog:

* parser.cc (cp_lexer_lookup_trait): Rename to ...
(cp_lexer_peek_trait): ... this.  Handle a subsequent token for
the corresponding built-in trait.
(cp_lexer_lookup_trait_expr): Rename to ...
(cp_lexer_peek_trait_expr): ... this.
(cp_lexer_lookup_trait_type): Rename to ...
(cp_lexer_peek_trait_type): ... this.
(cp_lexer_next_token_is_decl_specifier_keyword): Call
cp_lexer_peek_trait_type.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_primary_expression): Call cp_lexer_peek_trait_expr.

Signed-off-by: Ken Matsui 
---
 gcc/cp/parser.cc | 48 ++--
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 39952893ffa..59015eac596 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -247,12 +247,12 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static const cp_trait *cp_lexer_lookup_trait
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_expr
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_type
-  (const cp_token *);
+static const cp_trait *cp_lexer_peek_trait
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_expr
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_type
+  (cp_lexer *lexer, const cp_token *);
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -1183,21 +1183,33 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
 }
 }
 
-/* Look ups the corresponding built-in trait if a given token is
+/* Peeks the corresponding built-in trait if a given token is
a built-in trait.  Otherwise, returns nullptr.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait (const cp_token *token)
+cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
 {
-  tree id = token->u.value;
+  tree id = token1->u.value;
 
-  if (token->type == CPP_NAME
+  if (token1->type == CPP_NAME
   && TREE_CODE (id) == IDENTIFIER_NODE
   && IDENTIFIER_TRAIT_P (id))
 {
   const char *id_str = IDENTIFIER_POINTER (id);
   const int id_len = IDENTIFIER_LENGTH (id);
-  return cp_trait_lookup::find (id_str, id_len);
+  const cp_trait *trait = cp_trait_lookup::find (id_str, id_len);
+
+  /* Check if the subsequent token is a `<' token to
+ __type_pack_element or is a `(' token to everything else.  */
+  const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
+  if (trait->kind == CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_LESS)
+   return nullptr;
+  if (trait->kind != CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_OPEN_PAREN)
+   return nullptr;
+
+  return trait;
 }
   return nullptr;
 }
@@ -1206,9 +1218,9 @@ cp_lexer_lookup_trait (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_expr (const cp_token *token)
+cp_lexer_peek_trait_expr (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && !trait->type)
 return trait;
 
@@ -1219,9 +1231,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_type (const cp_token *token)
+cp_lexer_peek_trait_type (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && trait->type)
 return trait;
 
@@ -1236,7 +1248,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
*lexer)
   cp_token *token;
 
   token = cp_lexer_peek_token (lexer);
-  if (cp_lexer_lookup_trait_type (token))
+  if (cp_lexer_peek_trait_type (lexer, token))
 return true;
   return cp_keyword_starts_decl_specifier_p (token->keyword);
 }
@@ -6108,7 +6120,7 @@ cp_parser_primary_expression (cp_parser *parser,
 keyword.  */
 case CPP_NAME:
   {
-   const cp_trait* trait = cp_lexer_lookup_trait_expr (token);
+   const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer, token);
if (trait)
  return cp_parser_trait (parser, trait);
   }
@@ -20117,7 +20129,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 }
 
   /* If token is a type-yielding built-in traits, parse it.  */
-  

[PATCH v18 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-13 Thread Ken Matsui
Since RID_MAX soon reaches 255 and all built-in traits are used approximately
once in a C++ translation unit, this patch removes all RID values for built-in
traits and uses gperf to look up the specific trait. Rather than holding
traits as keywords, we set all trait identifiers as cik_trait, which is a new
cp_identifier_kind. As cik_reserved_for_udlit was unused and
cp_identifier_kind is 3 bits, we replaced the unused field with the new
cik_trait. Also, the later patch handles a subsequent token to the built-in
identifier so that we accept the use of non-function-like built-in trait
identifiers.

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Remove all mappings of
built-in traits.
* c-common.h (enum rid): Remove all RID values for built-in traits.

gcc/cp/ChangeLog:

* Make-lang.in: Add targets to generate cp-trait.gperf and
cp-trait.h.
* cp-objcp-common.cc (names_builtin_p): Remove all RID value
cases for built-in traits.  Check for built-in traits via
the new cik_trait identifier.
* cp-tree.h (cik_reserved_for_udlit): Rename to ...
(cik_trait): ... this.
(IDENTIFIER_ANY_OP_P): Exclude cik_trait.
(IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
* lex.cc (init_cp_traits): New function to set cik_trait for all
built-in trait identifiers.
(cxx_init): Call init_cp_traits function.
* parser.cc (cp_lexer_lookup_trait): New function to look up a
built-in trait from a token by gperf.
(cp_lexer_lookup_trait_expr): Likewise, look up an
expression-yielding built-in trait.
(cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
built-in trait.
(cp_keyword_starts_decl_specifier_p): Remove all RID value cases
for built-in traits.
(cp_lexer_next_token_is_decl_specifier_keyword): Handle
type-yielding built-in traits.
(cp_parser_primary_expression): Remove all RID value cases for
built-in traits.  Handle expression-yielding built-in traits.
(cp_parser_trait): Handle cp_trait instead of enum rid.
(cp_parser_simple_type_specifier): Remove all RID value cases
for built-in traits.  Handle type-yielding built-in traits.
* cp-trait-head.in: New file.
* cp-trait.gperf: New file.
* cp-trait.h: New file.

Co-authored-by: Patrick Palka 
Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |   7 --
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 +
 gcc/cp/cp-trait.gperf |  74 
 gcc/cp/cp-trait.h | 247 ++
 gcc/cp/cp-tree.h  |  14 ++-
 gcc/cp/lex.cc |  19 +++
 gcc/cp/parser.cc  | 132 
 10 files changed, 492 insertions(+), 70 deletions(-)
 create mode 100644 gcc/cp/cp-trait-head.in
 create mode 100644 gcc/cp/cp-trait.gperf
 create mode 100644 gcc/cp/cp-trait.h

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index f044db5b797..21fd333ef57 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
   { "wchar_t", RID_WCHAR,  D_CXXONLY },
   { "while",   RID_WHILE,  0 },
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  { NAME,  RID_##CODE, D_CXXONLY },
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-  /* An alias for __is_same.  */
-  { "__is_same_as",RID_IS_SAME,D_CXXONLY },
-
   /* C++ transactional memory.  */
   { "synchronized",RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1fdba7ef3ea..051a442e0f4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -168,11 +168,6 @@ enum rid
   RID_BUILTIN_LAUNDER,
   RID_BUILTIN_BIT_CAST,
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  RID_##CODE,
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-
   /* C++11 */
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
 
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 2727fb7f8cc..a67d1c3e9f3 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -34,6 +34,8 @@
 # - the compiler proper (eg: cc1plus)
 # - define the names for selecting the language in LANGUAGES.
 
+AWK = @AWK@
+
 # Actual names to use when installing a native compiler.
 CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
 GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
@@ -186,6 +188,30 @@ endif
 # This is the file that depends on the generated header file.
 cp/name-lookup.o: $(srcdir)/cp/std-name-hint.h
 
+# We always need the dependency on the .gperf file
+# because it itself is generated.
+ifeq 

[PATCH v18 01/40] c++: Sort built-in traits alphabetically

2023-10-13 Thread Ken Matsui
This patch sorts built-in traits alphabetically for better code
readability.

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Sort built-in traits
alphabetically.
* cp-trait.def: Likewise.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(finish_trait_type): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc | 68 -
 gcc/cp/cp-trait.def  | 10 +--
 gcc/cp/semantics.cc  | 94 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +-
 4 files changed, 121 insertions(+), 121 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9e4e7043cd..722fc334e6f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
   inform (loc, "  %qT is not trivially destructible", t1);
   break;
+case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+  inform (loc, "  %qT does not have unique object representations", t1);
+  break;
 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
   inform (loc, "  %qT does not have a virtual destructor", t1);
   break;
 case CPTK_IS_ABSTRACT:
   inform (loc, "  %qT is not an abstract class", t1);
   break;
+case CPTK_IS_AGGREGATE:
+  inform (loc, "  %qT is not an aggregate", t1);
+  break;
+case CPTK_IS_ASSIGNABLE:
+  inform (loc, "  %qT is not assignable from %qT", t1, t2);
+  break;
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONSTRUCTIBLE:
+  if (!t2)
+inform (loc, "  %qT is not default constructible", t1);
+  else
+inform (loc, "  %qT is not constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_CONVERTIBLE:
+  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_EMPTY:
   inform (loc, "  %qT is not an empty class", t1);
   break;
@@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_NOTHROW_ASSIGNABLE:
+  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+  if (!t2)
+   inform (loc, "  %qT is not nothrow default constructible", t1);
+  else
+   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   inform (loc, "  %qT is not pointer-interconvertible base of %qT",
  t1, t2);
@@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIAL:
   inform (loc, "  %qT is not a trivial type", t1);
   break;
-case CPTK_IS_UNION:
-  inform (loc, "  %qT is not a union", t1);
-  break;
-case CPTK_IS_AGGREGATE:
-  inform (loc, "  %qT is not an aggregate", t1);
-  break;
-case CPTK_IS_TRIVIALLY_COPYABLE:
-  inform (loc, "  %qT is not trivially copyable", t1);
-  break;
-case CPTK_IS_ASSIGNABLE:
-  inform (loc, "  %qT is not assignable from %qT", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
   inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
   break;
-case CPTK_IS_NOTHROW_ASSIGNABLE:
-  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
-  break;
-case CPTK_IS_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not default constructible", t1);
-  else
-   inform (loc, "  %qT is not constructible from %qE", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
   if (!t2)
inform (loc, "  %qT is not trivially default constructible", t1);
   else
inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
   break;
-case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not nothrow default constructible", t1);
-  else
-   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
-  break;
-case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
-  inform (loc, "  %qT does not have unique object representations", t1);
-  break;
-case CPTK_IS_CONVERTIBLE:
-  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+case CPTK_IS_TRIVIALLY_COPYABLE:
+  inform (loc, "  %qT is not trivially copyable", t1);
   break;
-case CPTK_IS_NOTHROW_CONVERTIBLE:
-   

[PATCH v18 00/40] Optimize type traits performance

2023-10-13 Thread Ken Matsui
This patch series optimizes type traits performance by implementing
built-in type traits and using them in libstdc++.

Changes in v18:

* Removed all RID values for built-in traits and used cik_trait
instead.
* Improved to handle the use of non-function-like built-in trait
identifiers.
* Reverted all changes to conflicted identifiers with new built-ins
in the existing code base.

Changes in v17:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in.
* Made ridpointers for RID_TRAIT_EXPR and RID_TRAIT_TYPE empty.

Changes in v16:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in and gperf struct.
* Supply -k option to gperf to support older versions than 2.8.

Changes in v15:

* Rebased on top of trunk.
* Use gperf to look up traits instead of enum rid.

Changes in v14:

* Added padding calculation to the commit message.

Changes in v13:

* Fixed ambiguous commit message and comment.

Changes in v12:

* Evaluated all paddings affected by the enum rid change.

Changes in v11:

* Merged all patches into one patch series.
* Rebased on top of trunk.
* Unified commit message style.
* Used _GLIBCXX_USE_BUILTIN_TRAIT.

Ken Matsui (40):
  c++: Sort built-in traits alphabetically
  c-family, c++: Look up built-in traits through gperf
  c++: Accept the use of non-function-like built-in trait identifiers
  c++: Implement __is_const built-in trait
  libstdc++: Optimize is_const trait performance
  c++: Implement __is_volatile built-in trait
  libstdc++: Optimize is_volatile trait performance
  c++: Implement __is_array built-in trait
  libstdc++: Optimize is_array trait performance
  c++: Implement __is_unbounded_array built-in trait
  libstdc++: Optimize is_unbounded_array trait performance
  c++: Implement __is_bounded_array built-in trait
  libstdc++: Optimize is_bounded_array trait performance
  c++: Implement __is_scoped_enum built-in trait
  libstdc++: Optimize is_scoped_enum trait performance
  c++: Implement __is_member_pointer built-in trait
  libstdc++: Optimize is_member_pointer trait performance
  c++: Implement __is_member_function_pointer built-in trait
  libstdc++: Optimize is_member_function_pointer trait performance
  c++: Implement __is_member_object_pointer built-in trait
  libstdc++: Optimize is_member_object_pointer trait performance
  c++: Implement __is_reference built-in trait
  libstdc++: Optimize is_reference trait performance
  c++: Implement __is_function built-in trait
  libstdc++: Optimize is_function trait performance
  libstdc++: Optimize is_object trait performance
  c++: Implement __remove_pointer built-in trait
  libstdc++: Optimize remove_pointer trait performance
  c++: Implement __is_pointer built-in trait
  libstdc++: Optimize is_pointer trait performance
  c++: Implement __is_arithmetic built-in trait
  libstdc++: Optimize is_arithmetic trait performance
  libstdc++: Optimize is_fundamental trait performance
  libstdc++: Optimize is_compound trait performance
  c++: Implement __is_unsigned built-in trait
  libstdc++: Optimize is_unsigned trait performance
  c++: Implement __is_signed built-in trait
  libstdc++: Optimize is_signed trait performance
  c++: Implement __is_scalar built-in trait
  libstdc++: Optimize is_scalar trait performance

 gcc/c-family/c-common.cc  |   7 -
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 ++
 gcc/cp/constraint.cc  | 112 +--
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 ++
 gcc/cp/cp-trait.def   |  27 +-
 gcc/cp/cp-trait.gperf |  91 ++
 gcc/cp/cp-trait.h | 285 ++
 gcc/cp/cp-tree.h  |  14 +-
 gcc/cp/lex.cc |  19 ++
 gcc/cp/parser.cc  | 144 ++---
 gcc/cp/semantics.cc   | 157 +++---
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  | 117 +--
 gcc/testsuite/g++.dg/ext/is_arithmetic.C  |  33 ++
 gcc/testsuite/g++.dg/ext/is_array.C   |  28 ++
 gcc/testsuite/g++.dg/ext/is_bounded_array.C   |  38 +++
 gcc/testsuite/g++.dg/ext/is_const.C   |  19 ++
 gcc/testsuite/g++.dg/ext/is_function.C|  58 
 .../g++.dg/ext/is_member_function_pointer.C   |  31 ++
 .../g++.dg/ext/is_member_object_pointer.C |  30 ++
 gcc/testsuite/g++.dg/ext/is_member_pointer.C  |  30 ++
 gcc/testsuite/g++.dg/ext/is_pointer.C |  51 
 gcc/testsuite/g++.dg/ext/is_reference.C   |  34 +++
 gcc/testsuite/g++.dg/ext/is_scalar.C  |  31 ++
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C |  

Re: [PATCH] Fortran: name conflict between internal procedure and derived type [PR104351]

2023-10-13 Thread Jerry D

On 10/11/23 12:44 PM, Harald Anlauf wrote:

Dear All,

sorry for attaching the wrong patch - this time it is the correct one!

Harald

On 10/11/23 21:39, Harald Anlauf wrote:

Dear All,

the attached trivial patch fixes (= catches) a forgotten corner-case
in the detection of a name conflict between an internal procedure and
a local declaration for the case that the latter is a derived type.
Another torture test by Gerhard... ;-)  Used to ICE previously.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald



This one is OK as well. Once I found the right patch on the right email. 
 Regardless, both good to go.


Thanks,

Jerry


Re: [PATCH] Fortran: name conflict between internal procedure and derived type [PR104351]

2023-10-13 Thread Jerry D

On 10/11/23 12:39 PM, Harald Anlauf wrote:

Dear All,

the attached trivial patch fixes (= catches) a forgotten corner-case
in the detection of a name conflict between an internal procedure and
a local declaration for the case that the latter is a derived type.
Another torture test by Gerhard... ;-)  Used to ICE previously.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald



This one is OK Harald.

Thanks,

Jerry


Continued (Non)mutlib and stub header issue (was Re: [PATCH v2] RISC-V: Use stdint-gcc.h in rvv testsuite)

2023-10-13 Thread Vineet Gupta

Hi Kito, Christoph, Patrick,

I've been trying to test a specific non multilib config 
(rv64-zicond_zfa) and seeing noisy output (compared to a similar multlib 
build) and it seems there's still a bunch of this header issue (for the 
rv32 abi headers) in the non-multlib config.


e.g.
FAIL: gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul1-7.c -O3 
-ftree-vectorize --param riscv-autovec-lmul=dynamic (test for excess errors)

...
...

The errors are missing header :

 from 
gcc/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul1-7.c:4:
INSTALL/tc-up-231010-zicond-zfa-non-multilib/sysroot/usr/include/gnu/stubs.h:8:11: 
fatal error: gnu/stubs-ilp32.h: No such file or directory



When looking around, I stumbled upon commit
    d0bbecb1c41 "RISC-V: Add riscv_vector.h wrapper in testsuite to 
prevent pull in stdint.h from C library"


Which seems like a step in a right direction, but how does one ensure 
that the wrapper riscv_vector.h (containing stdint-gcc.h) is included by 
test vs. the default riscv_vector.h (which is more user facing and thus 
needs to include the system stdint.h)


P.S. I couldn't find the posting for above commit on gcc-patches ?

Thx,
-Vineet


On 10/5/23 16:45, Patrick O'Neill wrote:

stdint.h can be replaced with stdint-gcc.h to resolve some missing
system headers in non-multilib installations.

Tested using glibc rv32gcv and rv64gcv on r14-4381-g7eb5ce7f58e.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-1.h:
Replace stdint.h with stdint-gcc.h.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-1.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-1.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-1.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c: Ditto.
* gcc.target/riscv/rvv/autovec/partial/slp-8.c: Ditto.
* gcc.target/riscv/rvv/autovec/partial/slp-9.c: Ditto.
* gcc.target/riscv/rvv/autovec/pr111232.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/cvt-0.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/cvt-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls-vlmax/perm.h: Ditto.
* gcc.target/riscv/rvv/base/abi-call-args-4-run.c: Ditto.
* gcc.target/riscv/rvv/base/pr110119-2.c: Ditto.
* gcc.target/riscv/rvv/vsetvl/pr111255.c: Ditto.
* gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c: Ditto.

Signed-off-by: Patrick O'Neill 
---
Changes from v1:
- Avoid changing riscv_vector.h

Failures looked like this:
In file included from 
/riscv-gnu-toolchain/build/sysroot/usr/include/features.h:515,
  from 
/riscv-gnu-toolchain/build/sysroot/usr/include/bits/libc-header-start.h:33,
  from /riscv-gnu-toolchain/build/sysroot/usr/include/stdint.h:26,
  from 
/riscv-gnu-toolchain/build/lib/gcc/riscv32-unknown-linux-gnu/14.0.0/include/stdint.h:9,
  from 
/riscv-gnu-toolchain/build/build-gcc-linux-stage2/gcc/include/stdint.h:9,
  from 
/riscv-gnu-toolchain/build/build-gcc-linux-stage2/gcc/include/riscv_vector.h:28,
  from 
/riscv-gnu-toolchain/gcc/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul1-7.c:4:
/riscv-gnu-toolchain/build/sysroot/usr/include/gnu/stubs.h:8:11: fatal error: 
gnu/stubs-ilp32.h: No such file or directory

Resolves these failures on rv32gcv (non-multilib):
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c (test 
for 

[PATCH v2] c++: Fix compile-time-hog in cp_fold_immediate_r [PR111660]

2023-10-13 Thread Marek Polacek
On Thu, Oct 12, 2023 at 09:41:43PM -0400, Jason Merrill wrote:
> On 10/12/23 17:04, Marek Polacek wrote:
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > -- >8 --
> > My recent patch introducing cp_fold_immediate_r caused exponential
> > compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
> > case recursively walks the arms of a COND_EXPR, but after processing
> > both arms it doesn't end the walk; it proceeds to walk the
> > sub-expressions of the outermost COND_EXPR, triggering again walking
> > the arms of the nested COND_EXPR, and so on.  This patch brings the
> > compile time down to about 0m0.033s.
> > 
> > I've added some debug prints to make sure that the rest of cp_fold_r
> > is still performed as before.
> > 
> >  PR c++/111660
> > 
> > gcc/cp/ChangeLog:
> > 
> >  * cp-gimplify.cc (cp_fold_immediate_r) : Return
> >  integer_zero_node instead of break;.
> >  (cp_fold_immediate): Return true if cp_fold_immediate_r returned
> >  error_mark_node.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >  * g++.dg/cpp0x/hog1.C: New test.
> > ---
> >   gcc/cp/cp-gimplify.cc |  9 ++--
> >   gcc/testsuite/g++.dg/cpp0x/hog1.C | 77 +++
> >   2 files changed, 82 insertions(+), 4 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C
> > 
> > diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
> > index bdf6e5f98ff..ca622ca169a 100644
> > --- a/gcc/cp/cp-gimplify.cc
> > +++ b/gcc/cp/cp-gimplify.cc
> > @@ -1063,16 +1063,16 @@ cp_fold_immediate_r (tree *stmt_p, int 
> > *walk_subtrees, void *data_)
> > break;
> > if (TREE_OPERAND (stmt, 1)
> >   && cp_walk_tree (_OPERAND (stmt, 1), cp_fold_immediate_r, data,
> > -  nullptr))
> > +  nullptr) == error_mark_node)
> > return error_mark_node;
> > if (TREE_OPERAND (stmt, 2)
> >   && cp_walk_tree (_OPERAND (stmt, 2), cp_fold_immediate_r, data,
> > -  nullptr))
> > +  nullptr) == error_mark_node)
> > return error_mark_node;
> > /* We're done here.  Don't clear *walk_subtrees here though: we're 
> > called
> >  from cp_fold_r and we must let it recurse on the expression with
> >  cp_fold.  */
> > -  break;
> > +  return integer_zero_node;
> 
> I'm concerned this will end up missing something like
> 
> 1 ? 1 : ((1 ? 1 : 1), immediate())
> 
> as the integer_zero_node from the inner ?: will prevent walk_tree from
> looking any farther.

You are right.  The line above works as expected, but

  1 ? 1 : ((1 ? 1 : id (42)), id (i));

shows the problem (when the expression isn't used as an initializer).

> Maybe we want to handle COND_EXPR in cp_fold_r instead of here?

I hope this version is better.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
My recent patch introducing cp_fold_immediate_r caused exponential
compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
case recursively walks the arms of a COND_EXPR, but after processing
both arms it doesn't end the walk; it proceeds to walk the
sub-expressions of the outermost COND_EXPR, triggering again walking
the arms of the nested COND_EXPR, and so on.  This patch brings the
compile time down to about 0m0.033s.

The ff_fold_immediate flag is unused after this patch but since I'm
using it in the P2564 patch, I'm not removing it now.

PR c++/111660

gcc/cp/ChangeLog:

* cp-gimplify.cc (cp_fold_immediate_r) : Don't
handle it here.
(cp_fold_r): Handle COND_EXPR here.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/hog1.C: New test.
* g++.dg/cpp2a/consteval36.C: New test.
---
 gcc/cp/cp-gimplify.cc| 38 +---
 gcc/testsuite/g++.dg/cpp0x/hog1.C| 77 
 gcc/testsuite/g++.dg/cpp2a/consteval36.C | 18 ++
 3 files changed, 111 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/consteval36.C

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index bdf6e5f98ff..801cba141cb 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1052,27 +1052,6 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, 
void *data_)
 
   switch (TREE_CODE (stmt))
 {
-/* Unfortunately we must handle code like
-false ? bar () : 42
-   where we have to check bar too.  The cp_fold call in cp_fold_r could
-   fold the ?: into a constant before we see it here.  */
-case COND_EXPR:
-  /* If we are called from cp_fold_immediate, we don't need to worry about
-cp_fold folding away the COND_EXPR.  */
-  if (data->flags & ff_fold_immediate)
-   break;
-  if (TREE_OPERAND (stmt, 1)
- && cp_walk_tree (_OPERAND (stmt, 1), cp_fold_immediate_r, data,
-  nullptr))
-   

Re: [PATCH] combine: Fix handling of unsigned constants

2023-10-13 Thread Jeff Law




On 10/6/23 01:45, Stefan Schulze Frielinghaus wrote:

If a CONST_INT represents an integer of a mode with fewer bits than in
HOST_WIDE_INT, then the integer is sign extended.  For those two
optimizations touched by this patch, the integers of interest have only
the most significant bit set w.r.t their mode, therefore, they were sign
extended.  Thus in order to get the integer of interest, we have to chop
off the high bits.

Bootstrapped and regtested on x64, powerpc64le, and s390.  Ok for
mainline?

gcc/ChangeLog:

* combine.cc (simplify_compare_const): Fix handling of unsigned
constants.

OK
jeff


Re: [PATCH v2] RISC-V: Make xtheadcondmov-indirect tests robust against instruction reordering

2023-10-13 Thread Jeff Law




On 10/12/23 12:28, Kito Cheng wrote:

Sorry for the late comment after Jeff say ok, but I guess we may
consider add "-fno-schedule-insns -fno-schedule-insns2" to avoid
disturbing from schedule like some of our test case in
gcc/testsuite/gcc.target/riscv/rvv?
It wouldn't be a bad idea to bring more stability, particularly to tests 
which are expecting instructions in a specific order.  THat feels like 
it's likely a distinct change though.


jeff


Re: [PATCH] gimple-match: Do not try UNCOND optimization with COND_LEN.

2023-10-13 Thread Robin Dapp
> Why are the contents of this if statement wrong for COND_LEN?
> If the "else" value doesn't matter, then the masked form can use
> the "then" value for all elements.  I would have expected the same
> thing to be true of COND_LEN.

Right, that one was overly pessimistic.  Removed.

> But isn't the test whether res_op->code itself is an internal_function?
> In other words, shouldn't it just be:
> 
>   if (internal_fn_p (res_op->code)
> && internal_fn_len_index (as_internal_fn (res_op->code)) != -1)
>   return true;
> 
> maybe_resimplify_conditional_op should already have converted to an
> internal function where possible, and if combined_fn (res_op->code)
> does any extra conversion on the fly, that conversion won't be reflected
> in res_op.

I went through some of our test cases and believe most of the problems
are due to situations like the following:

In vect-cond-arith-2.c we have (on riscv)
  vect_neg_xi_14.4_23 = -vect_xi_13.3_22;
  vect_res_2.5_24 = .COND_LEN_ADD ({ -1, ... }, vect_res_1.0_17, 
vect_neg_xi_14.4_23, vect_res_1.0_17, _29, 0);

On aarch64 this is a situation that matches the VEC_COND_EXPR
simplification that I disabled with this patch.  We valueized
to _26 = vect_res_1.0_17 - vect_xi_13.3_22 and then create
vect_res_2.5_24 = VEC_COND_EXPR ;
This is later re-assembled into a COND_SUB.

As we have two masks or COND_LEN we cannot use a VEC_COND_EXPR to
achieve the same thing.  Would it be possible to create a COND_OP
directly instead, though?  I tried the following (not very polished
obviously):

-  new_op.set_op (VEC_COND_EXPR, res_op->type,
-res_op->cond.cond, res_op->ops[0],
-res_op->cond.else_value);
-  *res_op = new_op;
-  return gimple_resimplify3 (seq, res_op, valueize);
+  if (!res_op->cond.len)
+   {
+ new_op.set_op (VEC_COND_EXPR, res_op->type,
+res_op->cond.cond, res_op->ops[0],
+res_op->cond.else_value);
+ *res_op = new_op;
+ return gimple_resimplify3 (seq, res_op, valueize);
+   }
+  else if (seq && *seq && is_gimple_assign (*seq))
+   {
+ new_op.code = gimple_assign_rhs_code (*seq);
+ new_op.type = res_op->type;
+ new_op.num_ops = gimple_num_ops (*seq) - 1;
+ new_op.ops[0] = gimple_assign_rhs1 (*seq);
+ if (new_op.num_ops > 1)
+   new_op.ops[1] = gimple_assign_rhs2 (*seq);
+ if (new_op.num_ops > 2)
+   new_op.ops[2] = gimple_assign_rhs2 (*seq);
+
+ new_op.cond = res_op->cond;
+
+ gimple_match_op bla2;
+ if (convert_conditional_op (_op, ))
+   {
+ *res_op = bla2;
+ // SEQ should now be dead.
+ return true;
+   }
+   }

This would make the other hunk (check whether it was a LEN
and try to recreate it) redundant I hope.

I don't know enough about valueization, whether it's always
safe to do that and other implications.  On riscv this seems
to work, though and the other backends never go through the LEN
path.  If, however, this is a feasible direction it could also
be done for the non-LEN targets?

Regards
 Robin


Re: [PATCH] genemit: Split insn-emit.cc into ten files.

2023-10-13 Thread Robin Dapp


> Hmm why? The same callback you use to consume the listed arguments
> can be used to consume the list can it not? I may be wrong, but from
> what I remember the callback is called when main can't consume an
> argv value and it's allowed to eat all remaining input?

Ah, I see.  If that's possible, then surely it shouldn't be that large
a change and I can add it still.

Regards
 Robin


RE: [PATCH] genemit: Split insn-emit.cc into ten files.

2023-10-13 Thread Tamar Christina
> -Original Message-
> From: Robin Dapp 
> Sent: Friday, October 13, 2023 4:15 PM
> To: gcc-patches 
> Cc: rdapp@gmail.com; jeffreyalaw ; Tamar
> Christina ; rjie...@linux.alibaba.com
> Subject: Re: [PATCH] genemit: Split insn-emit.cc into ten files.
> 
> > Testsuite is unchanged on all but x86 where, strangely, I saw several
> > illegal instructions in the pch tests.  Those were not reproducible in
> > a second manual test suite run.  I'm just running another full
> > bootstrap and testsuite cycle with the latest trunk.
> 
> Follow-up on the pch tests.  The errors are an artifact of my testing.
> I usually build unpatched without bootstrap and patched with it, comparing
> the testsuite results.
> 
> When bootstrapping unpatched, the same errors occur.  When bootstrapping
> with --with-arch=native we essentially use a vpxor for a memset which is an
> illegal instruction on gc188 of the compile farm.  This might be a known bug
> but I haven't found something in bugzilla.
> 
> In total:  Bootstrap and testsuite unchanged on x86, aarch64 and power10.
> 
> Regarding Tamar's comment:
> 
> > I'll leave the review to Richard, but I think you should adopt the
> > same approach taken by the match.pd split, in that you provide the
> > list of files as an argument to the genemit instead of the number of
> > files.  And if no list is provided it outputs to stdout as it does today.
> 
> I think this would involve rewriting the argument handling for all gen* tools 
> (it
> is shared via gensupport).  Currently, I make use of the callback and just add
> two new options which helps limit the number of changes.  Is stdout so
> valuable from a debugging point of view that changing it would be
> prohibitive?  Of course it's a change but I usually grep through insn-emit.cc
> anyways and that would still be possible.

Debugging here refers to debugging the output of gen*, which usually one does
With small examples when modifying the tool itself.

> I think this would involve rewriting the argument handling for all gen* tools 
> (it
> is shared via gensupport).  Currently, I make use of the callback and just add
> two new options which helps limit the number of changes.  

Hmm why? The same callback you use to consume the listed arguments can be used 
to
consume the list can it not? I may be wrong, but from what I remember the 
callback
is called when main can't consume an argv value and it's allowed to eat all 
remaining input?

But I'll leave it up to Richard. Having to read multiple files to check a 
change to gen*
seems like a usability issue though.

Regards,
Tamar

> 
> Regards
>  Robin


  1   2   >