]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 401627 - Add wcsncmp override and testcase.
authorMark Wielaard <mark@klomp.org>
Sat, 1 Dec 2018 22:54:40 +0000 (23:54 +0100)
committerMark Wielaard <mark@klomp.org>
Thu, 6 Dec 2018 15:40:34 +0000 (16:40 +0100)
glibc 2.28 added an avx2 optimized variant of wstrncmp which memcheck
cannot proof correct. Add a simple override in vg_replace_strmem.c.

NEWS
memcheck/tests/wcs.c
memcheck/tests/wcs.stderr.exp
shared/vg_replace_strmem.c

diff --git a/NEWS b/NEWS
index 7b784a80b240709c20f1ad5322160cbc121da629..edf0f7255bdd65dd896487b9294911cc15940853 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,7 @@ where XXXXXX is the bug number as listed below.
 401112  LLVM 5.0 generates comparison against partially initialized data
 385411  s390x: z13 vector floating-point instructions not implemented
 401578  drd: crashes sometimes on fork()
+401627  memcheck errors with glibc avx2 optimized wcsncmp
 
 Release 3.14.0 (9 October 2018)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 15730ad024689720e86c6b0c039b643ae0b1a09e..538304b1fe441d9eff54bac512019e5a27742f2f 100644 (file)
@@ -1,5 +1,6 @@
-// Uses various wchar_t * functions that have hand written SSE assembly
-// implementations in glibc. wcslen, wcscpy, wcscmp, wcsrchr, wcschr.
+// Uses various wchar_t * functions that have hand written SSE and/or AVX2
+// assembly implementations in glibc.
+// wcslen, wcscpy, wcscmp, wcsncmp, wcsrchr, wcschr.
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -18,6 +19,8 @@ int main(int argc, char **argv)
   c = wcscpy (b, a);
 
   fprintf (stderr, "wcscmp equal: %d\n", wcscmp (a, b)); // wcscmp equal: 0
+  fprintf (stderr,
+          "wcsncmp equal: %d\n", wcsncmp (a, b, l)); // wcsncmp equal: 0
 
   d = wcsrchr (a, L'd');
   e = wcschr (a, L'd');
index 41d74c83e8546acf44303fab740cdd7b4d8f9079..d5b5959bef95d274e58153c81263af42b7f1f163 100644 (file)
@@ -1,3 +1,4 @@
 wcslen: 53
 wcscmp equal: 0
+wcsncmp equal: 0
 wcsrchr == wcschr: 1
index d6927f08e0da1f22c5ebb63990ad38c6024b42bc..89a7dccb72dd5886c323e40ecb0a2f58b7fb4793 100644 (file)
    20420 STPNCPY
    20430 WMEMCHR
    20440 WCSNLEN
+   20450 WSTRNCMP
 */
 
 #if defined(VGO_solaris)
@@ -1927,6 +1928,36 @@ static inline void my_exit ( int x )
  WCSCMP(VG_Z_LIBC_SONAME,          wcscmp)
 #endif
 
+/*---------------------- wcsncmp ----------------------*/
+
+// This is a wchar_t equivalent to strncmp.  We don't
+// have wchar_t available here, but in the GNU C Library
+// wchar_t is always 32 bits wide and wcsncmp uses signed
+// comparison, not unsigned as in strncmp function.
+
+#define WCSNCMP(soname, fnname) \
+   int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
+          ( const Int* s1, const Int* s2, SizeT nmax ); \
+   int VG_REPLACE_FUNCTION_EZU(20450,soname,fnname) \
+          ( const Int* s1, const Int* s2, SizeT nmax ) \
+   { \
+      SizeT n = 0; \
+      while (True) { \
+         if (n >= nmax) return 0; \
+         if (*s1 == 0 && *s2 == 0) return 0; \
+         if (*s1 == 0) return -1; \
+         if (*s2 == 0) return 1; \
+         \
+         if (*s1 < *s2) return -1; \
+         if (*s1 > *s2) return 1; \
+         \
+         s1++; s2++; n++; \
+      } \
+   }
+#if defined(VGO_linux)
+ WCSNCMP(VG_Z_LIBC_SONAME,          wcsncmp)
+#endif
+
 /*---------------------- wcscpy ----------------------*/
 
 // This is a wchar_t equivalent to strcpy.  We don't