summaryrefslogtreecommitdiff
path: root/lib/msan/lit_tests
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2013-05-27 18:27:12 +0000
committerEd Schouten <ed@FreeBSD.org>2013-05-27 18:27:12 +0000
commit11023dc647fd8f41418da90d59db138400d0f334 (patch)
tree50f0ab80515576749ef638dd0766b70a65904bfa /lib/msan/lit_tests
parent58aabf08b77d221489f10e274812ec60917c21a8 (diff)
Diffstat (limited to 'lib/msan/lit_tests')
-rw-r--r--lib/msan/lit_tests/CMakeLists.txt32
-rw-r--r--lib/msan/lit_tests/Linux/glob.cc26
-rw-r--r--lib/msan/lit_tests/Linux/glob_test_root/aa0
-rw-r--r--lib/msan/lit_tests/Linux/glob_test_root/ab0
-rw-r--r--lib/msan/lit_tests/Linux/glob_test_root/ba0
-rw-r--r--lib/msan/lit_tests/Linux/lit.local.cfg9
-rw-r--r--lib/msan/lit_tests/Linux/syscalls.cc50
-rw-r--r--lib/msan/lit_tests/Unit/lit.cfg26
-rw-r--r--lib/msan/lit_tests/Unit/lit.site.cfg.in17
-rw-r--r--lib/msan/lit_tests/c-strdup.c17
-rw-r--r--lib/msan/lit_tests/default_blacklist.cc3
-rw-r--r--lib/msan/lit_tests/getaddrinfo-positive.cc19
-rw-r--r--lib/msan/lit_tests/getaddrinfo.cc24
-rw-r--r--lib/msan/lit_tests/heap-origin.cc33
-rw-r--r--lib/msan/lit_tests/lit.cfg85
-rw-r--r--lib/msan/lit_tests/lit.site.cfg.in18
-rw-r--r--lib/msan/lit_tests/no_sanitize_memory.cc34
-rw-r--r--lib/msan/lit_tests/no_sanitize_memory_prop.cc33
-rw-r--r--lib/msan/lit_tests/readdir64.cc27
-rw-r--r--lib/msan/lit_tests/stack-origin.cc32
20 files changed, 485 insertions, 0 deletions
diff --git a/lib/msan/lit_tests/CMakeLists.txt b/lib/msan/lit_tests/CMakeLists.txt
new file mode 100644
index 0000000000000..ed2da6b839f57
--- /dev/null
+++ b/lib/msan/lit_tests/CMakeLists.txt
@@ -0,0 +1,32 @@
+set(MSAN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
+set(MSAN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..)
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+ )
+
+if(COMPILER_RT_CAN_EXECUTE_TESTS)
+ # Run MSan tests only if we're sure we may produce working binaries.
+ set(MSAN_TEST_DEPS
+ ${SANITIZER_COMMON_LIT_TEST_DEPS}
+ ${MSAN_RUNTIME_LIBRARIES}
+ msan_blacklist)
+ set(MSAN_TEST_PARAMS
+ msan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+ if(LLVM_INCLUDE_TESTS)
+ list(APPEND MSAN_TEST_DEPS MsanUnitTests)
+ endif()
+ add_lit_testsuite(check-msan "Running the MemorySanitizer tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ PARAMS ${MSAN_TEST_PARAMS}
+ DEPENDS ${MSAN_TEST_DEPS}
+ )
+ set_target_properties(check-msan PROPERTIES FOLDER "MSan tests")
+endif()
diff --git a/lib/msan/lit_tests/Linux/glob.cc b/lib/msan/lit_tests/Linux/glob.cc
new file mode 100644
index 0000000000000..513679c6d3d7f
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/glob.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t %p 2>&1 | FileCheck %s
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t %p 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <glob.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[]) {
+ assert(argc == 2);
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%s/%s", argv[1], "glob_test_root/*a");
+
+ glob_t globbuf;
+ int res = glob(buf, 0, 0, &globbuf);
+
+ printf("%d %s\n", errno, strerror(errno));
+ assert(res == 0);
+ assert(globbuf.gl_pathc == 2);
+ printf("%zu\n", strlen(globbuf.gl_pathv[0]));
+ printf("%zu\n", strlen(globbuf.gl_pathv[1]));
+ printf("PASS\n");
+ // CHECK: PASS
+ return 0;
+}
diff --git a/lib/msan/lit_tests/Linux/glob_test_root/aa b/lib/msan/lit_tests/Linux/glob_test_root/aa
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/glob_test_root/aa
diff --git a/lib/msan/lit_tests/Linux/glob_test_root/ab b/lib/msan/lit_tests/Linux/glob_test_root/ab
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/glob_test_root/ab
diff --git a/lib/msan/lit_tests/Linux/glob_test_root/ba b/lib/msan/lit_tests/Linux/glob_test_root/ba
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/glob_test_root/ba
diff --git a/lib/msan/lit_tests/Linux/lit.local.cfg b/lib/msan/lit_tests/Linux/lit.local.cfg
new file mode 100644
index 0000000000000..57271b8078a49
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Linux']:
+ config.unsupported = True
diff --git a/lib/msan/lit_tests/Linux/syscalls.cc b/lib/msan/lit_tests/Linux/syscalls.cc
new file mode 100644
index 0000000000000..c12eda39189ee
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/syscalls.cc
@@ -0,0 +1,50 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t 2>&1
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t 2>&1
+
+#include <assert.h>
+#include <errno.h>
+#include <glob.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sanitizer/linux_syscall_hooks.h>
+#include <sanitizer/msan_interface.h>
+
+/* Test the presence of __sanitizer_syscall_ in the tool runtime, and general
+ sanity of their behaviour. */
+
+int main(int argc, char *argv[]) {
+ char buf[1000];
+ const int kTen = 10;
+ memset(buf, 0, sizeof(buf));
+ __msan_unpoison(buf, sizeof(buf));
+ __sanitizer_syscall_pre_recvmsg(0, buf, 0);
+ __sanitizer_syscall_pre_rt_sigpending(buf, kTen);
+ __sanitizer_syscall_pre_getdents(0, buf, kTen);
+ __sanitizer_syscall_pre_getdents64(0, buf, kTen);
+
+ __msan_unpoison(buf, sizeof(buf));
+ __sanitizer_syscall_post_recvmsg(0, 0, buf, 0);
+ __sanitizer_syscall_post_rt_sigpending(-1, buf, kTen);
+ __sanitizer_syscall_post_getdents(0, 0, buf, kTen);
+ __sanitizer_syscall_post_getdents64(0, 0, buf, kTen);
+ assert(__msan_test_shadow(buf, sizeof(buf)) == -1);
+
+ __msan_unpoison(buf, sizeof(buf));
+ __sanitizer_syscall_post_recvmsg(kTen, 0, buf, 0);
+
+ // Tell the kernel that the output struct size is 10 bytes, verify that those
+ // bytes are unpoisoned, and the next byte is not.
+ __msan_poison(buf, kTen + 1);
+ __sanitizer_syscall_post_rt_sigpending(0, buf, kTen);
+ assert(__msan_test_shadow(buf, sizeof(buf)) == kTen);
+
+ __msan_poison(buf, kTen + 1);
+ __sanitizer_syscall_post_getdents(kTen, 0, buf, kTen);
+ assert(__msan_test_shadow(buf, sizeof(buf)) == kTen);
+
+ __msan_poison(buf, kTen + 1);
+ __sanitizer_syscall_post_getdents64(kTen, 0, buf, kTen);
+ assert(__msan_test_shadow(buf, sizeof(buf)) == kTen);
+ return 0;
+}
diff --git a/lib/msan/lit_tests/Unit/lit.cfg b/lib/msan/lit_tests/Unit/lit.cfg
new file mode 100644
index 0000000000000..ee379d0deaedd
--- /dev/null
+++ b/lib/msan/lit_tests/Unit/lit.cfg
@@ -0,0 +1,26 @@
+# -*- Python -*-
+
+import os
+
+def get_required_attr(config, attr_name):
+ attr_value = getattr(config, attr_name, None)
+ if not attr_value:
+ lit.fatal("No attribute %r in test configuration! You may need to run "
+ "tests from your build directory or add this attribute "
+ "to lit.site.cfg " % attr_name)
+ return attr_value
+
+# Setup attributes common for all compiler-rt projects.
+compiler_rt_src_root = get_required_attr(config, 'compiler_rt_src_root')
+compiler_rt_lit_unit_cfg = os.path.join(compiler_rt_src_root, "lib",
+ "lit.common.unit.cfg")
+lit.load_config(config, compiler_rt_lit_unit_cfg)
+
+# Setup config name.
+config.name = 'MemorySanitizer-Unit'
+
+# Setup test source and exec root. For unit tests, we define
+# it as build directory with MSan unit tests.
+msan_binary_dir = get_required_attr(config, "msan_binary_dir")
+config.test_exec_root = os.path.join(msan_binary_dir, "tests")
+config.test_source_root = config.test_exec_root
diff --git a/lib/msan/lit_tests/Unit/lit.site.cfg.in b/lib/msan/lit_tests/Unit/lit.site.cfg.in
new file mode 100644
index 0000000000000..a91f6713303a1
--- /dev/null
+++ b/lib/msan/lit_tests/Unit/lit.site.cfg.in
@@ -0,0 +1,17 @@
+## Autogenerated by LLVM/Clang configuration.
+# Do not edit!
+
+config.target_triple = "@TARGET_TRIPLE@"
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@"
+config.llvm_build_mode = "@LLVM_BUILD_MODE@"
+config.msan_binary_dir = "@MSAN_BINARY_DIR@"
+
+try:
+ config.llvm_build_mode = config.llvm_build_mode % lit.params
+except KeyError,e:
+ key, = e.args
+ lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key))
+
+# Let the main config do the real work.
+lit.load_config(config, "@MSAN_SOURCE_DIR@/lit_tests/Unit/lit.cfg")
diff --git a/lib/msan/lit_tests/c-strdup.c b/lib/msan/lit_tests/c-strdup.c
new file mode 100644
index 0000000000000..7772f0f307b72
--- /dev/null
+++ b/lib/msan/lit_tests/c-strdup.c
@@ -0,0 +1,17 @@
+// RUN: %clang_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1
+// RUN: %clang_msan -m64 -O1 %s -o %t && %t >%t.out 2>&1
+// RUN: %clang_msan -m64 -O2 %s -o %t && %t >%t.out 2>&1
+// RUN: %clang_msan -m64 -O3 %s -o %t && %t >%t.out 2>&1
+
+// Test that strdup in C programs is intercepted.
+// GLibC headers translate strdup to __strdup at -O1 and higher.
+
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+ char buf[] = "abc";
+ char *p = strdup(buf);
+ if (*p)
+ exit(0);
+ return 0;
+}
diff --git a/lib/msan/lit_tests/default_blacklist.cc b/lib/msan/lit_tests/default_blacklist.cc
new file mode 100644
index 0000000000000..32cc02257cb09
--- /dev/null
+++ b/lib/msan/lit_tests/default_blacklist.cc
@@ -0,0 +1,3 @@
+// Test that MSan uses the default blacklist from resource directory.
+// RUN: %clangxx_msan -### %s 2>&1 | FileCheck %s
+// CHECK: fsanitize-blacklist={{.*}}msan_blacklist.txt
diff --git a/lib/msan/lit_tests/getaddrinfo-positive.cc b/lib/msan/lit_tests/getaddrinfo-positive.cc
new file mode 100644
index 0000000000000..f16679cc2aa26
--- /dev/null
+++ b/lib/msan/lit_tests/getaddrinfo-positive.cc
@@ -0,0 +1,19 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdlib.h>
+
+int main(void) {
+ struct addrinfo *ai;
+ struct addrinfo hint;
+ int res = getaddrinfo("localhost", NULL, &hint, &ai);
+ // CHECK: UMR in __interceptor_getaddrinfo at offset 0 inside
+ // CHECK: WARNING: Use of uninitialized value
+ // CHECK: #0 {{.*}} in main {{.*}}getaddrinfo-positive.cc:[[@LINE-3]]
+ return 0;
+}
diff --git a/lib/msan/lit_tests/getaddrinfo.cc b/lib/msan/lit_tests/getaddrinfo.cc
new file mode 100644
index 0000000000000..0518cf4733d0f
--- /dev/null
+++ b/lib/msan/lit_tests/getaddrinfo.cc
@@ -0,0 +1,24 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdlib.h>
+
+void poison_stack_ahead() {
+ char buf[100000];
+ // With -O0 this poisons a large chunk of stack.
+}
+
+int main(void) {
+ poison_stack_ahead();
+
+ struct addrinfo *ai;
+
+ // This should trigger loading of libnss_dns and friends.
+ // Those libraries are typically uninstrumented.They will call strlen() on a
+ // stack-allocated buffer, which is very likely to be poisoned. Test that we
+ // don't report this as an UMR.
+ int res = getaddrinfo("not-in-etc-hosts", NULL, NULL, &ai);
+ return 0;
+}
diff --git a/lib/msan/lit_tests/heap-origin.cc b/lib/msan/lit_tests/heap-origin.cc
new file mode 100644
index 0000000000000..54e2c31438ff8
--- /dev/null
+++ b/lib/msan/lit_tests/heap-origin.cc
@@ -0,0 +1,33 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ char *volatile x = (char*)malloc(5 * sizeof(char));
+ if (*x)
+ exit(0);
+ // CHECK: WARNING: Use of uninitialized value
+ // CHECK: {{#0 0x.* in main .*heap-origin.cc:}}[[@LINE-3]]
+
+ // CHECK-ORIGINS: Uninitialized value was created by a heap allocation
+ // CHECK-ORIGINS: {{#0 0x.* in .*malloc}}
+ // CHECK-ORIGINS: {{#1 0x.* in main .*heap-origin.cc:}}[[@LINE-8]]
+
+ // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*heap-origin.cc:.* main}}
+ return 0;
+}
diff --git a/lib/msan/lit_tests/lit.cfg b/lib/msan/lit_tests/lit.cfg
new file mode 100644
index 0000000000000..42381885fe8e5
--- /dev/null
+++ b/lib/msan/lit_tests/lit.cfg
@@ -0,0 +1,85 @@
+# -*- Python -*-
+
+import os
+
+def get_required_attr(config, attr_name):
+ attr_value = getattr(config, attr_name, None)
+ if not attr_value:
+ lit.fatal("No attribute %r in test configuration! You may need to run "
+ "tests from your build directory or add this attribute "
+ "to lit.site.cfg " % attr_name)
+ return attr_value
+
+# Setup config name.
+config.name = 'MemorySanitizer'
+
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+def DisplayNoConfigMessage():
+ lit.fatal("No site specific configuration available! " +
+ "Try running your test from the build tree or running " +
+ "make check-msan")
+
+# Figure out LLVM source root.
+llvm_src_root = getattr(config, 'llvm_src_root', None)
+if llvm_src_root is None:
+ # We probably haven't loaded the site-specific configuration: the user
+ # is likely trying to run a test file directly, and the site configuration
+ # wasn't created by the build system.
+ msan_site_cfg = lit.params.get('msan_site_config', None)
+ if (msan_site_cfg) and (os.path.exists(msan_site_cfg)):
+ lit.load_config(config, msan_site_cfg)
+ raise SystemExit
+
+ # Try to guess the location of site-specific configuration using llvm-config
+ # util that can point where the build tree is.
+ llvm_config = lit.util.which("llvm-config", config.environment["PATH"])
+ if not llvm_config:
+ DisplayNoConfigMessage()
+
+ # Find out the presumed location of generated site config.
+ llvm_obj_root = lit.util.capture(["llvm-config", "--obj-root"]).strip()
+ msan_site_cfg = os.path.join(llvm_obj_root, "projects", "compiler-rt",
+ "lib", "msan", "lit_tests", "lit.site.cfg")
+ if (not msan_site_cfg) or (not os.path.exists(msan_site_cfg)):
+ DisplayNoConfigMessage()
+
+ lit.load_config(config, msan_site_cfg)
+ raise SystemExit
+
+# Setup attributes common for all compiler-rt projects.
+compiler_rt_src_root = get_required_attr(config, "compiler_rt_src_root")
+compiler_rt_lit_cfg = os.path.join(compiler_rt_src_root, "lib",
+ "lit.common.cfg")
+if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)):
+ lit.fatal("Can't find common compiler-rt lit config at: %r"
+ % compiler_rt_lit_cfg)
+lit.load_config(config, compiler_rt_lit_cfg)
+
+# Setup default compiler flags used with -fsanitize=memory option.
+clang_msan_cflags = ["-fsanitize=memory",
+ "-mno-omit-leaf-frame-pointer",
+ "-fno-omit-frame-pointer",
+ "-fno-optimize-sibling-calls",
+ "-g"]
+clang_msan_cxxflags = ["-ccc-cxx "] + clang_msan_cflags
+config.substitutions.append( ("%clang_msan ",
+ " ".join([config.clang] + clang_msan_cflags) +
+ " ") )
+config.substitutions.append( ("%clangxx_msan ",
+ " ".join([config.clang] + clang_msan_cxxflags) +
+ " ") )
+
+# Setup path to external LLVM symbolizer to run MemorySanitizer output tests.
+llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
+if llvm_tools_dir:
+ llvm_symbolizer_path = os.path.join(llvm_tools_dir, "llvm-symbolizer")
+ config.environment['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer_path
+
+# Default test suffixes.
+config.suffixes = ['.c', '.cc', '.cpp']
+
+# MemorySanitizer tests are currently supported on Linux only.
+if config.host_os not in ['Linux']:
+ config.unsupported = True
diff --git a/lib/msan/lit_tests/lit.site.cfg.in b/lib/msan/lit_tests/lit.site.cfg.in
new file mode 100644
index 0000000000000..3b969e0b06142
--- /dev/null
+++ b/lib/msan/lit_tests/lit.site.cfg.in
@@ -0,0 +1,18 @@
+config.target_triple = "@TARGET_TRIPLE@"
+config.host_os = "@HOST_OS@"
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.clang = "@LLVM_BINARY_DIR@/bin/clang"
+
+# LLVM tools dir can be passed in lit parameters, so try to
+# apply substitution.
+try:
+ config.llvm_tools_dir = config.llvm_tools_dir % lit.params
+except KeyError,e:
+ key, = e.args
+ lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key))
+
+# Let the main config do the real work.
+lit.load_config(config, "@MSAN_SOURCE_DIR@/lit_tests/lit.cfg")
diff --git a/lib/msan/lit_tests/no_sanitize_memory.cc b/lib/msan/lit_tests/no_sanitize_memory.cc
new file mode 100644
index 0000000000000..48afc17e35e92
--- /dev/null
+++ b/lib/msan/lit_tests/no_sanitize_memory.cc
@@ -0,0 +1,34 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O1 %s -o %t && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O2 %s -o %t && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t >%t.out 2>&1
+
+// RUN: %clangxx_msan -m64 -O0 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O1 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O2 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O3 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1
+
+// Test that (no_sanitize_memory) functions
+// * don't check shadow values (-DCHECK_IN_F)
+// * treat all values loaded from memory as fully initialized (-UCHECK_IN_F)
+
+#include <stdlib.h>
+#include <stdio.h>
+
+__attribute__((noinline))
+__attribute__((no_sanitize_memory))
+int f(void) {
+ int x;
+ int * volatile p = &x;
+#ifdef CHECK_IN_F
+ if (*p)
+ exit(0);
+#endif
+ return *p;
+}
+
+int main(void) {
+ if (f())
+ exit(0);
+ return 0;
+}
diff --git a/lib/msan/lit_tests/no_sanitize_memory_prop.cc b/lib/msan/lit_tests/no_sanitize_memory_prop.cc
new file mode 100644
index 0000000000000..c74ca6b89db98
--- /dev/null
+++ b/lib/msan/lit_tests/no_sanitize_memory_prop.cc
@@ -0,0 +1,33 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1
+// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// Test that (no_sanitize_memory) functions propagate shadow.
+
+// Note that at -O0 there is no report, because 'x' in 'f' is spilled to the
+// stack, and then loaded back as a fully initialiazed value (due to
+// no_sanitize_memory attribute).
+
+#include <stdlib.h>
+#include <stdio.h>
+
+__attribute__((noinline))
+__attribute__((no_sanitize_memory))
+int f(int x) {
+ return x;
+}
+
+int main(void) {
+ int x;
+ int * volatile p = &x;
+ int y = f(*p);
+ // CHECK: WARNING: Use of uninitialized value
+ // CHECK: {{#0 0x.* in main .*no_sanitize_memory_prop.cc:}}[[@LINE+1]]
+ if (y)
+ exit(0);
+ return 0;
+}
diff --git a/lib/msan/lit_tests/readdir64.cc b/lib/msan/lit_tests/readdir64.cc
new file mode 100644
index 0000000000000..0ec106c741f51
--- /dev/null
+++ b/lib/msan/lit_tests/readdir64.cc
@@ -0,0 +1,27 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O1 %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O2 %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t
+
+// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O1 -D_FILE_OFFSET_BITS=64 %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O2 -D_FILE_OFFSET_BITS=64 %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O3 -D_FILE_OFFSET_BITS=64 %s -o %t && %t
+
+// Test that readdir64 is intercepted as well as readdir.
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+
+
+int main(void) {
+ DIR *dir = opendir(".");
+ struct dirent *d = readdir(dir);
+ if (d->d_name[0]) {
+ closedir(dir);
+ exit(0);
+ }
+ closedir(dir);
+ return 0;
+}
diff --git a/lib/msan/lit_tests/stack-origin.cc b/lib/msan/lit_tests/stack-origin.cc
new file mode 100644
index 0000000000000..90f5273092242
--- /dev/null
+++ b/lib/msan/lit_tests/stack-origin.cc
@@ -0,0 +1,32 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ int x;
+ int *volatile p = &x;
+ if (*p)
+ exit(0);
+ // CHECK: WARNING: Use of uninitialized value
+ // CHECK: {{#0 0x.* in main .*stack-origin.cc:}}[[@LINE-3]]
+
+ // CHECK-ORIGINS: Uninitialized value was created by an allocation of 'x' in the stack frame of function 'main'
+
+ // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*stack-origin.cc:.* main}}
+ return 0;
+}