Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -131,6 +131,8 @@ if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$") set(COMPILER_RT_TEST_COMPILER_ID Clang) +elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang-cl.exe$") + set(COMPILER_RT_TEST_COMPILER_ID Clang) else() set(COMPILER_RT_TEST_COMPILER_ID GNU) endif() Index: test/asan/TestCases/Windows/lit.local.cfg =================================================================== --- /dev/null +++ test/asan/TestCases/Windows/lit.local.cfg @@ -0,0 +1,14 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +# We only run a small set of tests on Windows for now. +# Override the parent directory's "unsupported" decision until we can handle +# all of its tests. +if root.host_os in ['Windows']: + config.unsupported = False +else: + config.unsupported = True Index: test/asan/TestCases/Windows/thread_stack_array_left_oob.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Windows/thread_stack_array_left_oob.cc @@ -0,0 +1,26 @@ +// RUN: %clangxx_asan -O0 %s -Fe%t 2>&1 +// 'cat' is used below to work around FileCheck buffering bug which makes this +// test flaky. FIXME: file an issue. +// RUN: not %run %t 2>&1 | cat | FileCheck %s --check-prefix=CHECK + +#include + +DWORD WINAPI thread_proc(void *context) { + int subscript = -1; + volatile char stack_buffer[42]; + stack_buffer[subscript] = 42; +// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: WRITE of size 1 at [[ADDR]] thread T1 +// CHECK: {{#0 .* thread_proc .*thread_stack_array_left_oob.cc}}:[[@LINE-3]] +// CHECK: Address [[ADDR]] is located in stack of thread T1 at offset {{.*}} in frame +// CHECK: thread_proc + return 0; +} + +int main(void) { + HANDLE thr = CreateThread(NULL, 0, thread_proc, NULL, 0, NULL); +// CHECK: Thread T1 created by T0 here: +// CHECK: {{#[01] .* main .*thread_stack_array_left_oob.cc}}:[[@LINE-2]] + WaitForSingleObject(thr, INFINITE); + return 0; +} Index: test/asan/lit.cfg =================================================================== --- test/asan/lit.cfg +++ test/asan/lit.cfg @@ -32,11 +32,19 @@ # FIXME: Review the set of required flags and check if it can be reduced. target_cflags = [get_required_attr(config, "target_cflags")] + extra_linkflags target_cxxflags = config.cxx_mode_flags + target_cflags -clang_asan_static_cflags = ["-fsanitize=address", - "-mno-omit-leaf-frame-pointer", - "-fno-omit-frame-pointer", - "-fno-optimize-sibling-calls", - "-g"] + target_cflags +clang_asan_static_cflags = ["-fsanitize=address"] + target_cflags + +clang_path = getattr(config, 'clang', None) +if clang_path.find("clang-cl") == -1: + clang_asan_static_cflags += ["-g", + "-mno-omit-leaf-frame-pointer", + "-fno-omit-frame-pointer", + "-fno-optimize-sibling-calls"] +else: + clang_asan_static_cflags += ["-Zi", + "-Wno-deprecated-declarations", + "-D_HAS_EXCEPTIONS=0"] + clang_asan_static_cxxflags = config.cxx_mode_flags + clang_asan_static_cflags if config.asan_dynamic: Index: test/lit.common.cfg =================================================================== --- test/lit.common.cfg +++ test/lit.common.cfg @@ -20,7 +20,10 @@ compiler_id = getattr(config, 'compiler_id', None) if compiler_id == "Clang": - config.cxx_mode_flags = ["--driver-mode=g++"] + if platform.system() != 'Windows': + config.cxx_mode_flags = ["--driver-mode=g++"] + else: + config.cxx_mode_flags = [] elif compiler_id == 'GNU': config.cxx_mode_flags = ["-x c++"] else: @@ -50,6 +53,10 @@ 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': + config.environment['LIB'] = os.environ['LIB'] + # Use ugly construction to explicitly prohibit "clang", "clang++" etc. # in RUN lines. config.substitutions.append(