Skip to content

Commit f3de488

Browse files
committed
Fix add_sanitizer_flag macro for MSVC
1 parent d732625 commit f3de488

File tree

2 files changed

+38
-21
lines changed

2 files changed

+38
-21
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ endif()
6363

6464
# Sanitizer flags
6565
if(USE_ASAN)
66+
if (MSVC)
67+
message(WARNING "Running targets compiled with AddressSanitizer flag requires AddressSanitizer library to be available in your environment search path")
68+
endif()
6669
add_sanitizer_flag(address)
6770
endif()
6871
if(USE_UBSAN)

cmake/helpers.cmake

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,17 @@ endfunction()
111111

112112
# Add sanitizer ${flag}, if it is supported, for both C and C++ compiler
113113
macro(add_sanitizer_flag flag)
114-
# Save current 'CMAKE_REQUIRED_LIBRARIES' state and temporarily extend it with
115-
# '-fsanitize=${flag}'. It is required by CMake to check the compiler for
116-
# availability of provided sanitizer ${flag}.
117-
if(WINDOWS)
118-
set(SANITIZER_FLAG "/fsanitize=${flag}")
119-
set(SANITIZER_ARGS "")
120-
else()
121-
set(SANITIZER_FLAG "-fsanitize=${flag}")
114+
set(SANITIZER_FLAG "-fsanitize=${flag}")
115+
if (NOT MSVC)
116+
# Not available on MSVC.
122117
set(SANITIZER_ARGS "-fno-sanitize-recover=all")
123118
endif()
124119

125-
set(SAVED_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
126-
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} ${SANITIZER_FLAG}")
120+
# Save current 'SAVED_CMAKE_REQUIRED_FLAGS' state and temporarily extend it
121+
# with '-fsanitize=${flag}'. It is required by CMake to check the compiler
122+
# for availability of provided sanitizer ${flag}.
123+
set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
124+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${SANITIZER_FLAG}")
127125

128126
if(${flag} STREQUAL "address")
129127
set(check_name "HAS_ASAN")
@@ -138,18 +136,34 @@ macro(add_sanitizer_flag flag)
138136
# Check C and CXX compilers for given sanitizer flag.
139137
check_c_compiler_flag("${SANITIZER_FLAG}" "C_${check_name}")
140138
check_cxx_compiler_flag("${SANITIZER_FLAG}" "CXX_${check_name}")
141-
if (${C_${check_name}} OR ${CXX_${check_name}})
142-
# Set appropriate linker flags for building executables.
143-
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZER_FLAG} ${SANITIZER_ARGS}")
144-
if (${C_${check_name}})
145-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZER_FLAG} ${SANITIZER_ARGS}")
146-
endif()
147-
if (${CXX_${check_name}})
148-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAG} ${SANITIZER_ARGS}")
149-
endif()
139+
if (NOT ${C_${check_name}} OR NOT ${CXX_${check_name}})
140+
message(FATAL_ERROR "${flag} sanitizer is not supported (either by C or CXX compiler)")
141+
endif()
142+
143+
# Check C and CXX compilers for sanitizer arguments.
144+
if (${SANITIZER_ARGS})
145+
check_c_compiler_flag("${SANITIZER_ARGS}" "C_HAS_SAN_ARGS")
146+
check_cxx_compiler_flag("${SANITIZER_ARGS}" "CXX_HAS_SAN_ARGS")
147+
endif()
148+
149+
if (${C_HAS_SAN_ARGS} AND ${CXX_HAS_SAN_ARGS})
150+
set(SANITIZER_OPTION "${SANITIZER_FLAG} ${SANITIZER_ARGS}")
151+
elseif (${SANITIZER_ARGS})
152+
# Ignore sanitizer argument as it's not supported but was set.
153+
message(WARNING "sanitizer argument ${SANITIZER_ARGS} is not supported (either by C or CXX compiler)")
154+
set(SANITIZER_OPTION "${SANITIZER_FLAG}")
150155
else()
151-
message(FATAL_ERROR "${flag} sanitizer is not supported (neither by C nor CXX compiler)")
156+
# No sanitizer argument was set.
157+
set(SANITIZER_OPTION "${SANITIZER_FLAG}")
152158
endif()
153159

154-
set(CMAKE_REQUIRED_LIBRARIES ${SAVED_CMAKE_REQUIRED_LIBRARIES})
160+
add_compile_options("${SANITIZER_OPTION}")
161+
162+
# Clang/gcc needs the flag added to the linker. The Microsoft LINK linker doesn't recognize
163+
# sanitizer flags and will give a LNK4044 warning.
164+
if (NOT MSVC)
165+
add_link_options("${SANITIZER_OPTION}")
166+
endif()
167+
168+
set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS})
155169
endmacro()

0 commit comments

Comments
 (0)