@@ -151,44 +151,52 @@ endif()
151151
152152if (ENABLE_SANITIZERS)
153153 if (NOT SANITIZERS)
154- set (SANITIZERS "address;undefined" )
154+ if (MSVC )
155+ if (MSVC_VERSION LESS 1928)
156+ # Technically 1928 is also used for VS 16.8, but CMake doesn't have a way
157+ # to distinguish patch versions of MSVC, so this is good enough
158+ message (FATAL_ERROR "Using sanitizers with MSVC requires Visual Studio 16.9 or newer" )
159+ endif ()
160+ set (SANITIZERS "address" )
161+ else ()
162+ set (SANITIZERS "address;undefined" )
163+ endif ()
155164 endif ()
156165
157- if ("thread" IN_LIST SANITIZERS)
158- list (REMOVE_ITEM SANITIZERS "thread" )
159- list (APPEND SANITIZE_OPTIONS thread)
160- endif ()
161- if ("address" IN_LIST SANITIZERS)
162- list (REMOVE_ITEM SANITIZERS "address" )
163- list (APPEND SANITIZE_OPTIONS address)
164- endif ()
165- if ("undefined" IN_LIST SANITIZERS)
166- list (REMOVE_ITEM SANITIZERS "undefined" )
167- list (APPEND SANITIZE_OPTIONS alignment bounds)
168- list (APPEND SANITIZE_OPTIONS shift signed-integer-overflow integer-divide-by-zero)
169- list (APPEND SANITIZE_OPTIONS null bool enum)
170- list (APPEND SANITIZE_OPTIONS return)
171- endif ()
172- if (SANITIZERS)
173- message (FATAL_ERROR "Unknown sanitizer(s) ${SANITIZERS} " )
174- else ()
175- message (STATUS "Using sanitizer options ${SANITIZE_OPTIONS} " )
176- endif ()
166+ foreach (option ${SANITIZERS} )
167+ if (option STREQUAL "thread" AND NOT MSVC )
168+ list (APPEND SANITIZE_OPTIONS thread)
169+ elseif (option STREQUAL "address" )
170+ list (APPEND SANITIZE_OPTIONS address)
171+ elseif (option STREQUAL "undefined" AND NOT MSVC )
172+ list (APPEND SANITIZE_OPTIONS alignment bounds)
173+ list (APPEND SANITIZE_OPTIONS shift signed-integer-overflow integer-divide-by-zero)
174+ list (APPEND SANITIZE_OPTIONS null bool enum)
175+ list (APPEND SANITIZE_OPTIONS return)
176+ else ()
177+ message (FATAL_ERROR "Unknown sanitizer ${option} " )
178+ endif ()
179+ endforeach ()
177180
178- string ( REPLACE ";" "," SANITIZE_OPTIONS " ${SANITIZE_OPTIONS} " )
181+ message ( STATUS "Using sanitizer options ${SANITIZE_OPTIONS} " )
179182
180- if (NOT APPLE )
181- set (SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS} -fno-sanitize-recover=address,undefined" )
183+ if (MSVC )
184+ string (REPLACE ";" " /fsanitize=" SANITIZE_OPTIONS "${SANITIZE_OPTIONS} " )
185+ set (SANITIZE_FLAGS "/Zi /fsanitize=${SANITIZE_OPTIONS} " )
182186 else ()
187+ string (REPLACE ";" "," SANITIZE_OPTIONS "${SANITIZE_OPTIONS} " )
183188 set (SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS} " )
189+ if (NOT APPLE )
190+ set (SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize-recover=address,undefined" )
191+ endif ()
184192 endif ()
185193
186194 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
187195 set (SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" )
188196 elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
189197 set (SANITIZE_FLAGS "${SANITIZE_FLAGS} -fuse-ld=gold" )
190- else ( )
191- message (FATAL_ERROR "Sanitizers are only available when using GCC or Clang" )
198+ elseif ( NOT MSVC )
199+ message (FATAL_ERROR "Sanitizers are only available when using MSVC, GCC, or Clang" )
192200 endif ()
193201
194202 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS} " )
0 commit comments