aboutsummaryrefslogtreecommitdiff
path: root/string
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2021-10-21 15:54:57 -0500
committerNoah Goldstein <goldstein.w.n@gmail.com>2021-10-26 16:51:29 -0500
commit44829b3ddb64e99e37343a0f25b2c082387d31a5 (patch)
treeba9565215210f530296dd4456816fc69f593e542 /string
parent8438135d3481853e300e1043cfee3946dadb28b3 (diff)
downloadglibc-44829b3ddb64e99e37343a0f25b2c082387d31a5.tar
glibc-44829b3ddb64e99e37343a0f25b2c082387d31a5.tar.gz
glibc-44829b3ddb64e99e37343a0f25b2c082387d31a5.tar.bz2
glibc-44829b3ddb64e99e37343a0f25b2c082387d31a5.zip
String: Add support for __memcmpeq() ABI on all targets
No bug. This commit adds support for __memcmpeq() as a new ABI for all targets. In this commit __memcmpeq() is implemented only as an alias to the corresponding targets memcmp() implementation. __memcmpeq() is added as a new symbol starting with GLIBC_2.35 and defined in string.h with comments explaining its behavior. Basic tests that it is callable and works where added in string/tester.c As discussed in the proposal "Add new ABI '__memcmpeq()' to libc" __memcmpeq() is essentially a reserved namespace for bcmp(). The means is shares the same specifications as memcmp() except the return value for non-equal byte sequences is any non-zero value. This is less strict than memcmp()'s return value specification and can be better optimized when a boolean return is all that is needed. __memcmpeq() is meant to only be called by compilers if they can prove that the return value of a memcmp() call is only used for its boolean value. All tests in string/tester.c passed. As well build succeeds on x86_64-linux-gnu target.
Diffstat (limited to 'string')
-rw-r--r--string/Versions3
-rw-r--r--string/memcmp.c3
-rw-r--r--string/string.h16
-rw-r--r--string/tester.c16
4 files changed, 38 insertions, 0 deletions
diff --git a/string/Versions b/string/Versions
index 298ecd401a..864c4cf7a4 100644
--- a/string/Versions
+++ b/string/Versions
@@ -89,4 +89,7 @@ libc {
sigdescr_np; sigabbrev_np;
strerrordesc_np; strerrorname_np;
}
+ GLIBC_2.35 {
+ __memcmpeq;
+ }
}
diff --git a/string/memcmp.c b/string/memcmp.c
index 9b46d7a905..eac4112530 100644
--- a/string/memcmp.c
+++ b/string/memcmp.c
@@ -359,3 +359,6 @@ libc_hidden_builtin_def(memcmp)
# undef bcmp
weak_alias (memcmp, bcmp)
#endif
+
+#undef __memcmpeq
+strong_alias (memcmp, __memcmpeq)
diff --git a/string/string.h b/string/string.h
index b1b083edce..e70feeaeea 100644
--- a/string/string.h
+++ b/string/string.h
@@ -64,6 +64,22 @@ extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1));
extern int memcmp (const void *__s1, const void *__s2, size_t __n)
__THROW __attribute_pure__ __nonnull ((1, 2));
+/* Compare N bytes of S1 and S2. Return zero if S1 and S2 are equal.
+ Return some non-zero value otherwise.
+
+ Essentially __memcmpeq has the exact same semantics as memcmp
+ except the return value is less constrained. memcmp is always a
+ correct implementation of __memcmpeq. As well !!memcmp, -memcmp,
+ or bcmp are correct implementations.
+
+ __memcmpeq is meant to be used by compilers when memcmp return is
+ only used for its bolean value.
+
+ __memcmpeq is declared only for use by compilers. Programs should
+ continue to use memcmp. */
+extern int __memcmpeq (const void *__s1, const void *__s2, size_t __n)
+ __THROW __attribute_pure__ __nonnull ((1, 2));
+
/* Search N bytes of S for C. */
#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
extern "C++"
diff --git a/string/tester.c b/string/tester.c
index 778160ae6e..605b3f00f9 100644
--- a/string/tester.c
+++ b/string/tester.c
@@ -1450,6 +1450,19 @@ test_bcmp (void)
}
static void
+test_memcmpeq (void)
+{
+ it = "__memcmpeq";
+ check (__memcmpeq ("a", "a", 1) == 0, 1); /* Identity. */
+ check (__memcmpeq ("abc", "abc", 3) == 0, 2); /* Multicharacter. */
+ check (__memcmpeq ("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
+ check (__memcmpeq ("abce", "abcd", 4) != 0, 4);
+ check (__memcmpeq ("alph", "beta", 4) != 0, 5);
+ check (__memcmpeq ("abce", "abcd", 3) == 0, 6); /* Count limited. */
+ check (__memcmpeq ("abc", "def", 0) == 0, 8); /* Zero count. */
+}
+
+static void
test_strerror (void)
{
it = "strerror";
@@ -1611,6 +1624,9 @@ main (void)
/* bcmp - somewhat like memcmp. */
test_bcmp ();
+ /* __memcmpeq - somewhat like memcmp. */
+ test_memcmpeq ();
+
/* strndup. */
test_strndup ();