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)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// 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>
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');
20420 STPNCPY
20430 WMEMCHR
20440 WCSNLEN
+ 20450 WSTRNCMP
*/
#if defined(VGO_solaris)
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