2023-02-20 20:21:59

by Vincent Dagonneau

[permalink] [raw]
Subject: [PATCH v4 0/4] tools/nolibc: Adding stdint.h, more integer types and tests

Hi,

This is version 5 of the patch to add stdint.h to nolibc. Previous
versions of this patch are available here:

* v4: https://lore.kernel.org/all/[email protected]/
* v3: https://lore.kernel.org/all/[email protected]/
* v2: https://lore.kernel.org/all/[email protected]/
* v1: https://lore.kernel.org/all/[email protected]/

This version includes the work done by Willy (see
https://lore.kernel.org/all/[email protected]/) on using
__LONG_MAX__ to calculate the max size of ssize_t, size_t, intptr_t,
uintptr_t and ptrdiff_t.

It also includes the '*fast*' types, although I have never seen them used
in the wild.

Thank you Willy for the review and the guidance!
Vincent.

Vincent Dagonneau (4):
tools/nolibc: Adding stdint.h
tools/nolibc: Adding integer types and integer limit macros
tools/nolibc: Enlarging column width of tests
tools/nolibc: Adds tests for the integer limits in stdint.h

tools/include/nolibc/Makefile | 4 +-
tools/include/nolibc/std.h | 15 +-
tools/include/nolibc/stdint.h | 84 +++++++++++
tools/testing/selftests/nolibc/nolibc-test.c | 139 ++++++++++++-------
4 files changed, 177 insertions(+), 65 deletions(-)
create mode 100644 tools/include/nolibc/stdint.h

--
2.39.1



2023-02-20 20:22:08

by Vincent Dagonneau

[permalink] [raw]
Subject: [PATCH v5 2/4] tools/nolibc: add integer types and integer limit macros

This commit adds some of the missing integer types to stdint.h and adds
limit macros (e.g. INTN_{MIN,MAX}).

The reference used for adding these types is
https://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html.

We rely on the compiler-defined __LONG_MAX__ to get the right limits for
ssize_t, size_t, intptr_t, uintptr_t and ptrdiff_t. This compiler
constant seem to have been defined at least since GCC 4.1.2 and clang
3.0.0 on x86_64. It is also defined on ARM (32&64), mips and RISC-V.

Note that the maximum size of size_t is implementation-defined (>65535),
in this case I chose to go with unsigned long on all platforms since
unsigned long == unsigned int on all the platforms we care about. Note
that the kernel uses either unsigned int or unsigned long in
linux/include/uapi/asm-generic/posix_types.h. These should be equivalent
for the plaforms we are targeting.

Also note that the 'fast*' flavor of the types have been chosen to be
always 1 byte for '*fast8*' and always long (a.k.a. size_t/ssize_t) for
the other variants. I have never seen the 'fast*' types in use in the wild
but that seems to be what glibc does.

Signed-off-by: Vincent Dagonneau <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
tools/include/nolibc/stdint.h | 77 +++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)

diff --git a/tools/include/nolibc/stdint.h b/tools/include/nolibc/stdint.h
index 4ba264031df9..f7179a583f61 100644
--- a/tools/include/nolibc/stdint.h
+++ b/tools/include/nolibc/stdint.h
@@ -21,4 +21,81 @@ typedef unsigned long uintptr_t;
typedef signed long intptr_t;
typedef signed long ptrdiff_t;

+typedef int8_t int_least8_t;
+typedef uint8_t uint_least8_t;
+typedef int16_t int_least16_t;
+typedef uint16_t uint_least16_t;
+typedef int32_t int_least32_t;
+typedef uint32_t uint_least32_t;
+typedef int64_t int_least64_t;
+typedef uint64_t uint_least64_t;
+
+typedef int8_t int_fast8_t;
+typedef uint8_t uint_fast8_t;
+typedef ssize_t int_fast16_t;
+typedef size_t uint_fast16_t;
+typedef ssize_t int_fast32_t;
+typedef size_t uint_fast32_t;
+typedef ssize_t int_fast64_t;
+typedef size_t uint_fast64_t;
+
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+/* limits of integral types */
+
+#define INT8_MIN (-128)
+#define INT16_MIN (-32767-1)
+#define INT32_MIN (-2147483647-1)
+#define INT64_MIN (-9223372036854775807LL-1)
+
+#define INT8_MAX (127)
+#define INT16_MAX (32767)
+#define INT32_MAX (2147483647)
+#define INT64_MAX (9223372036854775807LL)
+
+#define UINT8_MAX (255)
+#define UINT16_MAX (65535)
+#define UINT32_MAX (4294967295U)
+#define UINT64_MAX (18446744073709551615ULL)
+
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST64_MIN INT64_MIN
+
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MAX INT64_MAX
+
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define SIZE_MAX ((size_t)(__LONG_MAX__) * 2 + 1)
+#define SSIZE_MIN (-__LONG_MAX__ - 1)
+#define SSIZE_MAX __LONG_MAX__
+#define INTPTR_MIN SSIZE_MIN
+#define INTPTR_MAX SSIZE_MAX
+#define PTRDIFF_MIN SSIZE_MIN
+#define PTRDIFF_MAX SSIZE_MAX
+#define UINTPTR_MAX SIZE_MAX
+
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST16_MIN SSIZE_MIN
+#define INT_FAST32_MIN SSIZE_MIN
+#define INT_FAST64_MIN SSIZE_MIN
+
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MAX SSIZE_MAX
+#define INT_FAST32_MAX SSIZE_MAX
+#define INT_FAST64_MAX SSIZE_MAX
+
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX SIZE_MAX
+#define UINT_FAST32_MAX SIZE_MAX
+#define UINT_FAST64_MAX SIZE_MAX
+
#endif /* _NOLIBC_STDINT_H */
--
2.39.2


2023-02-20 20:22:20

by Vincent Dagonneau

[permalink] [raw]
Subject: [PATCH v5 1/4] tools/nolibc: add stdint.h

Nolibc works fine for small and limited program however most program
expect integer types to be defined in stdint.h rather than std.h.

This is a quick fix that moves the existing integer definitions in std.h
to stdint.h.

Signed-off-by: Vincent Dagonneau <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
tools/include/nolibc/Makefile | 4 ++--
tools/include/nolibc/std.h | 15 +--------------
tools/include/nolibc/stdint.h | 24 ++++++++++++++++++++++++
3 files changed, 27 insertions(+), 16 deletions(-)
create mode 100644 tools/include/nolibc/stdint.h

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index cfd06764b5ae..ec57d3932506 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -25,8 +25,8 @@ endif

nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
arch_file := arch-$(nolibc_arch).h
-all_files := ctype.h errno.h nolibc.h signal.h std.h stdio.h stdlib.h string.h \
- sys.h time.h types.h unistd.h
+all_files := ctype.h errno.h nolibc.h signal.h std.h stdint.h stdio.h stdlib.h \
+ string.h sys.h time.h types.h unistd.h

# install all headers needed to support a bare-metal compiler
all: headers
diff --git a/tools/include/nolibc/std.h b/tools/include/nolibc/std.h
index 1747ae125392..933bc0be7e1c 100644
--- a/tools/include/nolibc/std.h
+++ b/tools/include/nolibc/std.h
@@ -18,20 +18,7 @@
#define NULL ((void *)0)
#endif

-/* stdint types */
-typedef unsigned char uint8_t;
-typedef signed char int8_t;
-typedef unsigned short uint16_t;
-typedef signed short int16_t;
-typedef unsigned int uint32_t;
-typedef signed int int32_t;
-typedef unsigned long long uint64_t;
-typedef signed long long int64_t;
-typedef unsigned long size_t;
-typedef signed long ssize_t;
-typedef unsigned long uintptr_t;
-typedef signed long intptr_t;
-typedef signed long ptrdiff_t;
+#include "stdint.h"

/* those are commonly provided by sys/types.h */
typedef unsigned int dev_t;
diff --git a/tools/include/nolibc/stdint.h b/tools/include/nolibc/stdint.h
new file mode 100644
index 000000000000..4ba264031df9
--- /dev/null
+++ b/tools/include/nolibc/stdint.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Standard definitions and types for NOLIBC
+ * Copyright (C) 2023 Vincent Dagonneau <[email protected]>
+ */
+
+#ifndef _NOLIBC_STDINT_H
+#define _NOLIBC_STDINT_H
+
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+typedef unsigned long size_t;
+typedef signed long ssize_t;
+typedef unsigned long uintptr_t;
+typedef signed long intptr_t;
+typedef signed long ptrdiff_t;
+
+#endif /* _NOLIBC_STDINT_H */
--
2.39.2


2023-02-20 20:22:31

by Vincent Dagonneau

[permalink] [raw]
Subject: [PATCH v5 4/4] tools/nolibc: add tests for the integer limits in stdint.h

This commit adds tests for the limits added in a previous commit. The
limits are defined in decimal in stdint.h and as hexadecimal in the
tests (e.g. 0x7f = 127 or 0x80 = -128). Hopefully it catches some of the
most egregious mistakes.

As we rely on the compiler to provide __SIZEOF_LONG__, we also test
whether it is defined.

Signed-off-by: Vincent Dagonneau <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 62 +++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 882140508d56..ceaf60075331 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -561,7 +561,67 @@ int run_syscall(int min, int max)
CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
- case __LINE__:
+ CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break;
+ CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break;
+ CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break;
+ CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break;
+ CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break;
+ CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break;
+ CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break;
+ CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break;
+ CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break;
+ CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break;
+ CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break;
+ CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break;
+ CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break;
+ CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break;
+ CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break;
+ CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break;
+ CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break;
+ CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break;
+ CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break;
+ CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break;
+ CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break;
+ CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
+ CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
+ CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
+#if __SIZEOF_LONG__ == 8
+ CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break;
+ CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break;
+ CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break;
+ CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) 0x7fffffffffffffffLL); break;
+ CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) 0x8000000000000000LL); break;
+ CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) 0xffffffffffffffffULL); break;
+ CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) 0x7fffffffffffffffLL); break;
+ CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) 0x8000000000000000LL); break;
+ CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) 0xffffffffffffffffULL); break;
+ CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x8000000000000000LL); break;
+ CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffffffffffffLL); break;
+ CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffffffffffULL); break;
+ CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x8000000000000000LL); break;
+ CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffffffffffffLL); break;
+ CASE_TEST(limit_ssize_min); EXPECT_EQ(1, SSIZE_MIN, (ssize_t) 0x8000000000000000LL); break;
+ CASE_TEST(limit_ssize_max); EXPECT_EQ(1, SSIZE_MAX, (ssize_t) 0x7fffffffffffffffLL); break;
+ CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffffffffffULL); break;
+#elif __SIZEOF_LONG__ == 4
+ CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) 0x7fffffff); break;
+ CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) 0x80000000); break;
+ CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) 0xffffffffU); break;
+ CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) 0x7fffffff); break;
+ CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) 0x80000000); break;
+ CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) 0xffffffffU); break;
+ CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x80000000); break;
+ CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffff); break;
+ CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffU); break;
+ CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x80000000); break;
+ CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffff); break;
+ CASE_TEST(limit_ssize_min); EXPECT_EQ(1, SSIZE_MIN, (ssize_t) 0x80000000); break;
+ CASE_TEST(limit_ssize_max); EXPECT_EQ(1, SSIZE_MAX, (ssize_t) 0x7fffffff); break;
+ CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffU); break;
+#else
+# warning "__SIZEOF_LONG__ is undefined"
+#endif /* __SIZEOF_LONG__ */
+ case __LINE__:
return ret; /* must be last */
/* note: do not set any defaults so as to permit holes above */
}
--
2.39.2


2023-02-20 20:31:07

by Vincent Dagonneau

[permalink] [raw]
Subject: [PATCH v5 3/4] tools/nolibc: enlarge column width of tests

This commit enlarges the column width from 40 to 64 characters to make
room for longer tests

Signed-off-by: Vincent Dagonneau <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 96 ++++++++++----------
1 file changed, 48 insertions(+), 48 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index c4a0c915139c..882140508d56 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -130,111 +130,111 @@ static int pad_spc(int llen, int cnt, const char *fmt, ...)
*/

#define EXPECT_ZR(cond, expr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0)

static int expect_zr(int expr, int llen)
{
int ret = !(expr == 0);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_NZ(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0)

static int expect_nz(int expr, int llen)
{
int ret = !(expr != 0);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_EQ(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0)

-static int expect_eq(int expr, int llen, int val)
+static int expect_eq(uint64_t expr, int llen, uint64_t val)
{
int ret = !(expr == val);

- llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ llen += printf(" = %lld ", expr);
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_NE(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0)

static int expect_ne(int expr, int llen, int val)
{
int ret = !(expr != val);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_GE(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0)

static int expect_ge(int expr, int llen, int val)
{
int ret = !(expr >= val);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_GT(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0)

static int expect_gt(int expr, int llen, int val)
{
int ret = !(expr > val);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_LE(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0)

static int expect_le(int expr, int llen, int val)
{
int ret = !(expr <= val);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_LT(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0)

static int expect_lt(int expr, int llen, int val)
{
int ret = !(expr < val);

llen += printf(" = %d ", expr);
- pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
return ret;
}


#define EXPECT_SYSZR(cond, expr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0)

static int expect_syszr(int expr, int llen)
{
@@ -243,17 +243,17 @@ static int expect_syszr(int expr, int llen)
if (expr) {
ret = 1;
llen += printf(" = %d %s ", expr, errorname(errno));
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
llen += printf(" = %d ", expr);
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_SYSEQ(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0)

static int expect_syseq(int expr, int llen, int val)
{
@@ -262,17 +262,17 @@ static int expect_syseq(int expr, int llen, int val)
if (expr != val) {
ret = 1;
llen += printf(" = %d %s ", expr, errorname(errno));
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
llen += printf(" = %d ", expr);
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_SYSNE(cond, expr, val) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0)

static int expect_sysne(int expr, int llen, int val)
{
@@ -281,17 +281,17 @@ static int expect_sysne(int expr, int llen, int val)
if (expr == val) {
ret = 1;
llen += printf(" = %d %s ", expr, errorname(errno));
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
llen += printf(" = %d ", expr);
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_SYSER(cond, expr, expret, experr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0)

static int expect_syserr(int expr, int expret, int experr, int llen)
{
@@ -302,16 +302,16 @@ static int expect_syserr(int expr, int expret, int experr, int llen)
if (expr != expret || _errno != experr) {
ret = 1;
llen += printf(" != (%d %s) ", expret, errorname(experr));
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_PTRZR(cond, expr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0)

static int expect_ptrzr(const void *expr, int llen)
{
@@ -320,16 +320,16 @@ static int expect_ptrzr(const void *expr, int llen)
llen += printf(" = <%p> ", expr);
if (expr) {
ret = 1;
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_PTRNZ(cond, expr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0)

static int expect_ptrnz(const void *expr, int llen)
{
@@ -338,16 +338,16 @@ static int expect_ptrnz(const void *expr, int llen)
llen += printf(" = <%p> ", expr);
if (!expr) {
ret = 1;
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_STRZR(cond, expr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)

static int expect_strzr(const char *expr, int llen)
{
@@ -356,16 +356,16 @@ static int expect_strzr(const char *expr, int llen)
llen += printf(" = <%s> ", expr);
if (expr) {
ret = 1;
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_STRNZ(cond, expr) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0)

static int expect_strnz(const char *expr, int llen)
{
@@ -374,16 +374,16 @@ static int expect_strnz(const char *expr, int llen)
llen += printf(" = <%s> ", expr);
if (!expr) {
ret = 1;
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_STREQ(cond, expr, cmp) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0)

static int expect_streq(const char *expr, int llen, const char *cmp)
{
@@ -392,16 +392,16 @@ static int expect_streq(const char *expr, int llen, const char *cmp)
llen += printf(" = <%s> ", expr);
if (strcmp(expr, cmp) != 0) {
ret = 1;
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}


#define EXPECT_STRNE(cond, expr, cmp) \
- do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0)
+ do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0)

static int expect_strne(const char *expr, int llen, const char *cmp)
{
@@ -410,9 +410,9 @@ static int expect_strne(const char *expr, int llen, const char *cmp)
llen += printf(" = <%s> ", expr);
if (strcmp(expr, cmp) == 0) {
ret = 1;
- llen += pad_spc(llen, 40, "[FAIL]\n");
+ llen += pad_spc(llen, 64, "[FAIL]\n");
} else {
- llen += pad_spc(llen, 40, " [OK]\n");
+ llen += pad_spc(llen, 64, " [OK]\n");
}
return ret;
}
--
2.39.2


2023-02-21 17:34:10

by Thomas Weißschuh

[permalink] [raw]
Subject: Re: [PATCH v5 4/4] tools/nolibc: add tests for the integer limits in stdint.h

I think some comments from my last review got lost; see inline.

On Mon, Feb 20, 2023 at 03:20:10PM -0500, Vincent Dagonneau wrote:
> This commit adds tests for the limits added in a previous commit. The
> limits are defined in decimal in stdint.h and as hexadecimal in the
> tests (e.g. 0x7f = 127 or 0x80 = -128). Hopefully it catches some of the
> most egregious mistakes.
>
> As we rely on the compiler to provide __SIZEOF_LONG__, we also test
> whether it is defined.
>
> Signed-off-by: Vincent Dagonneau <[email protected]>
> Signed-off-by: Willy Tarreau <[email protected]>
> ---
> tools/testing/selftests/nolibc/nolibc-test.c | 62 +++++++++++++++++++-
> 1 file changed, 61 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index 882140508d56..ceaf60075331 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -561,7 +561,67 @@ int run_syscall(int min, int max)
> CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
> CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
> CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
> - case __LINE__:
> + CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break;
> + CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break;
> + CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break;
> + CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break;
> + CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break;
> + CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break;
> + CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break;
> + CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break;
> + CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break;
> + CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break;
> + CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break;
> + CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break;
> + CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break;
> + CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break;
> + CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break;
> + CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break;
> + CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break;
> + CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break;
> + CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break;
> + CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break;
> + CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break;
> + CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
> + CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
> + CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
> +#if __SIZEOF_LONG__ == 8
> + CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break;
> + CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break;
> + CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break;

The _least64 tests should also apply to 32bit, no?
And moved before the _fast8 tests.

> + CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) 0x7fffffffffffffffLL); break;
> + CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) 0x8000000000000000LL); break;
> + CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) 0xffffffffffffffffULL); break;
> + CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) 0x7fffffffffffffffLL); break;
> + CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) 0x8000000000000000LL); break;
> + CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) 0xffffffffffffffffULL); break;
> + CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x8000000000000000LL); break;
> + CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffffffffffffLL); break;
> + CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffffffffffULL); break;
> + CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x8000000000000000LL); break;
> + CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffffffffffffLL); break;
> + CASE_TEST(limit_ssize_min); EXPECT_EQ(1, SSIZE_MIN, (ssize_t) 0x8000000000000000LL); break;
> + CASE_TEST(limit_ssize_max); EXPECT_EQ(1, SSIZE_MAX, (ssize_t) 0x7fffffffffffffffLL); break;
> + CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffffffffffULL); break;
> +#elif __SIZEOF_LONG__ == 4
> + CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) 0x7fffffff); break;
> + CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) 0x80000000); break;
> + CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) 0xffffffffU); break;
> + CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) 0x7fffffff); break;
> + CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) 0x80000000); break;
> + CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) 0xffffffffU); break;
> + CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x80000000); break;
> + CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffff); break;
> + CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffU); break;
> + CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x80000000); break;
> + CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffff); break;
> + CASE_TEST(limit_ssize_min); EXPECT_EQ(1, SSIZE_MIN, (ssize_t) 0x80000000); break;
> + CASE_TEST(limit_ssize_max); EXPECT_EQ(1, SSIZE_MAX, (ssize_t) 0x7fffffff); break;
> + CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffU); break;
> +#else
> +# warning "__SIZEOF_LONG__ is undefined"
> +#endif /* __SIZEOF_LONG__ */
> + case __LINE__:

The case __LINE__ still seems to be misindented, at least different
than before.

> return ret; /* must be last */
> /* note: do not set any defaults so as to permit holes above */
> }
> --
> 2.39.2

2023-02-21 17:40:12

by Thomas Weißschuh

[permalink] [raw]
Subject: Re: [PATCH v5 2/4] tools/nolibc: add integer types and integer limit macros

On Mon, Feb 20, 2023 at 03:20:08PM -0500, Vincent Dagonneau wrote:
> This commit adds some of the missing integer types to stdint.h and adds
> limit macros (e.g. INTN_{MIN,MAX}).
>
> The reference used for adding these types is
> https://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html.
>
> We rely on the compiler-defined __LONG_MAX__ to get the right limits for
> ssize_t, size_t, intptr_t, uintptr_t and ptrdiff_t. This compiler
> constant seem to have been defined at least since GCC 4.1.2 and clang
> 3.0.0 on x86_64. It is also defined on ARM (32&64), mips and RISC-V.
>
> Note that the maximum size of size_t is implementation-defined (>65535),
> in this case I chose to go with unsigned long on all platforms since
> unsigned long == unsigned int on all the platforms we care about. Note
> that the kernel uses either unsigned int or unsigned long in
> linux/include/uapi/asm-generic/posix_types.h. These should be equivalent
> for the plaforms we are targeting.
>
> Also note that the 'fast*' flavor of the types have been chosen to be
> always 1 byte for '*fast8*' and always long (a.k.a. size_t/ssize_t) for
> the other variants. I have never seen the 'fast*' types in use in the wild
> but that seems to be what glibc does.
>
> Signed-off-by: Vincent Dagonneau <[email protected]>
> Signed-off-by: Willy Tarreau <[email protected]>
> ---
> tools/include/nolibc/stdint.h | 77 +++++++++++++++++++++++++++++++++++
> 1 file changed, 77 insertions(+)
>
> diff --git a/tools/include/nolibc/stdint.h b/tools/include/nolibc/stdint.h
> index 4ba264031df9..f7179a583f61 100644
> --- a/tools/include/nolibc/stdint.h
> +++ b/tools/include/nolibc/stdint.h
> @@ -21,4 +21,81 @@ typedef unsigned long uintptr_t;
> typedef signed long intptr_t;
> typedef signed long ptrdiff_t;
>
> +typedef int8_t int_least8_t;
> +typedef uint8_t uint_least8_t;
> +typedef int16_t int_least16_t;
> +typedef uint16_t uint_least16_t;
> +typedef int32_t int_least32_t;
> +typedef uint32_t uint_least32_t;
> +typedef int64_t int_least64_t;
> +typedef uint64_t uint_least64_t;
> +
> +typedef int8_t int_fast8_t;
> +typedef uint8_t uint_fast8_t;
> +typedef ssize_t int_fast16_t;
> +typedef size_t uint_fast16_t;
> +typedef ssize_t int_fast32_t;
> +typedef size_t uint_fast32_t;
> +typedef ssize_t int_fast64_t;
> +typedef size_t uint_fast64_t;
> +
> +typedef int64_t intmax_t;
> +typedef uint64_t uintmax_t;
> +
> +/* limits of integral types */
> +
> +#define INT8_MIN (-128)
> +#define INT16_MIN (-32767-1)
> +#define INT32_MIN (-2147483647-1)
> +#define INT64_MIN (-9223372036854775807LL-1)
> +
> +#define INT8_MAX (127)
> +#define INT16_MAX (32767)
> +#define INT32_MAX (2147483647)
> +#define INT64_MAX (9223372036854775807LL)
> +
> +#define UINT8_MAX (255)
> +#define UINT16_MAX (65535)
> +#define UINT32_MAX (4294967295U)
> +#define UINT64_MAX (18446744073709551615ULL)
> +
> +#define INT_LEAST8_MIN INT8_MIN
> +#define INT_LEAST16_MIN INT16_MIN
> +#define INT_LEAST32_MIN INT32_MIN
> +#define INT_LEAST64_MIN INT64_MIN
> +
> +#define INT_LEAST8_MAX INT8_MAX
> +#define INT_LEAST16_MAX INT16_MAX
> +#define INT_LEAST32_MAX INT32_MAX
> +#define INT_LEAST64_MAX INT64_MAX
> +
> +#define UINT_LEAST8_MAX UINT8_MAX
> +#define UINT_LEAST16_MAX UINT16_MAX
> +#define UINT_LEAST32_MAX UINT32_MAX
> +#define UINT_LEAST64_MAX UINT64_MAX
> +
> +#define SIZE_MAX ((size_t)(__LONG_MAX__) * 2 + 1)
> +#define SSIZE_MIN (-__LONG_MAX__ - 1)

SSIZE_MIN is not defined by a standard.
It also doesn't really make sense to have, as ssize_t is only supposed
to store [-1,SSIZE_MAX].

> +#define SSIZE_MAX __LONG_MAX__

Apparently SSIZE_MAX can also defined via the compilers <limits.h> as
used by nolibc-test.c leading to a warning.
Maybe wrap it in #ifndef SSIZE_MAX.

In file included from sysroot/x86/include/std.h:21,
from sysroot/x86/include/stdio.h:12,
from nolibc-test.c:15:
sysroot/x86/include/stdint.h:79: warning: "SSIZE_MAX" redefined
79 | #define SSIZE_MAX __LONG_MAX__
|
In file included from /usr/include/limits.h:195,
from /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed/limits.h:203,
from /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed/syslimits.h:7,
from /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed/limits.h:34,
from nolibc-test.c:6:
/usr/include/bits/posix1_lim.h:169: note: this is the location of the previous definition
169 | # define SSIZE_MAX LONG_MAX
|

> +#define INTPTR_MIN SSIZE_MIN
> +#define INTPTR_MAX SSIZE_MAX
> +#define PTRDIFF_MIN SSIZE_MIN
> +#define PTRDIFF_MAX SSIZE_MAX
> +#define UINTPTR_MAX SIZE_MAX
> +
> +#define INT_FAST8_MIN INT8_MIN
> +#define INT_FAST16_MIN SSIZE_MIN
> +#define INT_FAST32_MIN SSIZE_MIN
> +#define INT_FAST64_MIN SSIZE_MIN
> +
> +#define INT_FAST8_MAX INT8_MAX
> +#define INT_FAST16_MAX SSIZE_MAX
> +#define INT_FAST32_MAX SSIZE_MAX
> +#define INT_FAST64_MAX SSIZE_MAX
> +
> +#define UINT_FAST8_MAX UINT8_MAX
> +#define UINT_FAST16_MAX SIZE_MAX
> +#define UINT_FAST32_MAX SIZE_MAX
> +#define UINT_FAST64_MAX SIZE_MAX

Alignment of values within lines is inconsistent.

> +
> #endif /* _NOLIBC_STDINT_H */
> --
> 2.39.2
>

2023-02-21 17:44:58

by Willy Tarreau

[permalink] [raw]
Subject: Re: [PATCH v5 4/4] tools/nolibc: add tests for the integer limits in stdint.h

On Tue, Feb 21, 2023 at 05:34:01PM +0000, Thomas Wei?schuh wrote:
> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index 882140508d56..ceaf60075331 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > @@ -561,7 +561,67 @@ int run_syscall(int min, int max)
> > CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
> > CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
> > CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
> > - case __LINE__:
> > + CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break;
> > + CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break;
> > + CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break;
> > + CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break;
> > + CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break;
> > + CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break;
> > + CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break;
> > + CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break;
> > + CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break;
> > + CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break;
> > + CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break;
> > + CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break;
> > + CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break;
> > + CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break;
> > + CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break;
> > + CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break;
> > + CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break;
> > + CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break;
> > + CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break;
> > + CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break;
> > + CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break;
> > + CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
> > + CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
> > + CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
> > +#if __SIZEOF_LONG__ == 8
> > + CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break;
> > + CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break;
> > + CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break;
>
> The _least64 tests should also apply to 32bit, no?
> And moved before the _fast8 tests.

Just thinking loud, it seems to me that all of these _least/_fast ones
can in fact be reliably checked against INT_*, LONG_* and SIZE_MAX. Given
that these ones are already tested, maybe we can just get rid of the ifdef
around all the least/fast and map them to the ones we already test ? That
would possibly remove duplication and make it more readable.

Willy

2023-02-23 00:35:53

by Vincent Dagonneau

[permalink] [raw]
Subject: Re: [PATCH v5 2/4] tools/nolibc: add integer types and integer limit macros

Hi Thomas,

On Tue, Feb 21, 2023, at 12:40, Thomas Weißschuh wrote:
> On Mon, Feb 20, 2023 at 03:20:08PM -0500, Vincent Dagonneau wrote:
>> This commit adds some of the missing integer types to stdint.h and adds
>> limit macros (e.g. INTN_{MIN,MAX}).
>>
>> The reference used for adding these types is
>> https://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html.
>>
>> We rely on the compiler-defined __LONG_MAX__ to get the right limits for
>> ssize_t, size_t, intptr_t, uintptr_t and ptrdiff_t. This compiler
>> constant seem to have been defined at least since GCC 4.1.2 and clang
>> 3.0.0 on x86_64. It is also defined on ARM (32&64), mips and RISC-V.
>>
>> Note that the maximum size of size_t is implementation-defined (>65535),
>> in this case I chose to go with unsigned long on all platforms since
>> unsigned long == unsigned int on all the platforms we care about. Note
>> that the kernel uses either unsigned int or unsigned long in
>> linux/include/uapi/asm-generic/posix_types.h. These should be equivalent
>> for the plaforms we are targeting.
>>
>> Also note that the 'fast*' flavor of the types have been chosen to be
>> always 1 byte for '*fast8*' and always long (a.k.a. size_t/ssize_t) for
>> the other variants. I have never seen the 'fast*' types in use in the wild
>> but that seems to be what glibc does.
>>
>> Signed-off-by: Vincent Dagonneau <[email protected]>
>> Signed-off-by: Willy Tarreau <[email protected]>
>> ---
>> tools/include/nolibc/stdint.h | 77 +++++++++++++++++++++++++++++++++++
>> 1 file changed, 77 insertions(+)
>>
>> diff --git a/tools/include/nolibc/stdint.h b/tools/include/nolibc/stdint.h
>> index 4ba264031df9..f7179a583f61 100644
>> --- a/tools/include/nolibc/stdint.h
>> +++ b/tools/include/nolibc/stdint.h
>> @@ -21,4 +21,81 @@ typedef unsigned long uintptr_t;
>> typedef signed long intptr_t;
>> typedef signed long ptrdiff_t;
>>
>> +typedef int8_t int_least8_t;
>> +typedef uint8_t uint_least8_t;
>> +typedef int16_t int_least16_t;
>> +typedef uint16_t uint_least16_t;
>> +typedef int32_t int_least32_t;
>> +typedef uint32_t uint_least32_t;
>> +typedef int64_t int_least64_t;
>> +typedef uint64_t uint_least64_t;
>> +
>> +typedef int8_t int_fast8_t;
>> +typedef uint8_t uint_fast8_t;
>> +typedef ssize_t int_fast16_t;
>> +typedef size_t uint_fast16_t;
>> +typedef ssize_t int_fast32_t;
>> +typedef size_t uint_fast32_t;
>> +typedef ssize_t int_fast64_t;
>> +typedef size_t uint_fast64_t;
>> +
>> +typedef int64_t intmax_t;
>> +typedef uint64_t uintmax_t;
>> +
>> +/* limits of integral types */
>> +
>> +#define INT8_MIN (-128)
>> +#define INT16_MIN (-32767-1)
>> +#define INT32_MIN (-2147483647-1)
>> +#define INT64_MIN (-9223372036854775807LL-1)
>> +
>> +#define INT8_MAX (127)
>> +#define INT16_MAX (32767)
>> +#define INT32_MAX (2147483647)
>> +#define INT64_MAX (9223372036854775807LL)
>> +
>> +#define UINT8_MAX (255)
>> +#define UINT16_MAX (65535)
>> +#define UINT32_MAX (4294967295U)
>> +#define UINT64_MAX (18446744073709551615ULL)
>> +
>> +#define INT_LEAST8_MIN INT8_MIN
>> +#define INT_LEAST16_MIN INT16_MIN
>> +#define INT_LEAST32_MIN INT32_MIN
>> +#define INT_LEAST64_MIN INT64_MIN
>> +
>> +#define INT_LEAST8_MAX INT8_MAX
>> +#define INT_LEAST16_MAX INT16_MAX
>> +#define INT_LEAST32_MAX INT32_MAX
>> +#define INT_LEAST64_MAX INT64_MAX
>> +
>> +#define UINT_LEAST8_MAX UINT8_MAX
>> +#define UINT_LEAST16_MAX UINT16_MAX
>> +#define UINT_LEAST32_MAX UINT32_MAX
>> +#define UINT_LEAST64_MAX UINT64_MAX
>> +
>> +#define SIZE_MAX ((size_t)(__LONG_MAX__) * 2 + 1)
>> +#define SSIZE_MIN (-__LONG_MAX__ - 1)
>
> SSIZE_MIN is not defined by a standard.
> It also doesn't really make sense to have, as ssize_t is only supposed
> to store [-1,SSIZE_MAX].
>
>> +#define SSIZE_MAX __LONG_MAX__
>
> Apparently SSIZE_MAX can also defined via the compilers <limits.h> as
> used by nolibc-test.c leading to a warning.
> Maybe wrap it in #ifndef SSIZE_MAX.
>
> In file included from sysroot/x86/include/std.h:21,
> from sysroot/x86/include/stdio.h:12,
> from nolibc-test.c:15:
> sysroot/x86/include/stdint.h:79: warning: "SSIZE_MAX" redefined
> 79 | #define SSIZE_MAX __LONG_MAX__
> |
> In file included from /usr/include/limits.h:195,
> from
> /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed/limits.h:203,
> from
> /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed/syslimits.h:7,
> from
> /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/include-fixed/limits.h:34,
> from nolibc-test.c:6:
> /usr/include/bits/posix1_lim.h:169: note: this is the location of
> the previous definition
> 169 | # define SSIZE_MAX LONG_MAX
> |
>

Ok, I'll remove the SSIZE_MIN and SSIZE_MAX since neither seem to be in the standards page anyway.

Note that ssize_t is still defined in this file. It pre-dates my patch.

>> +#define INTPTR_MIN SSIZE_MIN
>> +#define INTPTR_MAX SSIZE_MAX
>> +#define PTRDIFF_MIN SSIZE_MIN
>> +#define PTRDIFF_MAX SSIZE_MAX
>> +#define UINTPTR_MAX SIZE_MAX
>> +
>> +#define INT_FAST8_MIN INT8_MIN
>> +#define INT_FAST16_MIN SSIZE_MIN
>> +#define INT_FAST32_MIN SSIZE_MIN
>> +#define INT_FAST64_MIN SSIZE_MIN
>> +
>> +#define INT_FAST8_MAX INT8_MAX
>> +#define INT_FAST16_MAX SSIZE_MAX
>> +#define INT_FAST32_MAX SSIZE_MAX
>> +#define INT_FAST64_MAX SSIZE_MAX
>> +
>> +#define UINT_FAST8_MAX UINT8_MAX
>> +#define UINT_FAST16_MAX SIZE_MAX
>> +#define UINT_FAST32_MAX SIZE_MAX
>> +#define UINT_FAST64_MAX SIZE_MAX
>
> Alignment of values within lines is inconsistent.
>

Thanks, I did a whole lot of alignment in the latest version, hopefully it should be ok now.

>> +
>> #endif /* _NOLIBC_STDINT_H */
>> --
>> 2.39.2
>>

Thanks for the review,
Vincent.

2023-02-23 00:38:40

by Vincent Dagonneau

[permalink] [raw]
Subject: Re: [PATCH v5 4/4] tools/nolibc: add tests for the integer limits in stdint.h



On Tue, Feb 21, 2023, at 12:44, Willy Tarreau wrote:
> On Tue, Feb 21, 2023 at 05:34:01PM +0000, Thomas Weißschuh wrote:
>> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
>> > index 882140508d56..ceaf60075331 100644
>> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
>> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
>> > @@ -561,7 +561,67 @@ int run_syscall(int min, int max)
>> > CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
>> > CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
>> > CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
>> > - case __LINE__:
>> > + CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break;
>> > + CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break;
>> > + CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break;
>> > + CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break;
>> > + CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break;
>> > + CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break;
>> > + CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break;
>> > + CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break;
>> > + CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break;
>> > + CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break;
>> > + CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break;
>> > + CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break;
>> > + CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break;
>> > + CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break;
>> > + CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break;
>> > + CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break;
>> > + CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break;
>> > + CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break;
>> > + CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break;
>> > + CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break;
>> > + CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break;
>> > + CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
>> > + CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
>> > + CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
>> > +#if __SIZEOF_LONG__ == 8
>> > + CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break;
>> > + CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break;
>> > + CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break;
>>
>> The _least64 tests should also apply to 32bit, no?
>> And moved before the _fast8 tests.
>
> Just thinking loud, it seems to me that all of these _least/_fast ones
> can in fact be reliably checked against INT_*, LONG_* and SIZE_MAX. Given
> that these ones are already tested, maybe we can just get rid of the ifdef
> around all the least/fast and map them to the ones we already test ? That
> would possibly remove duplication and make it more readable.
>

Ok, just did something similar in the newest version. It does make it more readable.

> Willy

2023-02-23 01:00:36

by Vincent Dagonneau

[permalink] [raw]
Subject: Re: [PATCH v5 4/4] tools/nolibc: add tests for the integer limits in stdint.h

On Tue, Feb 21, 2023, at 12:34, Thomas Weißschuh wrote:
> I think some comments from my last review got lost; see inline.
>

Yes, sorry, I hope the new version addresses them.

> On Mon, Feb 20, 2023 at 03:20:10PM -0500, Vincent Dagonneau wrote:
>> This commit adds tests for the limits added in a previous commit. The
>> limits are defined in decimal in stdint.h and as hexadecimal in the
>> tests (e.g. 0x7f = 127 or 0x80 = -128). Hopefully it catches some of the
>> most egregious mistakes.
>>
>> As we rely on the compiler to provide __SIZEOF_LONG__, we also test
>> whether it is defined.
>>
>> Signed-off-by: Vincent Dagonneau <[email protected]>
>> Signed-off-by: Willy Tarreau <[email protected]>
>> ---
>> tools/testing/selftests/nolibc/nolibc-test.c | 62 +++++++++++++++++++-
>> 1 file changed, 61 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
>> index 882140508d56..ceaf60075331 100644
>> --- a/tools/testing/selftests/nolibc/nolibc-test.c
>> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
>> @@ -561,7 +561,67 @@ int run_syscall(int min, int max)
>> CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
>> CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
>> CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
>> - case __LINE__:
>> + CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break;
>> + CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break;
>> + CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break;
>> + CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break;
>> + CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break;
>> + CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break;
>> + CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break;
>> + CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break;
>> + CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break;
>> + CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break;
>> + CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break;
>> + CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break;
>> + CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break;
>> + CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break;
>> + CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break;
>> + CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break;
>> + CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break;
>> + CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break;
>> + CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break;
>> + CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break;
>> + CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break;
>> + CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
>> + CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
>> + CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
>> +#if __SIZEOF_LONG__ == 8
>> + CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break;
>> + CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break;
>> + CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break;
>
> The _least64 tests should also apply to 32bit, no?
> And moved before the _fast8 tests.
>

You are right. I got confused. I added the fast64/least64 tests to 32 bits as well.

>> + CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) 0x7fffffffffffffffLL); break;
>> + CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) 0x8000000000000000LL); break;
>> + CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) 0xffffffffffffffffULL); break;
>> + CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) 0x7fffffffffffffffLL); break;
>> + CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) 0x8000000000000000LL); break;
>> + CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) 0xffffffffffffffffULL); break;
>> + CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x8000000000000000LL); break;
>> + CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffffffffffffLL); break;
>> + CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffffffffffULL); break;
>> + CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x8000000000000000LL); break;
>> + CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffffffffffffLL); break;
>> + CASE_TEST(limit_ssize_min); EXPECT_EQ(1, SSIZE_MIN, (ssize_t) 0x8000000000000000LL); break;
>> + CASE_TEST(limit_ssize_max); EXPECT_EQ(1, SSIZE_MAX, (ssize_t) 0x7fffffffffffffffLL); break;
>> + CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffffffffffULL); break;
>> +#elif __SIZEOF_LONG__ == 4
>> + CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) 0x7fffffff); break;
>> + CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) 0x80000000); break;
>> + CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) 0xffffffffU); break;
>> + CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) 0x7fffffff); break;
>> + CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) 0x80000000); break;
>> + CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) 0xffffffffU); break;
>> + CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x80000000); break;
>> + CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffff); break;
>> + CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffU); break;
>> + CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x80000000); break;
>> + CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffff); break;
>> + CASE_TEST(limit_ssize_min); EXPECT_EQ(1, SSIZE_MIN, (ssize_t) 0x80000000); break;
>> + CASE_TEST(limit_ssize_max); EXPECT_EQ(1, SSIZE_MAX, (ssize_t) 0x7fffffff); break;
>> + CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffU); break;
>> +#else
>> +# warning "__SIZEOF_LONG__ is undefined"
>> +#endif /* __SIZEOF_LONG__ */
>> + case __LINE__:
>
> The case __LINE__ still seems to be misindented, at least different
> than before.
>

Should be fixed in the new version.

>> return ret; /* must be last */
>> /* note: do not set any defaults so as to permit holes above */
>> }
>> --
>> 2.39.2