diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2021-10-21 15:54:57 -0500 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2021-10-26 16:51:29 -0500 |
commit | 44829b3ddb64e99e37343a0f25b2c082387d31a5 (patch) | |
tree | ba9565215210f530296dd4456816fc69f593e542 /string | |
parent | 8438135d3481853e300e1043cfee3946dadb28b3 (diff) | |
download | glibc-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/Versions | 3 | ||||
-rw-r--r-- | string/memcmp.c | 3 | ||||
-rw-r--r-- | string/string.h | 16 | ||||
-rw-r--r-- | string/tester.c | 16 |
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 (); |