From: Ammar Faizi <ammarfaizi2@openresty.com>
To: "Willy Tarreau" <w@1wt.eu>, "Thomas Weißschuh" <linux@weissschuh.net>
Cc: Ammar Faizi <ammarfaizi2@openresty.com>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Linux Kselftest Mailing List <linux-kselftest@vger.kernel.org>,
LLVM Mailing List <llvm@lists.linux.dev>,
Yichun Zhang <yichun@openresty.com>,
Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>,
Shuah Khan <shuah@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <nick.desaulniers+lkml@gmail.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
gwml@gnuweeb.org
Subject: [PATCH 3/4] selftests/nolibc: add abs() range test
Date: Sun, 26 Jul 2026 17:13:04 +0700 [thread overview]
Message-ID: <20260726101306.3772237-4-ammarfaizi2@openresty.com> (raw)
In-Reply-To: <20260726101306.3772237-1-ammarfaizi2@openresty.com>
The existing abs/abs_noop cases only cover abs(-10) and abs(10), and
labs() and llabs() have no coverage at all. Nothing exercises the type
minimum, where negating the argument overflows.
Add a case walking all three functions over the interesting points of
their argument type: the minimum, the minimum plus one, an ordinary
negative value, zero and the maximum. At the minimum the absolute
value is not representable and the argument is returned unchanged.
Both the arguments and the results have to be hidden from the
optimizer. The compiler knows these functions never return a negative
value, so it folds the comparisons at build time otherwise, and that
would equally hide the overflow being tested for.
Note that the overflow itself is only reported through the:
-fsanitize=undefined -fsanitize-trap=all
flags the suite already builds with; without them the wrapped result
is the same as the correct one. With the flags, and with the preceding
fix reverted, the run dies with SIGILL on this test on both i386 and
x86-64.
Cc: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>
Signed-off-by: Ammar Faizi <ammarfaizi2@openresty.com>
---
tools/testing/selftests/nolibc/nolibc-test.c | 47 ++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 996e8d13508e..4dc2ffea63bd 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1728,6 +1728,52 @@ int test_alloca(void)
return *x - 0x1234;
}
+/* abs(), labs() and llabs() over the whole range of their argument type */
+int test_abs_range(void)
+{
+ int i, ri;
+ long l, rl;
+ long long ll, rll;
+
+ /*
+ * Both the inputs and the results have to stay opaque: the compiler
+ * knows abs() and friends never return a negative value and would
+ * otherwise fold the comparisons below at build time, which would also
+ * hide the undefined behavior that is being tested for.
+ */
+ i = INT_MIN; l = LONG_MIN; ll = LLONG_MIN;
+ __asm__ ("" : "+r" (i), "+r" (l), "+r" (ll));
+ ri = abs(i); rl = labs(l); rll = llabs(ll);
+ __asm__ ("" : "+r" (ri), "+r" (rl), "+r" (rll));
+ /* the absolute value is not representable, the input is returned */
+ if (ri != INT_MIN || rl != LONG_MIN || rll != LLONG_MIN)
+ return 1;
+
+ i = INT_MIN + 1; l = LONG_MIN + 1; ll = LLONG_MIN + 1;
+ __asm__ ("" : "+r" (i), "+r" (l), "+r" (ll));
+ ri = abs(i); rl = labs(l); rll = llabs(ll);
+ __asm__ ("" : "+r" (ri), "+r" (rl), "+r" (rll));
+ if (ri != INT_MAX || rl != LONG_MAX || rll != LLONG_MAX)
+ return 2;
+
+ i = -42; l = -42; ll = -42;
+ __asm__ ("" : "+r" (i), "+r" (l), "+r" (ll));
+ if (abs(i) != 42 || labs(l) != 42 || llabs(ll) != 42)
+ return 3;
+
+ i = 0; l = 0; ll = 0;
+ __asm__ ("" : "+r" (i), "+r" (l), "+r" (ll));
+ if (abs(i) != 0 || labs(l) != 0 || llabs(ll) != 0)
+ return 4;
+
+ i = INT_MAX; l = LONG_MAX; ll = LLONG_MAX;
+ __asm__ ("" : "+r" (i), "+r" (l), "+r" (ll));
+ if (abs(i) != INT_MAX || labs(l) != LONG_MAX || llabs(ll) != LLONG_MAX)
+ return 5;
+
+ return 0;
+}
+
int test_difftime(void)
{
if (difftime(200., 100.) != 100.)
@@ -1943,6 +1989,7 @@ int run_stdlib(int min, int max)
CASE_TEST(toupper_noop); EXPECT_EQ(1, toupper('A'), 'A'); break;
CASE_TEST(abs); EXPECT_EQ(1, abs(-10), 10); break;
CASE_TEST(abs_noop); EXPECT_EQ(1, abs(10), 10); break;
+ CASE_TEST(abs_range); EXPECT_ZR(1, test_abs_range()); break;
CASE_TEST(alloca); EXPECT_ZR(1, test_alloca()); break;
CASE_TEST(difftime); EXPECT_ZR(1, test_difftime()); break;
CASE_TEST(memchr_foobar6_o); EXPECT_STREQ(1, memchr("foobar", 'o', 6), "oobar"); break;
--
Ammar Faizi
next prev parent reply other threads:[~2026-07-26 10:13 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-26 10:13 [PATCH 0/4] nolibc: syscall() and abs() fixes, plus a cleanup Ammar Faizi
2026-07-26 10:13 ` [PATCH 1/4] tools/nolibc: evaluate syscall() arguments before the arch macros Ammar Faizi
2026-07-26 20:16 ` Thomas Weißschuh
2026-07-27 1:21 ` Ammar Faizi
2026-07-27 3:42 ` Willy Tarreau
2026-07-28 6:53 ` Ammar Faizi
2026-07-27 3:30 ` Willy Tarreau
2026-07-27 16:18 ` Thomas Weißschuh
2026-07-28 6:51 ` Ammar Faizi
2026-07-26 10:13 ` [PATCH 2/4] tools/nolibc: stdlib: avoid signed overflow in abs() and friends Ammar Faizi
2026-07-26 14:13 ` David Laight
2026-07-26 16:01 ` Willy Tarreau
2026-07-27 7:32 ` David Laight
2026-07-27 16:15 ` Thomas Weißschuh
2026-07-28 8:46 ` David Laight
2026-07-28 16:31 ` Thomas Weißschuh
2026-07-28 16:37 ` Ammar Faizi
2026-07-26 10:13 ` Ammar Faizi [this message]
2026-07-26 20:00 ` [PATCH 3/4] selftests/nolibc: add abs() range test Thomas Weißschuh
2026-07-27 1:32 ` Ammar Faizi
2026-07-27 2:01 ` Ammar Faizi
2026-07-27 16:13 ` Thomas Weißschuh
2026-07-28 6:14 ` Ammar Faizi
2026-07-26 10:13 ` [PATCH 4/4] tools/nolibc: remove dead __ARCH_WANT_SYS_OLD_SELECT Ammar Faizi
2026-07-26 20:01 ` Thomas Weißschuh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260726101306.3772237-4-ammarfaizi2@openresty.com \
--to=ammarfaizi2@openresty.com \
--cc=alviro.iskandar@gnuweeb.org \
--cc=gwml@gnuweeb.org \
--cc=justinstitt@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux@weissschuh.net \
--cc=llvm@lists.linux.dev \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=nick.desaulniers+lkml@gmail.com \
--cc=shuah@kernel.org \
--cc=w@1wt.eu \
--cc=yichun@openresty.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®