diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -849,7 +849,7 @@ endif() macro(append_common_sanitizer_flags) - if (NOT MSVC) + if (NOT MSVC OR CLANG_CL) # Append -fno-omit-frame-pointer and turn on debug info to get better # stack traces. add_flag_if_supported("-fno-omit-frame-pointer" FNO_OMIT_FRAME_POINTER) @@ -928,23 +928,18 @@ message(FATAL_ERROR "This sanitizer not yet supported in a MinGW environment: ${LLVM_USE_SANITIZER}") endif() elseif(MSVC) - if (LLVM_USE_SANITIZER STREQUAL "Address") - append_common_sanitizer_flags() - append("/fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - if (NOT CLANG_CL) - # Not compatible with /RTC flags. - foreach (flags_opt_to_scrub - CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}) - string (REGEX REPLACE "(^| )/RTC[1csu]*($| )" " " - "${flags_opt_to_scrub}" "${${flags_opt_to_scrub}}") - endforeach() + if (NOT LLVM_USE_SANITIZER MATCHES "^(Address|Undefined|Address;Undefined|Undefined;Address)$") + message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${LLVM_USE_SANITIZER}") + endif() + append_common_sanitizer_flags() + if (LINKER_IS_LLD_LINK) + if (LLVM_HOST_TRIPLE MATCHES "i[2-6]86-.*") + set(arch "i386") + else() + set(arch "x86_64") endif() - if (LINKER_IS_LLD_LINK) - if (LLVM_HOST_TRIPLE MATCHES "i[2-6]86-.*") - set(arch "i386") - else() - set(arch "x86_64") - endif() + # Prepare ASAN runtime if needed + if (LLVM_USE_SANITIZER MATCHES ".*Address.*") if (${LLVM_USE_CRT_${uppercase_CMAKE_BUILD_TYPE}} MATCHES "^(MT|MTd)$") append("/wholearchive:clang_rt.asan-${arch}.lib /wholearchive:clang_rt.asan_cxx-${arch}.lib" CMAKE_EXE_LINKER_FLAGS) @@ -955,8 +950,25 @@ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) endif() endif() - else() - message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${LLVM_USE_SANITIZER}") + endif() + if (LLVM_USE_SANITIZER MATCHES ".*Address.*") + if (NOT CLANG_CL) + append("/fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + # Not compatible with /RTC flags. + foreach (flags_opt_to_scrub + CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}) + string (REGEX REPLACE "(^| )/RTC[1csu]*($| )" " " + "${flags_opt_to_scrub}" "${${flags_opt_to_scrub}}") + endforeach() + else() + append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() + endif() + if (LLVM_USE_SANITIZER MATCHES ".*Undefined.*") + if (NOT CLANG_CL) + message(FATAL_ERROR "This sanitizer is only supported by clang-cl: Undefined") + endif() + append(${LLVM_UBSAN_FLAGS} CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() else() message(FATAL_ERROR "LLVM_USE_SANITIZER is not supported on this platform.") diff --git a/llvm/include/llvm/ADT/EpochTracker.h b/llvm/include/llvm/ADT/EpochTracker.h --- a/llvm/include/llvm/ADT/EpochTracker.h +++ b/llvm/include/llvm/ADT/EpochTracker.h @@ -23,6 +23,7 @@ namespace llvm { #if LLVM_ENABLE_ABI_BREAKING_CHECKS +#define LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE /// A base class for data structure classes wishing to make iterators /// ("handles") pointing into themselves fail-fast. When building without @@ -78,6 +79,11 @@ }; #else +#ifdef _MSC_VER +#define LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE __declspec(empty_bases) +#else +#define LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE +#endif // _MSC_VER class DebugEpochBase { public: diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h --- a/llvm/include/llvm/ADT/SmallPtrSet.h +++ b/llvm/include/llvm/ADT/SmallPtrSet.h @@ -264,8 +264,9 @@ /// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet. template -class SmallPtrSetIterator : public SmallPtrSetIteratorImpl, - DebugEpochBase::HandleBase { +class LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE SmallPtrSetIterator + : public SmallPtrSetIteratorImpl, + DebugEpochBase::HandleBase { using PtrTraits = PointerLikeTypeTraits; public: diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -107,8 +107,9 @@ /// funky memory allocation and hashing things to make it extremely efficient, /// storing the string data *after* the value in the map. template -class StringMap : public StringMapImpl, - private detail::AllocatorHolder { +class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap + : public StringMapImpl, + private detail::AllocatorHolder { using AllocTy = detail::AllocatorHolder; public: diff --git a/llvm/include/llvm/Support/AllocatorBase.h b/llvm/include/llvm/Support/AllocatorBase.h --- a/llvm/include/llvm/Support/AllocatorBase.h +++ b/llvm/include/llvm/Support/AllocatorBase.h @@ -19,6 +19,12 @@ #ifndef LLVM_SUPPORT_ALLOCATORBASE_H #define LLVM_SUPPORT_ALLOCATORBASE_H +#ifdef _MSC_VER +#define LLVM_ALLOCATORHOLDER_EMPTYBASE __declspec(empty_bases) +#else +#define LLVM_ALLOCATORHOLDER_EMPTYBASE +#endif // _MSC_VER + #include "llvm/Support/Compiler.h" #include "llvm/Support/MemAlloc.h" #include