aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt7
-rw-r--r--test/asan/CMakeLists.txt6
-rw-r--r--test/asan/TestCases/Windows/dll_host.cc7
-rw-r--r--test/asan/TestCases/Windows/globals_multiple_dlls.cc51
-rw-r--r--test/asan/TestCases/Windows/oom.cc12
-rw-r--r--test/asan/TestCases/Windows/symbols_path.cc22
-rw-r--r--test/asan/TestCases/dlclose-test.cc7
-rw-r--r--test/asan/TestCases/gc-test.cc6
-rw-r--r--test/asan/lit.cfg8
-rw-r--r--test/cfi/CMakeLists.txt23
-rw-r--r--test/cfi/anon-namespace.cpp93
-rw-r--r--test/cfi/lit.cfg35
-rw-r--r--test/cfi/lit.site.cfg.in2
-rw-r--r--test/cfi/multiple-inheritance.cpp82
-rw-r--r--test/cfi/overwrite.cpp67
-rw-r--r--test/cfi/simple-fail.cpp99
-rw-r--r--test/cfi/simple-pass.cpp97
-rw-r--r--test/cfi/utils.h53
-rw-r--r--test/cfi/vdtor.cpp62
-rw-r--r--test/lit.common.cfg3
-rw-r--r--test/lit.common.configured.in2
-rw-r--r--test/lsan/lit.common.cfg4
-rw-r--r--test/msan/mmap_below_shadow.cc5
-rw-r--r--test/msan/strlen_of_shadow.cc4
-rw-r--r--test/msan/vector_select.cc8
-rw-r--r--test/sanitizer_common/TestCases/Linux/ptrace.cc14
-rw-r--r--test/tsan/global_race.cc6
-rw-r--r--test/tsan/global_race2.cc6
-rw-r--r--test/tsan/global_race3.cc6
-rw-r--r--test/tsan/map32bit.cc3
-rw-r--r--test/tsan/mmap_large.cc4
-rw-r--r--test/tsan/signal_segv_handler.cc39
-rw-r--r--test/tsan/test.h9
-rw-r--r--test/ubsan/TestCases/TypeCheck/Function/function.cpp21
-rw-r--r--test/ubsan/TestCases/TypeCheck/null.cpp10
-rw-r--r--test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp2
-rw-r--r--test/ubsan/TestCases/TypeCheck/vptr.cpp18
37 files changed, 861 insertions, 42 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2ceb86463ae0..85a1735b1cf9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -7,6 +7,12 @@ configure_lit_site_cfg(
# add_subdirectory(builtins)
set(SANITIZER_COMMON_LIT_TEST_DEPS)
+if(COMPILER_RT_STANDALONE_BUILD)
+ add_executable(FileCheck IMPORTED GLOBAL)
+ set_property(TARGET FileCheck PROPERTY IMPORTED_LOCATION ${LLVM_TOOLS_BINARY_DIR}/FileCheck)
+ list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS FileCheck)
+endif()
+
# When ANDROID, we build tests with the host compiler (i.e. CMAKE_C_COMPILER),
# and run tests with tools from the host toolchain.
if(NOT ANDROID)
@@ -51,6 +57,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
if(COMPILER_RT_HAS_UBSAN)
add_subdirectory(ubsan)
endif()
+ add_subdirectory(cfi)
endif()
if(COMPILER_RT_STANDALONE_BUILD)
diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt
index 0c46ef7e6e31..e1b81264604d 100644
--- a/test/asan/CMakeLists.txt
+++ b/test/asan/CMakeLists.txt
@@ -55,11 +55,7 @@ foreach(arch ${ASAN_SUPPORTED_ARCH})
endforeach()
set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
-if(COMPILER_RT_STANDALONE_BUILD)
- add_executable(FileCheck IMPORTED GLOBAL)
- set_property(TARGET FileCheck PROPERTY IMPORTED_LOCATION ${LLVM_TOOLS_BINARY_DIR}/FileCheck)
- list(APPEND ASAN_TEST_DEPS FileCheck)
-else()
+if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND ASAN_TEST_DEPS asan)
endif()
set(ASAN_DYNAMIC_TEST_DEPS ${ASAN_TEST_DEPS})
diff --git a/test/asan/TestCases/Windows/dll_host.cc b/test/asan/TestCases/Windows/dll_host.cc
index d3b4c149d009..71721fe29e88 100644
--- a/test/asan/TestCases/Windows/dll_host.cc
+++ b/test/asan/TestCases/Windows/dll_host.cc
@@ -6,9 +6,14 @@
//
// Get the list of ASan wrappers exported by the main module RTL:
// RUN: dumpbin /EXPORTS %t | grep -o "__asan_wrap[^ ]*" | grep -v @ | sort | uniq > %t.exported_wrappers
+// FIXME: we should really check the other __asan exports too.
+// RUN: dumpbin /EXPORTS %t | grep -o "__sanitizer_[^ ]*" | grep -v @ | sort | uniq >> %t.exported_wrappers
//
// Get the list of ASan wrappers imported by the DLL RTL:
-// RUN: grep INTERCEPT_LIBRARY_FUNCTION %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed "s/.*(\(.*\)).*/__asan_wrap_\1/" | sort | uniq > %t.dll_imports
+// [BEWARE: be really careful with the sed commands, as this test can be run
+// from different environemnts with different shells and seds]
+// RUN: grep INTERCEPT_LIBRARY_FUNCTION %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(/__asan_wrap_/ | sed -e s/).*// | sort | uniq > %t.dll_imports
+// RUN: grep "^INTERFACE_FUNCTION.*sanitizer" %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(// | sed -e s/).*// | sort | uniq >> %t.dll_imports
//
// Now make sure the DLL thunk imports everything:
// RUN: echo
diff --git a/test/asan/TestCases/Windows/globals_multiple_dlls.cc b/test/asan/TestCases/Windows/globals_multiple_dlls.cc
new file mode 100644
index 000000000000..634e5782796c
--- /dev/null
+++ b/test/asan/TestCases/Windows/globals_multiple_dlls.cc
@@ -0,0 +1,51 @@
+// Make sure everything works even if the main module doesn't have any stack
+// variables, thus doesn't explicitly reference any symbol exported by the
+// runtime thunk.
+//
+// RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll
+// RUN: %clang_cl_asan -O0 -DEXE %s -Fe%te.exe
+// RUN: env ASAN_OPTIONS=report_globals=2 %run %te.exe %t.dll 2>&1 | FileCheck %s
+
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+extern "C" {
+#if defined(EXE)
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ printf("Usage: %s [client].dll\n", argv[0]);
+ return 101;
+ }
+ const char *dll_name = argv[1];
+
+// CHECK: time to load DLL
+ printf("time to load DLL\n");
+ fflush(0);
+
+// On DLL load, the "in DLL\n" string is registered:
+// CHECK: Added Global{{.*}} size=19
+// CHECK: in DLL(reason=1)
+ HMODULE dll = LoadLibrary(dll_name);
+ if (dll == NULL)
+ return 3;
+
+// CHECK: in DLL(reason=0)
+// CHECK-NEXT: Removed Global{{.*}} size=19
+ if (!FreeLibrary(dll))
+ return 4;
+
+// CHECK: bye!
+ printf("bye!\n");
+ fflush(0);
+}
+#elif defined(DLL)
+BOOL WINAPI DllMain(HMODULE, DWORD reason, LPVOID) {
+ printf("in DLL(reason=%d)\n", (int)reason);
+ fflush(0);
+ return TRUE;
+}
+#else
+# error oops!
+#endif
+}
diff --git a/test/asan/TestCases/Windows/oom.cc b/test/asan/TestCases/Windows/oom.cc
new file mode 100644
index 000000000000..b24cddf17a97
--- /dev/null
+++ b/test/asan/TestCases/Windows/oom.cc
@@ -0,0 +1,12 @@
+// RUN: %clang_cl_asan -O0 %s -Fe%t
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+#include <malloc.h>
+
+int main() {
+ while (true) {
+ void *ptr = malloc(200 * 1024 * 1024); // 200MB
+ free(ptr);
+ }
+// CHECK: failed to allocate
+}
diff --git a/test/asan/TestCases/Windows/symbols_path.cc b/test/asan/TestCases/Windows/symbols_path.cc
new file mode 100644
index 000000000000..3c69f8861d78
--- /dev/null
+++ b/test/asan/TestCases/Windows/symbols_path.cc
@@ -0,0 +1,22 @@
+// Make sure symbolization works even if the path to the .exe file changes.
+// RUN: mkdir %t || true
+// RUN: %clang_cl_asan -O0 %s -Fe%t/symbols_path.exe
+// RUN: not %run %t/symbols_path.exe 2>&1 | FileCheck %s
+// RUN: mkdir %t2 || true
+// RUN: mv %t/* %t2
+// RUN: not %run %t2/symbols_path.exe 2>&1 | FileCheck %s
+
+#include <malloc.h>
+
+int main() {
+ char *buffer = (char*)malloc(42);
+ buffer[-1] = 42;
+// CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+// CHECK: WRITE of size 1 at [[ADDR]] thread T0
+// CHECK-NEXT: {{#0 .* main .*symbols_path.cc}}:[[@LINE-3]]
+// CHECK: [[ADDR]] is located 1 bytes to the left of 42-byte region
+// CHECK: allocated by thread T0 here:
+// CHECK-NEXT: {{#0 .* malloc }}
+// CHECK-NEXT: {{#1 .* main .*symbols_path.cc}}:[[@LINE-8]]
+ free(buffer);
+}
diff --git a/test/asan/TestCases/dlclose-test.cc b/test/asan/TestCases/dlclose-test.cc
index 2d31aee5a32f..369abd3127cc 100644
--- a/test/asan/TestCases/dlclose-test.cc
+++ b/test/asan/TestCases/dlclose-test.cc
@@ -33,6 +33,13 @@
#include <string>
+#if defined(__FreeBSD__)
+// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before
+// that, it was never implemented. So just define it to zero.
+#undef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
using std::string;
typedef int *(fun_t)();
diff --git a/test/asan/TestCases/gc-test.cc b/test/asan/TestCases/gc-test.cc
index ffbea85b2650..4ffa51dd22d3 100644
--- a/test/asan/TestCases/gc-test.cc
+++ b/test/asan/TestCases/gc-test.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_asan %s -pthread -o %t
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: %clangxx_asan -O3 %s -pthread -o %t
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
// REQUIRES: stable-runtime
#include <assert.h>
@@ -9,6 +12,7 @@
#include <sanitizer/asan_interface.h>
static const int kNumThreads = 2;
+static const int kLeftRedzoneSize = sizeof(void *) * 4;
void *Thread(void *unused) {
void *fake_stack = __asan_get_current_fake_stack();
@@ -23,7 +27,7 @@ void *Thread(void *unused) {
assert(real_stack);
assert((char*)beg <= (char*)&var[0]);
assert((char*)end > (char*)&var[0]);
- for (int i = -32; i < 15; i++) {
+ for (int i = -kLeftRedzoneSize; i < 15; i++) {
void *beg1, *end1;
char *ptr = &var[0] + i;
void *real_stack1 =
diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg
index 8be7062614b3..a6f443cfb6a5 100644
--- a/test/asan/lit.cfg
+++ b/test/asan/lit.cfg
@@ -3,6 +3,8 @@
import os
import platform
+import lit.formats
+
def get_required_attr(config, attr_name):
attr_value = getattr(config, attr_name, None)
if attr_value == None:
@@ -15,6 +17,8 @@ def get_required_attr(config, attr_name):
def push_dynamic_library_lookup_path(config, new_path):
if platform.system() == 'Windows':
dynamic_library_lookup_var = 'PATH'
+ elif platform.system() == 'Darwin':
+ dynamic_library_lookup_var = 'DYLD_LIBRARY_PATH'
else:
dynamic_library_lookup_var = 'LD_LIBRARY_PATH'
@@ -25,6 +29,10 @@ def push_dynamic_library_lookup_path(config, new_path):
# Setup config name.
config.name = 'AddressSanitizer' + config.name_suffix
+# testFormat: The test format to use to interpret tests.
+external_bash = (not sys.platform in ['win32'])
+config.test_format = lit.formats.ShTest(external_bash)
+
# Setup source root.
config.test_source_root = os.path.dirname(__file__)
diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt
new file mode 100644
index 000000000000..f519fb089505
--- /dev/null
+++ b/test/cfi/CMakeLists.txt
@@ -0,0 +1,23 @@
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+
+set(CFI_TEST_DEPS)
+if(NOT COMPILER_RT_STANDALONE_BUILD)
+ list(APPEND CFI_TEST_DEPS
+ FileCheck
+ clang
+ not
+ )
+ if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR)
+ list(APPEND CFI_TEST_DEPS
+ LLVMgold
+ )
+ endif()
+endif()
+
+add_lit_testsuite(check-cfi "Running the cfi regression tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${CFI_TEST_DEPS})
+set_target_properties(check-cfi PROPERTIES FOLDER "Tests")
diff --git a/test/cfi/anon-namespace.cpp b/test/cfi/anon-namespace.cpp
new file mode 100644
index 000000000000..0c2c689966f1
--- /dev/null
+++ b/test/cfi/anon-namespace.cpp
@@ -0,0 +1,93 @@
+// RUN: %clangxx_cfi -c -DTU1 -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -c -DTU1 -o %t1.o %s
+// RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx -o %t %t1.o %t2.o
+// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// Tests that the CFI mechanism treats classes in the anonymous namespace in
+// different translation units as having distinct identities. This is done by
+// compiling two translation units TU1 and TU2 containing a class named B in an
+// anonymous namespace, and testing that the program crashes if TU2 attempts to
+// use a TU1 B as a TU2 B.
+
+// FIXME: This test should not require that the paths supplied to the compiler
+// are different. It currently does so because bitset names have global scope
+// so we have to mangle the file path into the bitset name.
+
+#include <stdio.h>
+#include "utils.h"
+
+struct A {
+ virtual void f() = 0;
+};
+
+namespace {
+
+struct B : A {
+ virtual void f() {}
+};
+
+}
+
+A *mkb();
+
+#ifdef TU1
+
+A *mkb() {
+ return new B;
+}
+
+#endif // TU1
+
+#ifdef TU2
+
+int main() {
+#ifdef B32
+ break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+ break_optimization(new Deriver<B, 2>);
+#endif
+
+ A *a = mkb();
+ break_optimization(a);
+
+ // CFI: 1
+ // NCFI: 1
+ fprintf(stderr, "1\n");
+
+ ((B *)a)->f(); // UB here
+
+ // CFI-NOT: 2
+ // NCFI: 2
+ fprintf(stderr, "2\n");
+}
+
+#endif // TU2
diff --git a/test/cfi/lit.cfg b/test/cfi/lit.cfg
new file mode 100644
index 000000000000..d78820daa055
--- /dev/null
+++ b/test/cfi/lit.cfg
@@ -0,0 +1,35 @@
+import lit.formats
+import os
+import subprocess
+import sys
+
+config.name = 'cfi'
+config.suffixes = ['.cpp']
+config.test_source_root = os.path.dirname(__file__)
+
+def is_darwin_lto_supported():
+ return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib'))
+
+def is_linux_lto_supported():
+ if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')):
+ return False
+
+ ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE)
+ ld_out = ld_cmd.stdout.read().decode()
+ ld_cmd.wait()
+
+ if not '-plugin' in ld_out:
+ return False
+
+ return True
+
+clangxx = ' '.join([config.clang] + config.cxx_mode_flags)
+
+config.substitutions.append((r"%clangxx ", clangxx + ' '))
+
+if sys.platform == 'darwin' and is_darwin_lto_supported():
+ config.substitutions.append((r"%clangxx_cfi ", 'env DYLD_LIBRARY_PATH=' + config.llvm_shlib_dir + ' ' + clangxx + ' -fsanitize=cfi '))
+elif sys.platform.startswith('linux') and is_linux_lto_supported():
+ config.substitutions.append((r"%clangxx_cfi ", clangxx + ' -fuse-ld=gold -fsanitize=cfi '))
+else:
+ config.unsupported = True
diff --git a/test/cfi/lit.site.cfg.in b/test/cfi/lit.site.cfg.in
new file mode 100644
index 000000000000..76897e701874
--- /dev/null
+++ b/test/cfi/lit.site.cfg.in
@@ -0,0 +1,2 @@
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/test/cfi/multiple-inheritance.cpp b/test/cfi/multiple-inheritance.cpp
new file mode 100644
index 000000000000..523af6f72f2f
--- /dev/null
+++ b/test/cfi/multiple-inheritance.cpp
@@ -0,0 +1,82 @@
+// RUN: %clangxx_cfi -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -o %t %s
+// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// Tests that the CFI mechanism is sensitive to multiple inheritance and only
+// permits calls via virtual tables for the correct base class.
+
+#include <stdio.h>
+#include "utils.h"
+
+struct A {
+ virtual void f() = 0;
+};
+
+struct B {
+ virtual void g() = 0;
+};
+
+struct C : A, B {
+ virtual void f(), g();
+};
+
+void C::f() {}
+void C::g() {}
+
+int main(int argc, char **argv) {
+#ifdef B32
+ break_optimization(new Deriver<A, 0>);
+ break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+ break_optimization(new Deriver<A, 0>);
+ break_optimization(new Deriver<A, 1>);
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+ break_optimization(new Deriver<A, 0>);
+ break_optimization(new Deriver<A, 1>);
+ break_optimization(new Deriver<A, 2>);
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+ break_optimization(new Deriver<B, 2>);
+#endif
+
+ C *c = new C;
+ break_optimization(c);
+
+ // CFI: 1
+ // NCFI: 1
+ fprintf(stderr, "1\n");
+
+ if (argc > 1) {
+ A *a = c;
+ ((B *)a)->g(); // UB here
+ } else {
+ B *b = c;
+ ((A *)b)->f(); // UB here
+ }
+
+ // CFI-NOT: 2
+ // NCFI: 2
+ fprintf(stderr, "2\n");
+}
diff --git a/test/cfi/overwrite.cpp b/test/cfi/overwrite.cpp
new file mode 100644
index 000000000000..d7e58d9277e9
--- /dev/null
+++ b/test/cfi/overwrite.cpp
@@ -0,0 +1,67 @@
+// RUN: %clangxx_cfi -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -o %t %s
+// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// Tests that the CFI mechanism crashes the program when a virtual table is
+// replaced with a compatible table of function pointers that does not belong to
+// any class, by manually overwriting the virtual table of an object and
+// attempting to make a call through it.
+
+#include <stdio.h>
+#include "utils.h"
+
+struct A {
+ virtual void f();
+};
+
+void A::f() {}
+
+void foo() {
+ fprintf(stderr, "foo\n");
+}
+
+void *fake_vtable[] = { (void *)&foo };
+
+int main() {
+#ifdef B32
+ break_optimization(new Deriver<A, 0>);
+#endif
+
+#ifdef B64
+ break_optimization(new Deriver<A, 0>);
+ break_optimization(new Deriver<A, 1>);
+#endif
+
+#ifdef BM
+ break_optimization(new Deriver<A, 0>);
+ break_optimization(new Deriver<A, 1>);
+ break_optimization(new Deriver<A, 2>);
+#endif
+
+ A *a = new A;
+ *((void **)a) = fake_vtable; // UB here
+ break_optimization(a);
+
+ // CFI: 1
+ // NCFI: 1
+ fprintf(stderr, "1\n");
+
+ // CFI-NOT: foo
+ // NCFI: foo
+ a->f();
+
+ // CFI-NOT: 2
+ // NCFI: 2
+ fprintf(stderr, "2\n");
+}
diff --git a/test/cfi/simple-fail.cpp b/test/cfi/simple-fail.cpp
new file mode 100644
index 000000000000..cf24f86e0064
--- /dev/null
+++ b/test/cfi/simple-fail.cpp
@@ -0,0 +1,99 @@
+// RUN: %clangxx_cfi -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O1 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O1 -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O1 -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O1 -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O2 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O2 -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O2 -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O2 -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O3 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O3 -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O3 -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -O3 -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -o %t %s
+// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// Tests that the CFI mechanism crashes the program when making a virtual call
+// to an object of the wrong class but with a compatible vtable, by casting a
+// pointer to such an object and attempting to make a call through it.
+
+#include <stdio.h>
+#include "utils.h"
+
+struct A {
+ virtual void f();
+};
+
+void A::f() {}
+
+struct B {
+ virtual void f();
+};
+
+void B::f() {}
+
+int main() {
+#ifdef B32
+ break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+ break_optimization(new Deriver<B, 2>);
+#endif
+
+ A *a = new A;
+ break_optimization(a);
+
+ // CFI: 1
+ // NCFI: 1
+ fprintf(stderr, "1\n");
+
+ ((B *)a)->f(); // UB here
+
+ // CFI-NOT: 2
+ // NCFI: 2
+ fprintf(stderr, "2\n");
+}
diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp
new file mode 100644
index 000000000000..50e7d9256084
--- /dev/null
+++ b/test/cfi/simple-pass.cpp
@@ -0,0 +1,97 @@
+// RUN: %clangxx_cfi -o %t %s
+// RUN: %t
+
+// Tests that the CFI mechanism does not crash the program when making various
+// kinds of valid calls involving classes with various different linkages and
+// types of inheritance.
+
+#include "utils.h"
+
+struct A {
+ virtual void f();
+};
+
+void A::f() {}
+
+struct A2 : A {
+ virtual void f();
+};
+
+void A2::f() {}
+
+struct B {
+ virtual void f() {}
+};
+
+struct B2 : B {
+ virtual void f() {}
+};
+
+namespace {
+
+struct C {
+ virtual void f();
+};
+
+void C::f() {}
+
+struct C2 : C {
+ virtual void f();
+};
+
+void C2::f() {}
+
+struct D {
+ virtual void f() {}
+};
+
+struct D2 : D {
+ virtual void f() {}
+};
+
+}
+
+struct E {
+ virtual void f() {}
+};
+
+struct E2 : virtual E {
+ virtual void f() {}
+};
+
+int main() {
+ A *a = new A;
+ break_optimization(a);
+ a->f();
+ a = new A2;
+ break_optimization(a);
+ a->f();
+
+ B *b = new B;
+ break_optimization(b);
+ b->f();
+ b = new B2;
+ break_optimization(b);
+ b->f();
+
+ C *c = new C;
+ break_optimization(c);
+ c->f();
+ c = new C2;
+ break_optimization(c);
+ c->f();
+
+ D *d = new D;
+ break_optimization(d);
+ d->f();
+ d = new D2;
+ break_optimization(d);
+ d->f();
+
+ E *e = new E;
+ break_optimization(e);
+ e->f();
+ e = new E2;
+ break_optimization(e);
+ e->f();
+}
diff --git a/test/cfi/utils.h b/test/cfi/utils.h
new file mode 100644
index 000000000000..5c290d151069
--- /dev/null
+++ b/test/cfi/utils.h
@@ -0,0 +1,53 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+inline void break_optimization(void *arg) {
+ __asm__ __volatile__("" : : "r" (arg) : "memory");
+}
+
+// Tests will instantiate this class to pad out bit sets to test out the various
+// ways we can represent the bit set (32-bit inline, 64-bit inline, memory).
+// This class has 37 virtual member functions, which forces us to use a
+// pointer-aligned bitset.
+template <typename T, unsigned I>
+class Deriver : T {
+ virtual void f() {}
+ virtual void g() {}
+ virtual void f1() {}
+ virtual void f2() {}
+ virtual void f3() {}
+ virtual void f4() {}
+ virtual void f5() {}
+ virtual void f6() {}
+ virtual void f7() {}
+ virtual void f8() {}
+ virtual void f9() {}
+ virtual void f10() {}
+ virtual void f11() {}
+ virtual void f12() {}
+ virtual void f13() {}
+ virtual void f14() {}
+ virtual void f15() {}
+ virtual void f16() {}
+ virtual void f17() {}
+ virtual void f18() {}
+ virtual void f19() {}
+ virtual void f20() {}
+ virtual void f21() {}
+ virtual void f22() {}
+ virtual void f23() {}
+ virtual void f24() {}
+ virtual void f25() {}
+ virtual void f26() {}
+ virtual void f27() {}
+ virtual void f28() {}
+ virtual void f29() {}
+ virtual void f30() {}
+ virtual void f31() {}
+ virtual void f32() {}
+ virtual void f33() {}
+ virtual void f34() {}
+ virtual void f35() {}
+};
+
+#endif
diff --git a/test/cfi/vdtor.cpp b/test/cfi/vdtor.cpp
new file mode 100644
index 000000000000..e21883c380dd
--- /dev/null
+++ b/test/cfi/vdtor.cpp
@@ -0,0 +1,62 @@
+// RUN: %clangxx_cfi -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -o %t %s
+// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// Tests that the CFI enforcement also applies to virtual destructor calls made
+// via 'delete'.
+
+#include <stdio.h>
+#include "utils.h"
+
+struct A {
+ virtual ~A();
+};
+
+A::~A() {}
+
+struct B {
+ virtual ~B();
+};
+
+B::~B() {}
+
+int main() {
+#ifdef B32
+ break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+ break_optimization(new Deriver<B, 0>);
+ break_optimization(new Deriver<B, 1>);
+ break_optimization(new Deriver<B, 2>);
+#endif
+
+ A *a = new A;
+ break_optimization(a);
+
+ // CFI: 1
+ // NCFI: 1
+ fprintf(stderr, "1\n");
+
+ delete (B *)a; // UB here
+
+ // CFI-NOT: 2
+ // NCFI: 2
+ fprintf(stderr, "2\n");
+}
diff --git a/test/lit.common.cfg b/test/lit.common.cfg
index 0ee2b84481da..0a551862c32b 100644
--- a/test/lit.common.cfg
+++ b/test/lit.common.cfg
@@ -61,7 +61,8 @@ path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
config.environment['PATH'] = path
# Help MSVS link.exe find the standard libraries.
-if platform.system() == 'Windows':
+# Make sure we only try to use it when targetting Windows.
+if platform.system() == 'Windows' and '-win' in config.target_triple:
config.environment['LIB'] = os.environ['LIB']
# Use ugly construction to explicitly prohibit "clang", "clang++" etc.
diff --git a/test/lit.common.configured.in b/test/lit.common.configured.in
index ceab67d4ad07..4a5966e44f32 100644
--- a/test/lit.common.configured.in
+++ b/test/lit.common.configured.in
@@ -18,6 +18,8 @@ set_default("llvm_obj_root", "@LLVM_BINARY_DIR@")
set_default("compiler_rt_src_root", "@COMPILER_RT_SOURCE_DIR@")
set_default("compiler_rt_obj_root", "@COMPILER_RT_BINARY_DIR@")
set_default("llvm_tools_dir", "@LLVM_TOOLS_DIR@")
+set_default("llvm_shlib_dir", "@SHLIBDIR@")
+set_default("gold_executable", "@GOLD_EXECUTABLE@")
set_default("clang", "@COMPILER_RT_TEST_COMPILER@")
set_default("compiler_id", "@COMPILER_RT_TEST_COMPILER_ID@")
set_default("compiler_rt_arch", "@COMPILER_RT_SUPPORTED_ARCH@")
diff --git a/test/lsan/lit.common.cfg b/test/lsan/lit.common.cfg
index bd1aa2769c42..ba9c283ca84a 100644
--- a/test/lsan/lit.common.cfg
+++ b/test/lsan/lit.common.cfg
@@ -44,8 +44,8 @@ config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
config.substitutions.append( ("%clang_lsan ", build_invocation(clang_lsan_cflags)) )
config.substitutions.append( ("%clangxx_lsan ", build_invocation(clang_lsan_cxxflags)) )
-# LeakSanitizer tests are currently supported on x86-64 Linux only.
-if config.host_os not in ['Linux'] or config.host_arch not in ['x86_64']:
+# LeakSanitizer tests are currently supported on x86-64 Linux and mips64 Linux only.
+if config.host_os not in ['Linux'] or config.host_arch not in ['x86_64', 'mips64']:
config.unsupported = True
config.suffixes = ['.c', '.cc', '.cpp']
diff --git a/test/msan/mmap_below_shadow.cc b/test/msan/mmap_below_shadow.cc
index 4b5890ba0fb8..0b982d58930d 100644
--- a/test/msan/mmap_below_shadow.cc
+++ b/test/msan/mmap_below_shadow.cc
@@ -15,8 +15,13 @@
int main(void) {
// Hint address just below shadow.
+#if defined(__x86_64__)
uintptr_t hint = 0x4f0000000000ULL;
const uintptr_t app_start = 0x600000000000ULL;
+#elif defined (__mips64)
+ uintptr_t hint = 0x4f00000000ULL;
+ const uintptr_t app_start = 0x6000000000ULL;
+#endif
uintptr_t p = (uintptr_t)mmap(
(void *)hint, 4096, PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | (FIXED ? MAP_FIXED : 0), -1, 0);
diff --git a/test/msan/strlen_of_shadow.cc b/test/msan/strlen_of_shadow.cc
index bb9fe17d41cd..8f1b4e1fc6bb 100644
--- a/test/msan/strlen_of_shadow.cc
+++ b/test/msan/strlen_of_shadow.cc
@@ -9,7 +9,11 @@
#include <string.h>
const char *mem_to_shadow(const char *p) {
+#if defined(__x86_64__)
return (char *)((uintptr_t)p & ~0x400000000000ULL);
+#elif defined (__mips64)
+ return (char *)((uintptr_t)p & ~0x4000000000ULL);
+#endif
}
int main(void) {
diff --git a/test/msan/vector_select.cc b/test/msan/vector_select.cc
index e8d55423293c..afeb1ad50c8b 100644
--- a/test/msan/vector_select.cc
+++ b/test/msan/vector_select.cc
@@ -4,10 +4,18 @@
// Regression test for MemorySanitizer instrumentation of a select instruction
// with vector arguments.
+#if defined(__x86_64__)
#include <emmintrin.h>
__m128d select(bool b, __m128d c, __m128d d)
{
return b ? c : d;
}
+#elif defined (__mips64)
+typedef double __w64d __attribute__ ((vector_size(16)));
+__w64d select(bool b, __w64d c, __w64d d)
+{
+ return b ? c : d;
+}
+#endif
diff --git a/test/sanitizer_common/TestCases/Linux/ptrace.cc b/test/sanitizer_common/TestCases/Linux/ptrace.cc
index 2bf0fd2f0f35..ba318169ee7d 100644
--- a/test/sanitizer_common/TestCases/Linux/ptrace.cc
+++ b/test/sanitizer_common/TestCases/Linux/ptrace.cc
@@ -8,6 +8,10 @@
#include <sys/user.h>
#include <sys/wait.h>
#include <unistd.h>
+#if __mips64
+ #include <asm/ptrace.h>
+ #include <sys/procfs.h>
+#endif
int main(void) {
pid_t pid;
@@ -33,19 +37,23 @@ int main(void) {
printf("%x\n", fpregs.mxcsr);
#endif // __x86_64__
-#if __powerpc64__
+#if (__powerpc64__ || __mips64)
struct pt_regs regs;
res = ptrace((enum __ptrace_request)PTRACE_GETREGS, pid, NULL, &regs);
assert(!res);
+#if (__powerpc64__)
if (regs.nip)
printf("%lx\n", regs.nip);
-
+#else
+ if (regs.cp0_epc)
+ printf("%lx\n", regs.cp0_epc);
+#endif
elf_fpregset_t fpregs;
res = ptrace((enum __ptrace_request)PTRACE_GETFPREGS, pid, NULL, &fpregs);
assert(!res);
if ((elf_greg_t)fpregs[32]) // fpscr
printf("%lx\n", (elf_greg_t)fpregs[32]);
-#endif // __powerpc64__
+#endif // (__powerpc64__ || __mips64)
siginfo_t siginfo;
res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
diff --git a/test/tsan/global_race.cc b/test/tsan/global_race.cc
index d70bee4a556b..3128ec411749 100644
--- a/test/tsan/global_race.cc
+++ b/test/tsan/global_race.cc
@@ -11,9 +11,9 @@ void *Thread(void *a) {
int main() {
barrier_init(&barrier, 2);
- // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
- // match to the format used in the diagnotic message.
- fprintf(stderr, "addr=0x%012lx\n", (unsigned long) GlobalData);
+ fprintf(stderr, "addr=");
+ print_address(GlobalData);
+ fprintf(stderr, "\n");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
GlobalData[2] = 43;
diff --git a/test/tsan/global_race2.cc b/test/tsan/global_race2.cc
index 6631008d85a5..4ab2842e7eef 100644
--- a/test/tsan/global_race2.cc
+++ b/test/tsan/global_race2.cc
@@ -11,9 +11,9 @@ void *Thread(void *a) {
int main() {
barrier_init(&barrier, 2);
- // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
- // match to the format used in the diagnotic message.
- fprintf(stderr, "addr2=0x%012lx\n", (unsigned long) &x);
+ fprintf(stderr, "addr2=");
+ print_address(&x);
+ fprintf(stderr, "\n");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
x = 0;
diff --git a/test/tsan/global_race3.cc b/test/tsan/global_race3.cc
index e7e9a7fef028..1531d7830f78 100644
--- a/test/tsan/global_race3.cc
+++ b/test/tsan/global_race3.cc
@@ -16,9 +16,9 @@ void *Thread(void *a) {
int main() {
barrier_init(&barrier, 2);
- // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
- // match to the format used in the diagnotic message.
- fprintf(stderr, "addr3=0x%012lx\n", (unsigned long) XXX::YYY::ZZZ);
+ fprintf(stderr, "addr3=");
+ print_address(XXX::YYY::ZZZ);
+ fprintf(stderr, "\n");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
XXX::YYY::ZZZ[0] = 0;
diff --git a/test/tsan/map32bit.cc b/test/tsan/map32bit.cc
index 9dae6880e7fe..d9a04655ddca 100644
--- a/test/tsan/map32bit.cc
+++ b/test/tsan/map32bit.cc
@@ -7,6 +7,9 @@
// Test for issue:
// https://code.google.com/p/thread-sanitizer/issues/detail?id=5
+// MAP_32BIT flag for mmap is supported only for x86_64.
+// XFAIL: mips64
+
void *Thread(void *ptr) {
*(int*)ptr = 42;
barrier_wait(&barrier);
diff --git a/test/tsan/mmap_large.cc b/test/tsan/mmap_large.cc
index e715ea666231..4ae4c0863501 100644
--- a/test/tsan/mmap_large.cc
+++ b/test/tsan/mmap_large.cc
@@ -5,7 +5,11 @@
#include <sys/mman.h>
int main() {
+#ifdef __x86_64__
const size_t kLog2Size = 39;
+#elif defined(__mips64)
+ const size_t kLog2Size = 32;
+#endif
const uintptr_t kLocation = 0x40ULL << kLog2Size;
void *p = mmap(
reinterpret_cast<void*>(kLocation),
diff --git a/test/tsan/signal_segv_handler.cc b/test/tsan/signal_segv_handler.cc
new file mode 100644
index 000000000000..2d806eef6764
--- /dev/null
+++ b/test/tsan/signal_segv_handler.cc
@@ -0,0 +1,39 @@
+// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" %run %t 2>&1 | FileCheck %s
+
+// JVM uses SEGV to preempt threads. All threads do a load from a known address
+// periodically. When runtime needs to preempt threads, it unmaps the page.
+// Threads start triggering SEGV one by one. The signal handler blocks
+// threads while runtime does its thing. Then runtime maps the page again
+// and resumes the threads.
+// Previously this pattern conflicted with stop-the-world machinery,
+// because it briefly reset SEGV handler to SIG_DFL.
+// As the consequence JVM just silently died.
+
+// This test sets memory flushing rate to maximum, then does series of
+// "benign" SEGVs that are handled by signal handler, and ensures that
+// the process survive.
+
+#include "test.h"
+#include <signal.h>
+#include <sys/mman.h>
+
+void *guard;
+
+void handler(int signo, siginfo_t *info, void *uctx) {
+ mprotect(guard, 4096, PROT_READ | PROT_WRITE);
+}
+
+int main() {
+ struct sigaction a;
+ a.sa_sigaction = handler;
+ a.sa_flags = SA_SIGINFO;
+ sigaction(SIGSEGV, &a, 0);
+ guard = mmap(0, 4096, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ for (int i = 0; i < 1000000; i++) {
+ mprotect(guard, 4096, PROT_NONE);
+ *(int*)guard = 1;
+ }
+ fprintf(stderr, "DONE\n");
+}
+
+// CHECK: DONE
diff --git a/test/tsan/test.h b/test/tsan/test.h
index 4496e56cda87..bb861b07745e 100644
--- a/test/tsan/test.h
+++ b/test/tsan/test.h
@@ -29,3 +29,12 @@ void barrier_init(pthread_barrier_t *barrier, unsigned count) {
// Default instance of the barrier, but a test can declare more manually.
pthread_barrier_t barrier;
+void print_address(void *address) {
+// On FreeBSD, the %p conversion specifier works as 0x%x and thus does not match
+// to the format used in the diagnotic message.
+#ifdef __x86_64__
+ fprintf(stderr, "0x%012lx", (unsigned long) address);
+#elif defined(__mips64)
+ fprintf(stderr, "0x%010lx", (unsigned long) address);
+#endif
+}
diff --git a/test/ubsan/TestCases/TypeCheck/Function/function.cpp b/test/ubsan/TestCases/TypeCheck/Function/function.cpp
index deca77d459c0..2609c6a8f666 100644
--- a/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ b/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -12,13 +12,24 @@ void f() {}
void g(int x) {}
-int main(void) {
- // CHECK: runtime error: call to function f() through pointer to incorrect function type 'void (*)(int)'
+void make_valid_call() {
+ // CHECK-NOT: runtime error: call to function g
+ reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(g))(42);
+}
+
+void make_invalid_call() {
+ // CHECK: function.cpp:25:3: runtime error: call to function f() through pointer to incorrect function type 'void (*)(int)'
// CHECK-NEXT: function.cpp:11: note: f() defined here
- // NOSYM: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+ // NOSYM: function.cpp:25:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
// NOSYM-NEXT: ({{.*}}+0x{{.*}}): note: (unknown) defined here
reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f))(42);
+}
- // CHECK-NOT: runtime error: call to function g
- reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(g))(42);
+int main(void) {
+ make_valid_call();
+ make_invalid_call();
+ // Check that no more errors will be printed.
+ // CHECK-NOT: runtime error: call to function
+ // NOSYM-NOT: runtime error: call to function
+ make_invalid_call();
}
diff --git a/test/ubsan/TestCases/TypeCheck/null.cpp b/test/ubsan/TestCases/TypeCheck/null.cpp
index 2a90f7fb956b..190dc30e5dfe 100644
--- a/test/ubsan/TestCases/TypeCheck/null.cpp
+++ b/test/ubsan/TestCases/TypeCheck/null.cpp
@@ -18,21 +18,21 @@ int main(int, char **argv) {
switch (argv[1][0]) {
case 'l':
- // CHECK-LOAD: null.cpp:22:12: runtime error: load of null pointer of type 'int'
+ // CHECK-LOAD: null.cpp:[[@LINE+1]]:12: runtime error: load of null pointer of type 'int'
return *p;
case 's':
- // CHECK-STORE: null.cpp:25:5: runtime error: store to null pointer of type 'int'
+ // CHECK-STORE: null.cpp:[[@LINE+1]]:5: runtime error: store to null pointer of type 'int'
*p = 1;
break;
case 'r':
- // CHECK-REFERENCE: null.cpp:29:15: runtime error: reference binding to null pointer of type 'int'
+ // CHECK-REFERENCE: null.cpp:[[@LINE+1]]:15: runtime error: reference binding to null pointer of type 'int'
{int &r = *p;}
break;
case 'm':
- // CHECK-MEMBER: null.cpp:33:15: runtime error: member access within null pointer of type 'S'
+ // CHECK-MEMBER: null.cpp:[[@LINE+1]]:15: runtime error: member access within null pointer of type 'S'
return s->k;
case 'f':
- // CHECK-MEMFUN: null.cpp:36:12: runtime error: member call on null pointer of type 'S'
+ // CHECK-MEMFUN: null.cpp:[[@LINE+1]]:12: runtime error: member call on null pointer of type 'S'
return s->f();
}
}
diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
index 033da24451c2..806e45c7d357 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
+// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
// FIXME: This test produces linker errors on Darwin.
diff --git a/test/ubsan/TestCases/TypeCheck/vptr.cpp b/test/ubsan/TestCases/TypeCheck/vptr.cpp
index 98eac271c3a1..1f8ee02641a8 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=vptr -g %s -O3 -o %t
+// RUN: %clangxx -frtti -fsanitize=vptr -g %s -O3 -o %t
// RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
// RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
// RUN: %run %t rS && %run %t rV && %run %t oV
@@ -12,16 +12,16 @@
// RUN: %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace
// RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
// RUN: echo "vptr_check:S" > %t.loc-supp
-// RUN: ASAN_OPTIONS="suppressions='%t.loc-supp'" UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
+// RUN: UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
// FIXME: This test produces linker errors on Darwin.
// XFAIL: darwin