[PATCH] Combine malloc + memset to calloc

2021-11-12 Thread Seija K. via Gcc-patches
I apologize this is the diff I meant to send:

diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index a2dd4895d48..25d9acda752 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -609,8 +609,7 @@ __gnat_setup_communication (struct TTY_Process**
process_out) /* output param */
 {
   struct TTY_Process* process;

-  process = (struct TTY_Process*)malloc (sizeof (struct TTY_Process));
-  ZeroMemory (process, sizeof (struct TTY_Process));
+  process = (struct TTY_Process*)calloc (1, sizeof (struct TTY_Process));
   *process_out = process;

   return 0;
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 1655a2fd765..2c895a2d9a9 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1307,8 +1307,7 @@ parse_args (prototype *protoptr)
   do {
 consume_whitespace ();
 int oldpos = pos;
-typelist *argentry = (typelist *) malloc (sizeof (typelist));
-memset (argentry, 0, sizeof *argentry);
+typelist *argentry = (typelist *) calloc (1, sizeof (typelist));
 typeinfo *argtype = &argentry->info;
 success = match_type (argtype, VOID_NOTOK);
 if (success)
diff --git a/gcc/d/dmd/ctfeexpr.c b/gcc/d/dmd/ctfeexpr.c
index a8e97833ad0..1acad62c371 100644
--- a/gcc/d/dmd/ctfeexpr.c
+++ b/gcc/d/dmd/ctfeexpr.c
@@ -1350,8 +1350,7 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression
*e2)
 if (es2->keys->length != dim)
 return 1;

-bool *used = (bool *)mem.xmalloc(sizeof(bool) * dim);
-memset(used, 0, sizeof(bool) * dim);
+bool *used = (bool *) mem.xcalloc (dim, sizeof(bool));

 for (size_t i = 0; i < dim; ++i)
 {
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 0cba95411a6..f5bff8b9441 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3081,9 +3081,16 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
  0).exists ())
  {
   unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
-  unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
-  memset (buf, (init_type == AUTO_INIT_PATTERN
- ? INIT_PATTERN_VALUE : 0), total_bytes);
+  unsigned char *buf;
+if (init_type == AUTO_INIT_PATTERN)
+  {
+buf = (unsigned char *) xmalloc (total_bytes);
+memset (buf, INIT_PATTERN_VALUE, total_bytes);
+  }
+else
+  {
+buf = (unsigned char *) xcalloc (1, total_bytes);
+  }
   tree itype = build_nonstandard_integer_type
  (total_bytes * BITS_PER_UNIT, 1);
   wide_int w = wi::from_buffer (buf, total_bytes);
diff --git a/libiberty/calloc.c b/libiberty/calloc.c
index f4bd27b1cd2..1ef4156d28a 100644
--- a/libiberty/calloc.c
+++ b/libiberty/calloc.c
@@ -17,7 +17,7 @@ Uses @code{malloc} to allocate storage for @var{nelem}
objects of

 /* For systems with larger pointers than ints, this must be declared.  */
 PTR malloc (size_t);
-void bzero (PTR, size_t);
+void memset (PTR, int, size_t);

 PTR
 calloc (size_t nelem, size_t elsize)
@@ -28,7 +28,7 @@ calloc (size_t nelem, size_t elsize)
 nelem = elsize = 1;

   ptr = malloc (nelem * elsize);
-  if (ptr) bzero (ptr, nelem * elsize);
+  if (ptr) memset (ptr, 0, nelem * elsize);

   return ptr;
 }
diff --git a/libiberty/partition.c b/libiberty/partition.c
index 81e5fc0f79a..75512d67258 100644
--- a/libiberty/partition.c
+++ b/libiberty/partition.c
@@ -146,8 +146,7 @@ partition_print (partition part, FILE *fp)
   int e;

   /* Flag the elements we've already printed.  */
-  done = (char *) xmalloc (num_elements);
-  memset (done, 0, num_elements);
+  done = (char *) xcalloc (num_elements, 1);

   /* A buffer used to sort elements in a class.  */
   class_elements = (int *) xmalloc (num_elements * sizeof (int));
diff --git a/libobjc/gc.c b/libobjc/gc.c
index 57895e61930..95a75f5cb2e 100644
--- a/libobjc/gc.c
+++ b/libobjc/gc.c
@@ -307,10 +307,9 @@ __objc_generate_gc_type_description (Class class)
  / sizeof (void *));
   size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
   mask = objc_atomic_malloc (size * sizeof (int));
-  memset (mask, 0, size * sizeof (int));

   class_structure_type = objc_atomic_malloc (type_size);
-  *class_structure_type = current = 0;
+  current = 0;
   __objc_class_structure_encoding (class, &class_structure_type,
&type_size, ¤t);
   if (current + 1 == type_size)


[PATCH] Combine malloc + memset to calloc

2021-11-12 Thread Seija K. via Gcc-patches
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index a2dd4895d48..25d9acda752 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -609,8 +609,7 @@ __gnat_setup_communication (struct TTY_Process**
process_out) /* output param */
 {
   struct TTY_Process* process;

-  process = (struct TTY_Process*)malloc (sizeof (struct TTY_Process));
-  ZeroMemory (process, sizeof (struct TTY_Process));
+  process = (struct TTY_Process*)calloc (1, sizeof (struct TTY_Process));
   *process_out = process;

   return 0;
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 1655a2fd765..2c895a2d9a9 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1307,8 +1307,7 @@ parse_args (prototype *protoptr)
   do {
 consume_whitespace ();
 int oldpos = pos;
-typelist *argentry = (typelist *) malloc (sizeof (typelist));
-memset (argentry, 0, sizeof *argentry);
+typelist *argentry = (typelist *) calloc (1, sizeof (typelist));
 typeinfo *argtype = &argentry->info;
 success = match_type (argtype, VOID_NOTOK);
 if (success)
diff --git a/gcc/d/dmd/ctfeexpr.c b/gcc/d/dmd/ctfeexpr.c
index a8e97833ad0..0086aceef84 100644
--- a/gcc/d/dmd/ctfeexpr.c
+++ b/gcc/d/dmd/ctfeexpr.c
@@ -1350,8 +1350,7 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression
*e2)
 if (es2->keys->length != dim)
 return 1;

-bool *used = (bool *)mem.xmalloc(sizeof(bool) * dim);
-memset(used, 0, sizeof(bool) * dim);
+bool *used = (bool *) mem.xcalloc(dim, sizeof(bool));

 for (size_t i = 0; i < dim; ++i)
 {
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 0cba95411a6..f5bff8b9441 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3081,9 +3081,16 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
  0).exists ())
  {
   unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
-  unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
-  memset (buf, (init_type == AUTO_INIT_PATTERN
- ? INIT_PATTERN_VALUE : 0), total_bytes);
+  unsigned char *buf;
+if (init_type == AUTO_INIT_PATTERN)
+  {
+buf = (unsigned char *) xmalloc (total_bytes);
+memset (buf, INIT_PATTERN_VALUE, total_bytes);
+  }
+else
+  {
+buf = (unsigned char *) xcalloc (1, total_bytes);
+  }
   tree itype = build_nonstandard_integer_type
  (total_bytes * BITS_PER_UNIT, 1);
   wide_int w = wi::from_buffer (buf, total_bytes);
diff --git a/libiberty/calloc.c b/libiberty/calloc.c
index f4bd27b1cd2..1ef4156d28a 100644
--- a/libiberty/calloc.c
+++ b/libiberty/calloc.c
@@ -17,7 +17,7 @@ Uses @code{malloc} to allocate storage for @var{nelem}
objects of

 /* For systems with larger pointers than ints, this must be declared.  */
 PTR malloc (size_t);
-void bzero (PTR, size_t);
+void memset (PTR, int, size_t);

 PTR
 calloc (size_t nelem, size_t elsize)
@@ -28,7 +28,7 @@ calloc (size_t nelem, size_t elsize)
 nelem = elsize = 1;

   ptr = malloc (nelem * elsize);
-  if (ptr) bzero (ptr, nelem * elsize);
+  if (ptr) memset (ptr, 0, nelem * elsize);

   return ptr;
 }
diff --git a/libiberty/partition.c b/libiberty/partition.c
index 81e5fc0f79a..75512d67258 100644
--- a/libiberty/partition.c
+++ b/libiberty/partition.c
@@ -146,8 +146,7 @@ partition_print (partition part, FILE *fp)
   int e;

   /* Flag the elements we've already printed.  */
-  done = (char *) xmalloc (num_elements);
-  memset (done, 0, num_elements);
+  done = (char *) xcalloc (num_elements, 1);

   /* A buffer used to sort elements in a class.  */
   class_elements = (int *) xmalloc (num_elements * sizeof (int));
diff --git a/libobjc/gc.c b/libobjc/gc.c
index 57895e61930..95a75f5cb2e 100644
--- a/libobjc/gc.c
+++ b/libobjc/gc.c
@@ -307,10 +307,9 @@ __objc_generate_gc_type_description (Class class)
  / sizeof (void *));
   size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
   mask = objc_atomic_malloc (size * sizeof (int));
-  memset (mask, 0, size * sizeof (int));

   class_structure_type = objc_atomic_malloc (type_size);
-  *class_structure_type = current = 0;
+  current = 0;
   __objc_class_structure_encoding (class, &class_structure_type,
&type_size, ¤t);
   if (current + 1 == type_size)


[PATCH] Combine malloc + memset to calloc

2021-11-12 Thread Seija K. via Gcc-patches
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index a2dd4895d48..25d9acda752 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -609,8 +609,7 @@ __gnat_setup_communication (struct TTY_Process**
process_out) /* output param */
 {
   struct TTY_Process* process;

-  process = (struct TTY_Process*)malloc (sizeof (struct TTY_Process));
-  ZeroMemory (process, sizeof (struct TTY_Process));
+  process = (struct TTY_Process*)calloc (1, sizeof (struct TTY_Process));
   *process_out = process;

   return 0;
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 1655a2fd765..2c895a2d9a9 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1307,8 +1307,7 @@ parse_args (prototype *protoptr)
   do {
 consume_whitespace ();
 int oldpos = pos;
-typelist *argentry = (typelist *) malloc (sizeof (typelist));
-memset (argentry, 0, sizeof *argentry);
+typelist *argentry = (typelist *) calloc (1, sizeof (typelist));
 typeinfo *argtype = &argentry->info;
 success = match_type (argtype, VOID_NOTOK);
 if (success)
diff --git a/gcc/d/dmd/ctfeexpr.c b/gcc/d/dmd/ctfeexpr.c
index a8e97833ad0..401ed748f43 100644
--- a/gcc/d/dmd/ctfeexpr.c
+++ b/gcc/d/dmd/ctfeexpr.c
@@ -1350,8 +1350,7 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression
*e2)
 if (es2->keys->length != dim)
 return 1;

-bool *used = (bool *)mem.xmalloc(sizeof(bool) * dim);
-memset(used, 0, sizeof(bool) * dim);
+bool *used = (bool *)mem.xcalloc(dim, sizeof(bool));

 for (size_t i = 0; i < dim; ++i)
 {
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 0cba95411a6..f5bff8b9441 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3081,9 +3081,16 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
  0).exists ())
  {
   unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
-  unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
-  memset (buf, (init_type == AUTO_INIT_PATTERN
- ? INIT_PATTERN_VALUE : 0), total_bytes);
+  unsigned char *buf;
+if (init_type == AUTO_INIT_PATTERN)
+  {
+buf = (unsigned char *) xmalloc (total_bytes);
+memset (buf, INIT_PATTERN_VALUE, total_bytes);
+  }
+else
+  {
+buf = (unsigned char *) xcalloc (1, total_bytes);
+  }
   tree itype = build_nonstandard_integer_type
  (total_bytes * BITS_PER_UNIT, 1);
   wide_int w = wi::from_buffer (buf, total_bytes);
diff --git a/libiberty/calloc.c b/libiberty/calloc.c
index f4bd27b1cd2..1ef4156d28a 100644
--- a/libiberty/calloc.c
+++ b/libiberty/calloc.c
@@ -17,7 +17,7 @@ Uses @code{malloc} to allocate storage for @var{nelem}
objects of

 /* For systems with larger pointers than ints, this must be declared.  */
 PTR malloc (size_t);
-void bzero (PTR, size_t);
+void memset (PTR, int, size_t);

 PTR
 calloc (size_t nelem, size_t elsize)
@@ -28,7 +28,7 @@ calloc (size_t nelem, size_t elsize)
 nelem = elsize = 1;

   ptr = malloc (nelem * elsize);
-  if (ptr) bzero (ptr, nelem * elsize);
+  if (ptr) memset (ptr, 0, nelem * elsize);

   return ptr;
 }
diff --git a/libiberty/partition.c b/libiberty/partition.c
index 81e5fc0f79a..75512d67258 100644
--- a/libiberty/partition.c
+++ b/libiberty/partition.c
@@ -146,8 +146,7 @@ partition_print (partition part, FILE *fp)
   int e;

   /* Flag the elements we've already printed.  */
-  done = (char *) xmalloc (num_elements);
-  memset (done, 0, num_elements);
+  done = (char *) xcalloc (num_elements, 1);

   /* A buffer used to sort elements in a class.  */
   class_elements = (int *) xmalloc (num_elements * sizeof (int));
diff --git a/libobjc/gc.c b/libobjc/gc.c
index 57895e61930..95a75f5cb2e 100644
--- a/libobjc/gc.c
+++ b/libobjc/gc.c
@@ -307,10 +307,9 @@ __objc_generate_gc_type_description (Class class)
  / sizeof (void *));
   size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
   mask = objc_atomic_malloc (size * sizeof (int));
-  memset (mask, 0, size * sizeof (int));

   class_structure_type = objc_atomic_malloc (type_size);
-  *class_structure_type = current = 0;
+  current = 0;
   __objc_class_structure_encoding (class, &class_structure_type,
&type_size, ¤t);
   if (current + 1 == type_size)


[PATCH] gcc: trans-mem.c (gate_tm_init): Return false if cfun->cfg is NULL

2021-06-14 Thread Seija K. via Gcc-patches
This is a patch to fix BUG 87162 by returning false if cfg is null.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87162

diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 1d4eb80620295..326e1c412465b 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -2099,6 +2099,9 @@ gate_tm_init (void)
   if (!flag_tm)
 return false;

+  if (!cfun->cfg)
+return false;
+
   calculate_dominance_info (CDI_DOMINATORS);
   bitmap_obstack_initialize (&tm_obstack);


[PATCH] testsuite : __attribute__((fallthrough)) with braces

2021-06-14 Thread Seija K. via Gcc-patches
diff --git a/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
b/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
index e8659e572ca6d..1f3ca4ac37acf 100644
--- a/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
+++ b/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
@@ -48,6 +48,13 @@ fn (int i)
   case 11:
 bar (1);
 __attribute__((fallthrough, unused)); /* { dg-warning "attribute
ignored" } */
+  case 12:
+  { bar (1);
+__attribute__((fallthrough));
+  }
+  case 13:
+  { bar (1);
+  } __attribute__((fallthrough));
   default:
 bar (99);
   }


Re: [PATCH] PR libstdc++/98842: Fixed Constraints on operator<=>(optional, U)

2021-06-13 Thread Seija K. via Gcc-patches
Awesome, thanks!

On Mon, Jun 7, 2021 at 11:30 AM Jonathan Wakely 
wrote:

> On Fri, 4 Jun 2021 at 21:41, Jonathan Wakely wrote:
> >
> > On Thu, 3 Jun 2021 at 17:27, Seija K. via Libstdc++ <
> libstd...@gcc.gnu.org>
> > wrote:
> >
> > > The original operator was underconstrained. _Up needs to fulfill
> > > compare_three_way_result,
> > > as mentioned in this bug report
> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842
> > >
> >
> > Thanks, I'll get the patch applied next week.
>
> The patch causes testsuite failures.
>
> I fixed it with the attached change instead, including a workaround
> for an apparent C++20 defect.
>
> Pushed to trunk so far.
>


[PATCH] libgcc libiberty: optimize and modernize standard string and memory functions

2021-06-03 Thread Seija K. via Gcc-patches
This patch optimizes and simplifies many of the standard string functions.

Since C99, some of the standard string functions have been changed to use
the restrict modifier.

diff --git a/libgcc/memcmp.c b/libgcc/memcmp.c
index 2348afe1d27f7..74195cf6baf13 100644
--- a/libgcc/memcmp.c
+++ b/libgcc/memcmp.c
@@ -7,10 +7,11 @@ memcmp (const void *str1, const void *str2, size_t count)
   const unsigned char *s1 = str1;
   const unsigned char *s2 = str2;

-  while (count-- > 0)
+  while (count--)
 {
-  if (*s1++ != *s2++)
- return s1[-1] < s2[-1] ? -1 : 1;
+  if (*s1 != *s2)
+ return *s1 < *s2 ? -1 : 1;
+  s1++, s2++;
 }
   return 0;
 }
diff --git a/libgcc/memcpy.c b/libgcc/memcpy.c
index 58b1e405627aa..616df78fd2969 100644
--- a/libgcc/memcpy.c
+++ b/libgcc/memcpy.c
@@ -2,7 +2,7 @@
 #include 

 void *
-memcpy (void *dest, const void *src, size_t len)
+memcpy (void * restrict dest, const void * restrict src, size_t len)
 {
   char *d = dest;
   const char *s = src;
diff --git a/libgcc/memset.c b/libgcc/memset.c
index 3e7025ee39443..b3b27cd63e12d 100644
--- a/libgcc/memset.c
+++ b/libgcc/memset.c
@@ -5,7 +5,7 @@ void *
 memset (void *dest, int val, size_t len)
 {
   unsigned char *ptr = dest;
-  while (len-- > 0)
-*ptr++ = val;
+  while (len--)
+*ptr++ = (unsigned char)val;
   return dest;
 }
diff --git a/libiberty/memchr.c b/libiberty/memchr.c
index 7448ab9e71c32..6f03e9c281108 100644
--- a/libiberty/memchr.c
+++ b/libiberty/memchr.c
@@ -23,7 +23,7 @@ memchr (register const PTR src_void, int c, size_t length)
 {
   const unsigned char *src = (const unsigned char *)src_void;

-  while (length-- > 0)
+  while (length--)
   {
 if (*src == c)
  return (PTR)src;
diff --git a/libiberty/memcmp.c b/libiberty/memcmp.c
index 37db60f38267a..f41b35a758cc4 100644
--- a/libiberty/memcmp.c
+++ b/libiberty/memcmp.c
@@ -27,8 +27,9 @@ memcmp (const PTR str1, const PTR str2, size_t count)

   while (count-- > 0)
 {
-  if (*s1++ != *s2++)
- return s1[-1] < s2[-1] ? -1 : 1;
+  if (*s1 != *s2)
+ return *s1 < *s2 ? -1 : 1;
+  s1++, s2++;
 }
   return 0;
 }
diff --git a/libiberty/memcpy.c b/libiberty/memcpy.c
index 7f67d0bd1f26c..d388ae7f3506b 100644
--- a/libiberty/memcpy.c
+++ b/libiberty/memcpy.c
@@ -19,7 +19,7 @@ Copies @var{length} bytes from memory region
@var{in} to region
 void bcopy (const void*, void*, size_t);

 PTR
-memcpy (PTR out, const PTR in, size_t length)
+memcpy (PTR restrict out, const PTR restrict in, size_t length)
 {
 bcopy(in, out, length);
 return out;
diff --git a/libiberty/mempcpy.c b/libiberty/mempcpy.c
index f4c624d4a3227..ac56eeaee0d5e 100644
--- a/libiberty/mempcpy.c
+++ b/libiberty/mempcpy.c
@@ -33,10 +33,10 @@ Copies @var{length} bytes from memory region
@var{in} to region
 #include 
 #include 

-extern PTR memcpy (PTR, const PTR, size_t);
+extern PTR memcpy (PTR restrict, const PTR restrict, size_t);

 PTR
-mempcpy (PTR dst, const PTR src, size_t len)
+mempcpy (PTR restrict dst, const PTR restrict src, size_t len)
 {
   return (char *) memcpy (dst, src, len) + len;
 }


[PATCH] libgcc: Fix _Unwind_Backtrace() for SEH

2021-06-03 Thread Seija K. via Gcc-patches
Forgot to assign to gcc_context.cfa and gcc_context.ra. Note this fix can
be backported to earlier editions of gcc as well

diff --git a/libgcc/unwind-seh.c b/libgcc/unwind-seh.c
index 8c6aade9a3b39..d40d16702a9e1 100644
--- a/libgcc/unwind-seh.c
+++ b/libgcc/unwind-seh.c
@@ -466,6 +466,9 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace,
&gcc_context.disp->HandlerData,
&gcc_context.disp->EstablisherFrame, NULL);

+  gcc_context.cfa = ms_context.Rsp;
+  gcc_context.ra = ms_context.Rip;
+
   /* Call trace function.  */
   if (trace (&gcc_context, trace_argument) != _URC_NO_REASON)
return _URC_FATAL_PHASE1_ERROR;


[PATCH] PR libstdc++/98842: Fixed Constraints on operator<=>(optional, U)

2021-06-03 Thread Seija K. via Gcc-patches
The original operator was underconstrained. _Up needs to fulfill
compare_three_way_result,
as mentioned in this bug report
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98842

diff --git a/libstdc++-v3/include/std/optional
b/libstdc++-v3/include/std/optional
index 8b9e038e6e510..9e61c1b2cbfbd 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -1234,7 +1234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return !__rhs || __lhs >= *__rhs; }

 #ifdef __cpp_lib_three_way_comparison
-  template
+  template _Up>
 constexpr compare_three_way_result_t<_Tp, _Up>
 operator<=>(const optional<_Tp>& __x, const _Up& __v)
 { return bool(__x) ? *__x <=> __v : strong_ordering::less; }