Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Nov 2025 19:22:14 +0000
From:      Robert Clausecker <fuz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 2fb8cbc6ef1b - main - libc/tests: add stdbit test framework and unit tests
Message-ID:  <692c9966.26e27.70621b5b@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by fuz:

URL: https://cgit.FreeBSD.org/src/commit/?id=2fb8cbc6ef1b3cc6cd60e5db07f8305623f9b044

commit 2fb8cbc6ef1b3cc6cd60e5db07f8305623f9b044
Author:     Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2025-11-18 17:33:12 +0000
Commit:     Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2025-11-30 19:21:52 +0000

    libc/tests: add stdbit test framework and unit tests
    
    This adds unit tests for all 70 functions in <stdbit.h>.
    
    I'm sorry for the test framework, but it makes it so I don't
    have to write 70 unit tests by hand.
    
    Reviewed by:    adrian, des
    Approved by:    markj (mentor)
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D53660
---
 etc/mtree/BSD.tests.dist                           |  2 +
 lib/libc/tests/Makefile                            |  1 +
 lib/libc/tests/stdbit/Makefile                     | 19 +++++
 lib/libc/tests/stdbit/stdbit-test-framework.c      | 80 ++++++++++++++++++++++
 lib/libc/tests/stdbit/stdbit-test-kernel.c         | 68 ++++++++++++++++++
 lib/libc/tests/stdbit/stdc_bit_ceil_test.c         | 20 ++++++
 lib/libc/tests/stdbit/stdc_bit_floor_test.c        | 25 +++++++
 lib/libc/tests/stdbit/stdc_bit_width_test.c        | 22 ++++++
 lib/libc/tests/stdbit/stdc_count_ones_test.c       | 22 ++++++
 lib/libc/tests/stdbit/stdc_count_zeros_test.c      | 23 +++++++
 .../tests/stdbit/stdc_first_leading_one_test.c     | 29 ++++++++
 .../tests/stdbit/stdc_first_leading_zero_test.c    | 30 ++++++++
 .../tests/stdbit/stdc_first_trailing_one_test.c    | 26 +++++++
 .../tests/stdbit/stdc_first_trailing_zero_test.c   | 27 ++++++++
 lib/libc/tests/stdbit/stdc_has_single_bit_test.c   | 21 ++++++
 lib/libc/tests/stdbit/stdc_leading_ones_test.c     | 26 +++++++
 lib/libc/tests/stdbit/stdc_leading_zeros_test.c    | 26 +++++++
 lib/libc/tests/stdbit/stdc_trailing_ones_test.c    | 23 +++++++
 lib/libc/tests/stdbit/stdc_trailing_zeros_test.c   | 23 +++++++
 19 files changed, 513 insertions(+)

diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index 0380b925e64c..e2b8c8ede325 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -382,6 +382,8 @@
             ..
             ssp
             ..
+            stdbit
+            ..
             stdio
             ..
             stdlib
diff --git a/lib/libc/tests/Makefile b/lib/libc/tests/Makefile
index 975c895770ee..ae8e0e937676 100644
--- a/lib/libc/tests/Makefile
+++ b/lib/libc/tests/Makefile
@@ -14,6 +14,7 @@ TESTS_SUBDIRS+=	resolv
 TESTS_SUBDIRS+=	rpc
 TESTS_SUBDIRS+=	secure
 TESTS_SUBDIRS+=	setjmp
+TESTS_SUBDIRS+=	stdbit
 TESTS_SUBDIRS+=	stdio
 TESTS_SUBDIRS+=	stdlib
 TESTS_SUBDIRS+=	stdtime
diff --git a/lib/libc/tests/stdbit/Makefile b/lib/libc/tests/stdbit/Makefile
new file mode 100644
index 000000000000..37450056007a
--- /dev/null
+++ b/lib/libc/tests/stdbit/Makefile
@@ -0,0 +1,19 @@
+# ensure libc functions are tested, not clang's builtins
+CFLAGS+=	-fno-builtin
+
+ATF_TESTS_C+=	stdc_bit_ceil_test \
+		stdc_bit_floor_test \
+		stdc_bit_width_test \
+		stdc_count_ones_test \
+		stdc_count_zeros_test \
+		stdc_first_leading_one_test \
+		stdc_first_leading_zero_test \
+		stdc_first_trailing_one_test \
+		stdc_first_trailing_zero_test \
+		stdc_has_single_bit_test \
+		stdc_leading_ones_test \
+		stdc_leading_zeros_test \
+		stdc_trailing_ones_test \
+		stdc_trailing_zeros_test
+
+.include <bsd.test.mk>
diff --git a/lib/libc/tests/stdbit/stdbit-test-framework.c b/lib/libc/tests/stdbit/stdbit-test-framework.c
new file mode 100644
index 000000000000..368b38fb4745
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdbit-test-framework.c
@@ -0,0 +1,80 @@
+/*     
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * Test framework for stdbit functions.
+ * Requires the following macros to be defined:
+ *
+ * FUNCSTEM -- name of the function without type suffix
+ * MKREFFUNC(name, type) -- macro to generate a reference
+ *   implementation of the function as a static function
+ *   named name with give argument type.
+ */
+
+#include <sys/cdefs.h>
+#include <atf-c.h>
+#include <limits.h>
+#include <stdbit.h>
+#include <stdint.h>
+
+#define ATF_TC_WITHOUT_HEAD1(stem, suffix) ATF_TC_WITHOUT_HEAD2(__CONCAT(stem, suffix))
+#define ATF_TC_WITHOUT_HEAD2(case) ATF_TC_WITHOUT_HEAD(case)
+#define ATF_TC_BODY1(stem, suffix, tc) ATF_TC_BODY2(__CONCAT(stem, suffix), tc)
+#define ATF_TC_BODY2(case, tc) ATF_TC_BODY(case, tc)
+
+#define SUFFIX _uc
+#define TYPE unsigned char
+#define TYPE_WIDTH UCHAR_WIDTH
+#include "stdbit-test-kernel.c"
+#undef TYPE_WIDTH
+#undef TYPE
+#undef SUFFIX
+
+#define SUFFIX _us
+#define TYPE unsigned short
+#define TYPE_WIDTH USHRT_WIDTH
+#include "stdbit-test-kernel.c"
+#undef TYPE_WIDTH
+#undef TYPE
+#undef SUFFIX
+
+#define SUFFIX _ui
+#define TYPE unsigned int
+#define TYPE_WIDTH UINT_WIDTH
+#include "stdbit-test-kernel.c"
+#undef TYPE_WIDTH
+#undef TYPE
+#undef SUFFIX
+
+#define SUFFIX _ul
+#define TYPE unsigned long
+#define TYPE_WIDTH ULONG_WIDTH
+#include "stdbit-test-kernel.c"
+#undef TYPE_WIDTH
+#undef TYPE
+#undef SUFFIX
+
+#define SUFFIX _ull
+#define TYPE unsigned long long
+#define TYPE_WIDTH ULLONG_WIDTH
+#include "stdbit-test-kernel.c"
+#undef TYPE_WIDTH
+#undef TYPE
+#undef SUFFIX
+
+#define ADD_CASE(stem, suffix) ADD_CASE1(__CONCAT(stem, suffix))
+#define ADD_CASE1(case) ATF_TP_ADD_TC(tp, case)
+
+ATF_TP_ADD_TCS(tp)
+{
+	ADD_CASE(FUNCSTEM, _uc);
+	ADD_CASE(FUNCSTEM, _us);
+	ADD_CASE(FUNCSTEM, _ui);
+	ADD_CASE(FUNCSTEM, _ul);
+	ADD_CASE(FUNCSTEM, _ull);
+
+	return (atf_no_error());
+}
diff --git a/lib/libc/tests/stdbit/stdbit-test-kernel.c b/lib/libc/tests/stdbit/stdbit-test-kernel.c
new file mode 100644
index 000000000000..d584e391ff6f
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdbit-test-kernel.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * test kernel for stdbit functions.
+ * Requires the following macros to be defined:
+ *
+ * FUNCSTEM -- stem of the function name
+ * SUFFIX -- type suffic
+ * TYPE -- argument type
+ * MKREFFUNC(ref, type) -- reference function builder
+ */
+
+#define FUNC __CONCAT(FUNCSTEM, SUFFIX)
+#define REF __CONCAT(FUNCSTEM, __CONCAT(SUFFIX, _ref))
+
+MKREFFUNC(REF, TYPE)
+
+ATF_TC_WITHOUT_HEAD1(FUNCSTEM, SUFFIX);
+ATF_TC_BODY1(FUNCSTEM, SUFFIX, tc)
+{
+	uintmax_t has, want;
+	size_t i, j;
+	TYPE value;
+
+	/* test all single-bit patterns */
+	for (i = 0; i < TYPE_WIDTH; i++) {
+		value = (TYPE)1 << i;
+		has = FUNC(value);
+		want = REF(value);
+		ATF_CHECK_EQ_MSG(has, want, "%s(%#jx) == %#jx != %#jx == %s(%#jx)",
+		    __XSTRING(FUNC), (uintmax_t)value, has, want, __XSTRING(REF), (uintmax_t)value);
+	}
+
+	/* test all double-bit patterns */
+	for (i = 0; i < TYPE_WIDTH; i++) {
+		for (j = 0; j < i; j++) {
+			value = (TYPE)1 << i | (TYPE)1 << j;
+			has = FUNC(value);
+			want = REF(value);
+			ATF_CHECK_EQ_MSG(has, want, "%s(%#jx) == %#jx != %#jx == %s(%#jx)",
+			    __XSTRING(FUNC), (uintmax_t)value, has, want, __XSTRING(REF), (uintmax_t)value);
+		}
+	}
+
+	/* test all barber-pole patterns */
+	value = ~(TYPE)0;
+	for (i = 0; i < TYPE_WIDTH; i++) {
+		has = FUNC(value);
+		want = REF(value);
+		ATF_CHECK_EQ_MSG(has, want, "%s(%#jx) == %#jx != %#jx == %s(%#jx)",
+		    __XSTRING(FUNC), (uintmax_t)value, has, want, __XSTRING(REF), (uintmax_t)value);
+
+		value = ~value;		
+		has = FUNC(value);
+		want = REF(value);
+		ATF_CHECK_EQ_MSG(has, want, "%s(%#jx) == %#jx != %#jx == %s(%#jx)",
+		    __XSTRING(FUNC), (uintmax_t)value, has, want, __XSTRING(REF), (uintmax_t)value);
+
+		value = ~value << 1;
+	}
+}
+
+#undef REF
+#undef FUNC
diff --git a/lib/libc/tests/stdbit/stdc_bit_ceil_test.c b/lib/libc/tests/stdbit/stdc_bit_ceil_test.c
new file mode 100644
index 000000000000..0495da55c5d9
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_bit_ceil_test.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_bit_ceil
+#define MKREFFUNC(name, type)						\
+	static type 							\
+	name(type value) 						\
+	{ 								\
+		type ceil = 1;						\
+									\
+		while (ceil < value && ceil != 0)			\
+			ceil <<= 1;					\
+									\
+		return (ceil);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_bit_floor_test.c b/lib/libc/tests/stdbit/stdc_bit_floor_test.c
new file mode 100644
index 000000000000..a2c5b5f7d8ce
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_bit_floor_test.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_bit_floor
+#define MKREFFUNC(name, type)						\
+	static type 							\
+	name(type value) 						\
+	{ 								\
+		type floor = 1;						\
+									\
+		if (value == 0)						\
+			return (0);					\
+									\
+		while (value != 1) {					\
+			floor <<= 1;					\
+			value >>= 1;					\
+		}							\
+									\
+		return (floor);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_bit_width_test.c b/lib/libc/tests/stdbit/stdc_bit_width_test.c
new file mode 100644
index 000000000000..bfcb2b3bd779
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_bit_width_test.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_bit_width
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		unsigned width = 0;					\
+									\
+		while (value != 0) {					\
+			value >>= 1;					\
+			width++;					\
+		}							\
+									\
+		return (width);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_count_ones_test.c b/lib/libc/tests/stdbit/stdc_count_ones_test.c
new file mode 100644
index 000000000000..9093edde495b
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_count_ones_test.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_count_ones
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		unsigned count = 0;					\
+									\
+		while (value != 0) {					\
+			count += value & 1;				\
+			value >>= 1;					\
+		}							\
+									\
+		return (count);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_count_zeros_test.c b/lib/libc/tests/stdbit/stdc_count_zeros_test.c
new file mode 100644
index 000000000000..a82de6696a64
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_count_zeros_test.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_count_zeros
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		unsigned count = 0;					\
+									\
+		value = ~value;						\
+		while (value != 0) {					\
+			count += value & 1;				\
+			value >>= 1;					\
+		}							\
+									\
+		return (count);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_first_leading_one_test.c b/lib/libc/tests/stdbit/stdc_first_leading_one_test.c
new file mode 100644
index 000000000000..7312789262ea
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_first_leading_one_test.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_first_leading_one
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned pos = 1;					\
+									\
+		if (value == 0)						\
+			return (0);					\
+									\
+		while ((type)(bit << 1) != 0)				\
+			bit <<= 1;					\
+									\
+		while ((bit & value) == 0) {				\
+			bit >>= 1;					\
+			pos++;						\
+		}							\
+									\
+		return (pos);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_first_leading_zero_test.c b/lib/libc/tests/stdbit/stdc_first_leading_zero_test.c
new file mode 100644
index 000000000000..df2a1f4b8673
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_first_leading_zero_test.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_first_leading_zero
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned pos = 1;					\
+									\
+		value = ~value;						\
+		if (value == 0)						\
+			return (0);					\
+									\
+		while ((type)(bit << 1) != 0)				\
+			bit <<= 1;					\
+									\
+		while ((bit & value) == 0) {				\
+			bit >>= 1;					\
+			pos++;						\
+		}							\
+									\
+		return (pos);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_first_trailing_one_test.c b/lib/libc/tests/stdbit/stdc_first_trailing_one_test.c
new file mode 100644
index 000000000000..43284786cd0e
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_first_trailing_one_test.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_first_trailing_one
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned pos = 1;					\
+									\
+		if (value == 0)						\
+			return (0);					\
+									\
+		while ((bit & value) == 0) {				\
+			bit <<= 1;					\
+			pos++;						\
+		}							\
+									\
+		return (pos);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_first_trailing_zero_test.c b/lib/libc/tests/stdbit/stdc_first_trailing_zero_test.c
new file mode 100644
index 000000000000..ab2a995dcc86
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_first_trailing_zero_test.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_first_trailing_zero
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned pos = 1;					\
+									\
+		value = ~value;						\
+		if (value == 0)						\
+			return (0);					\
+									\
+		while ((bit & value) == 0) {				\
+			bit <<= 1;					\
+			pos++;						\
+		}							\
+									\
+		return (pos);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_has_single_bit_test.c b/lib/libc/tests/stdbit/stdc_has_single_bit_test.c
new file mode 100644
index 000000000000..3426deccd8d0
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_has_single_bit_test.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_has_single_bit
+#define MKREFFUNC(name, type)						\
+	static bool 							\
+	name(type value) 						\
+	{ 								\
+		type bit;						\
+									\
+		for (bit = 1; bit != 0; bit <<= 1)			\
+			if (value == bit)				\
+				return (true);				\
+									\
+		return (false);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_leading_ones_test.c b/lib/libc/tests/stdbit/stdc_leading_ones_test.c
new file mode 100644
index 000000000000..616b3d5e6279
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_leading_ones_test.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_leading_ones
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned count = 0;					\
+									\
+		while ((type)(bit << 1) != 0)				\
+			bit <<= 1;					\
+									\
+		while (bit != 0 && (bit & value) != 0) {		\
+			bit >>= 1;					\
+			count++;					\
+		}							\
+									\
+		return (count);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_leading_zeros_test.c b/lib/libc/tests/stdbit/stdc_leading_zeros_test.c
new file mode 100644
index 000000000000..7c9d26e86456
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_leading_zeros_test.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_leading_zeros
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned count = 0;					\
+									\
+		while ((type)(bit << 1) != 0)				\
+			bit <<= 1;					\
+									\
+		while (bit != 0 && (bit & value) == 0) {		\
+			bit >>= 1;					\
+			count++;					\
+		}							\
+									\
+		return (count);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_trailing_ones_test.c b/lib/libc/tests/stdbit/stdc_trailing_ones_test.c
new file mode 100644
index 000000000000..9e261cc543de
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_trailing_ones_test.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_trailing_ones
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned count = 0;					\
+									\
+		while (bit != 0 && (bit & value) != 0) {		\
+			bit <<= 1;					\
+			count++;					\
+		}							\
+									\
+		return (count);						\
+	}
+
+#include "stdbit-test-framework.c"
diff --git a/lib/libc/tests/stdbit/stdc_trailing_zeros_test.c b/lib/libc/tests/stdbit/stdc_trailing_zeros_test.c
new file mode 100644
index 000000000000..81fe11c5c82a
--- /dev/null
+++ b/lib/libc/tests/stdbit/stdc_trailing_zeros_test.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define FUNCSTEM stdc_trailing_zeros
+#define MKREFFUNC(name, type)						\
+	static unsigned							\
+	name(type value) 						\
+	{ 								\
+		type bit = 1;						\
+		unsigned count = 0;					\
+									\
+		while (bit != 0 && (bit & value) == 0) {		\
+			bit <<= 1;					\
+			count++;					\
+		}							\
+									\
+		return (count);						\
+	}
+
+#include "stdbit-test-framework.c"


help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?692c9966.26e27.70621b5b>