summaryrefslogtreecommitdiffstats
path: root/compiler-rt/test/sanitizer_common
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2018-02-24 01:01:14 +0000
committerKamil Rytarowski <n54@gmx.com>2018-02-24 01:01:14 +0000
commitc22867f5fc960970d413a15cfe47a2e7379c6e29 (patch)
tree34028ec596559ce619b2fe9b4097a9eef623b7e5 /compiler-rt/test/sanitizer_common
parent524946232b38103b0582a4aecf0c64e99843f8bd (diff)
downloadbcm5719-llvm-c22867f5fc960970d413a15cfe47a2e7379c6e29.tar.gz
bcm5719-llvm-c22867f5fc960970d413a15cfe47a2e7379c6e29.zip
Correct ctype(3) functions with NLS on NetBSD
Summary: The setlocale(3) function reloads the ctype(3) arrays from external files. This happens behind the scenes in the internals of libc (citrus library, runes functions etc). ctype(3) functions like isspace(3) can be provided with two variations on NetBSD: inlined or via a global symbol in libc: ``` #if defined(_NETBSD_SOURCE) && !defined(_CTYPE_NOINLINE) && \ !defined(__cplusplus) #include <sys/ctype_inline.h> #else #include <sys/ctype_bits.h> #endif ``` The in-lined versions are de-facto array lookup operations. ``` #define isspace(c) ((int)((_ctype_tab_ + 1)[(c)] & _CTYPE_S)) ``` After setting setlocale(3) the ctype(3) arrays (_ctype_tab_, _toupper_tab_, _tolower_tab_) are reload behind the scenes and they are required to be marked as initialized. Set them initialized inside the common setlocale(3) interceptor. The arrays are of size of 257 elements: 0..255 + 1 (EOF). This corrects errors on NetBSD/amd64 in applications prebuilt with MSan. Sponsored by <The NetBSD Foundation> Reviewers: vitalybuka, dvyukov, joerg Reviewed By: vitalybuka Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D42020 llvm-svn: 326008
Diffstat (limited to 'compiler-rt/test/sanitizer_common')
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/ctype.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/compiler-rt/test/sanitizer_common/TestCases/ctype.c b/compiler-rt/test/sanitizer_common/TestCases/ctype.c
new file mode 100644
index 00000000000..37e0af89be6
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/ctype.c
@@ -0,0 +1,89 @@
+// RUN: %clang %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <ctype.h>
+#include <limits.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void check_ctype(void) {
+ unsigned char c;
+ volatile size_t i = 0; /* a dummy variable to prevent optimizing code out */
+
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isalpha(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isascii(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isblank(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!iscntrl(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isdigit(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isgraph(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!islower(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isprint(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!ispunct(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isspace(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isupper(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isxdigit(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isalnum(c);
+
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!tolower(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!toupper(c);
+
+ i += !!isalpha(EOF);
+ i += !!isascii(EOF);
+ i += !!isblank(EOF);
+ i += !!iscntrl(EOF);
+ i += !!isdigit(EOF);
+ i += !!isgraph(EOF);
+ i += !!islower(EOF);
+ i += !!isprint(EOF);
+ i += !!ispunct(EOF);
+ i += !!isspace(EOF);
+ i += !!isupper(EOF);
+ i += !!isxdigit(EOF);
+ i += !!isalnum(EOF);
+
+ i += !!tolower(EOF);
+ i += !!toupper(EOF);
+
+ if (i)
+ return;
+ else
+ return;
+}
+
+int main(int argc, char **argv) {
+ check_ctype();
+
+ setlocale(LC_ALL, "");
+
+ check_ctype();
+
+ setlocale(LC_ALL, "en_US.UTF-8");
+
+ check_ctype();
+
+ setlocale(LC_CTYPE, "pl_PL.UTF-8");
+
+ check_ctype();
+
+ printf("OK\n");
+
+ // CHECK: OK
+
+ return 0;
+}
OpenPOWER on IntegriCloud