Repository: cython/cython
Pull request: Fix duplication of `IS_UNSIGNED_IMPL`
Closes #5356, Fixes #5302

Problem statement:
[BUG] Error at compilation with `overflowcheck(True)`.
### Describe the bug

I get an error at compilation when using `overflowcheck(True)` with 3.0.0b2.
Prior version worked well.

### Code to reproduce the behaviour:

```cython
%%cython --cplus

cimport cython

@cython.overflowcheck(True)
cdef size_t _mul_checked(size_t a, size_t b) except? -1:
    return a * b

def f(size_t[:] a, size_t[:] b):
    return _mul_checked(a.shape[0], b.shape[0])
```
Output:
```
Content of stderr:
/home/eric/.cache/ipython/cython/_cython_magic_7ec89a75959ed7157c2554d3336a3feedfc6cd9d.cpp:2382:8: error: redefinition of ‘struct __PYX_IS_UNSIGNED_IMPL<T>’
 2382 | struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);};
      |        ^~~~~~~~~~~~~~~~~~~~~~
/home/eric/.cache/ipython/cython/_cython_magic_7ec89a75959ed7157c2554d3336a3feedfc6cd9d.cpp:1329:8: note: previous definition of ‘struct __PYX_IS_UNSIGNED_IMPL<T>’
 1329 | struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);};
      |        ^~~~~~~~~~~~~~~~~~~~~~
```

### Expected behaviour

_No response_

### OS

Linux

### Python version

3.10.0

### Cython version

3.0.0b2

### Additional context

_No response_

Hints from issue discussion:
~It seems to be unintational that cython includes util twice~ It happend so `Buffer.c` and `Overflow.c` were included at the same time
but the easy fix of moving `__PYX_IS_UNSIGNED_IMPL ` into cython module util will help

Commit message: Use char buffers so bytearray would be accepted

Patch to review:
diff --git a/Cython/Utility/Buffer.c b/Cython/Utility/Buffer.c
index 7f4775e0248..be50d0f4807 100644
--- a/Cython/Utility/Buffer.c
+++ b/Cython/Utility/Buffer.c
@@ -53,14 +53,7 @@ static void __Pyx_RaiseBufferFallbackError(void) {
 
 /////////////// BufferFormatStructs.proto ///////////////
 //@proto_block: utility_code_proto_before_types
-
-#ifdef __cplusplus
-template<typename T>
-struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);};
-#define __PYX_IS_UNSIGNED(type) __PYX_IS_UNSIGNED_IMPL<type>::value
-#else
-#define __PYX_IS_UNSIGNED(type) (((type) -1) > 0)
-#endif
+//@requires: Overflow.c::Common
 
 /* Run-time type information about structs used with buffers */
 struct __Pyx_StructField_;
diff --git a/tests/run/buffer_n_overflowcheck_T5356.pyx b/tests/run/buffer_n_overflowcheck_T5356.pyx
new file mode 100644
index 00000000000..519a351810b
--- /dev/null
+++ b/tests/run/buffer_n_overflowcheck_T5356.pyx
@@ -0,0 +1,17 @@
+# mode: run
+# ticket: t5356
+
+cimport cython
+
+
+@cython.overflowcheck(True)
+cdef size_t _mul_checked(size_t a, size_t b) except? -1:
+    return a * b
+
+
+def f(unsigned char[:] a, unsigned char[:] b):
+    """
+    >>> f(memoryview(bytearray(b"12")), memoryview(bytearray(b"345")))
+    6
+    """
+    return _mul_checked(a.shape[0], b.shape[0])


Code review comments:
diff_hunk: @@ -53,14 +53,7 @@ static void __Pyx_RaiseBufferFallbackError(void) {
 
 /////////////// BufferFormatStructs.proto ///////////////
 //@proto_block: utility_code_proto_before_types
-
-#ifdef __cplusplus
-template<typename T>
-struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);};
-#define __PYX_IS_UNSIGNED(type) __PYX_IS_UNSIGNED_IMPL<type>::value
-#else
-#define __PYX_IS_UNSIGNED(type) (((type) -1) > 0)
-#endif
+//@requires: Overflow.c::Common
path: Cython/Utility/Buffer.c
text: @user1:
I don't think we need the `__Pyx_check_twos_complement()` part in `Common.c` for this. Thus, it might be worth extracting the unsigned checks into a new, separate utility code section and let both existing utility code sections depend on that.

@author:
You're right, I've seen this and thought that it probably won't cause any problems, but I'm not sure about it so this seems like a better option