13
13
# License for the specific language governing permissions and limitations under
14
14
# the License.
15
15
16
+ include (CheckCXXSourceCompiles )
17
+
16
18
set (USE_SANITIZER
17
19
""
18
20
CACHE
@@ -28,48 +30,109 @@ function(append value)
28
30
endforeach (variable )
29
31
endfunction ()
30
32
33
+ function (test_san_flags return_var flags )
34
+ set (QUIET_BACKUP ${CMAKE_REQUIRED_QUIET} )
35
+ set (CMAKE_REQUIRED_QUIET TRUE )
36
+ unset (${return_var} CACHE )
37
+ set (FLAGS_BACKUP ${CMAKE_REQUIRED_FLAGS} )
38
+ set (CMAKE_REQUIRED_FLAGS "${flags} " )
39
+ check_cxx_source_compiles ("int main() { return 0; }" ${return_var} )
40
+ set (CMAKE_REQUIRED_FLAGS "${FLAGS_BACKUP} " )
41
+ set (CMAKE_REQUIRED_QUIET "${QUIET_BACKUP} " )
42
+ endfunction ()
43
+
31
44
if (USE_SANITIZER )
32
45
append ("-fno-omit-frame-pointer" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
33
46
47
+ unset (SANITIZER_SELECTED_FLAGS )
48
+
34
49
if (UNIX )
35
50
36
51
if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
37
52
append ("-O1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
38
53
endif ()
39
54
40
- if (USE_SANITIZER MATCHES "([Aa]ddress);([Uu]ndefined)"
41
- OR USE_SANITIZER MATCHES "([Uu]ndefined);([Aa]ddress)" )
42
- message (STATUS "Building with Address, Undefined sanitizers" )
43
- append ("-fsanitize=address,undefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
44
- elseif (USE_SANITIZER MATCHES "([Aa]ddress)" )
55
+ if (USE_SANITIZER MATCHES "([Aa]ddress)" )
45
56
# Optional: -fno-optimize-sibling-calls -fsanitize-address-use-after-scope
46
- message (STATUS "Building with Address sanitizer" )
47
- append ("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
48
- elseif (USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)" )
57
+ message (STATUS "Testing with Address sanitizer" )
58
+ set (SANITIZER_ADDR_FLAG "-fsanitize=address" )
59
+ test_san_flags (SANITIZER_ADDR_AVAILABLE ${SANITIZER_ADDR_FLAG} )
60
+ if (SANITIZER_ADDR_AVAILABLE )
61
+ message (STATUS " Building with Address sanitizer" )
62
+ append ("${SANITIZER_ADDR_FLAG} " SANITIZER_SELECTED_FLAGS )
63
+ else ()
64
+ message (FATAL_ERROR "Address sanitizer not available for ${CMAKE_CXX_COMPILER} " )
65
+ endif ()
66
+ endif ()
67
+
68
+ if (USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)" )
49
69
# Optional: -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2
50
- append ( "-fsanitize=memory" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
70
+ set ( SANITIZER_MEM_FLAG "-fsanitize=memory" )
51
71
if (USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)" )
52
- message (STATUS "Building with MemoryWithOrigins sanitizer" )
53
- append ("-fsanitize-memory-track-origins" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
72
+ message (STATUS "Testing with MemoryWithOrigins sanitizer" )
73
+ append ("-fsanitize-memory-track-origins" SANITIZER_MEM_FLAG )
54
74
else ()
55
- message (STATUS "Building with Memory sanitizer" )
75
+ message (STATUS "Testing with Memory sanitizer" )
56
76
endif ()
57
- elseif (USE_SANITIZER MATCHES "([Uu]ndefined)" )
58
- message (STATUS "Building with Undefined sanitizer" )
59
- append ("-fsanitize=undefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
77
+ test_san_flags (SANITIZER_MEM_AVAILABLE ${SANITIZER_MEM_FLAG} )
78
+ if (SANITIZER_MEM_AVAILABLE )
79
+ if (USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)" )
80
+ message (STATUS " Building with MemoryWithOrigins sanitizer" )
81
+ else ()
82
+ message (STATUS " Building with Memory sanitizer" )
83
+ endif ()
84
+ append ("${SANITIZER_MEM_FLAG} " SANITIZER_SELECTED_FLAGS )
85
+ else ()
86
+ message (FATAL_ERROR "Memory [With Origins] sanitizer not available for ${CMAKE_CXX_COMPILER} " )
87
+ endif ()
88
+ endif ()
89
+
90
+ if (USE_SANITIZER MATCHES "([Uu]ndefined)" )
91
+ message (STATUS "Testing with Undefined Behaviour sanitizer" )
92
+ set (SANITIZER_UB_FLAG "-fsanitize=undefined" )
60
93
if (EXISTS "${BLACKLIST_FILE} " )
61
- append ("-fsanitize-blacklist=${BLACKLIST_FILE} " CMAKE_C_FLAGS
62
- CMAKE_CXX_FLAGS )
94
+ append ("-fsanitize-blacklist=${BLACKLIST_FILE} " SANITIZER_UB_FLAG )
95
+ endif ()
96
+ test_san_flags (SANITIZER_UB_AVAILABLE ${SANITIZER_UB_FLAG} )
97
+ if (SANITIZER_UB_AVAILABLE )
98
+ message (STATUS " Building with Undefined Behaviour sanitizer" )
99
+ append ("${SANITIZER_UB_FLAG} " SANITIZER_SELECTED_FLAGS )
100
+ else ()
101
+ message (FATAL_ERROR "Undefined Behaviour sanitizer not available for ${CMAKE_CXX_COMPILER} " )
102
+ endif ()
103
+ endif ()
104
+
105
+ if (USE_SANITIZER MATCHES "([Tt]hread)" )
106
+ message (STATUS "Testing with Thread sanitizer" )
107
+ set (SANITIZER_THREAD_FLAG "-fsanitize=thread" )
108
+ test_san_flags (SANITIZER_THREAD_AVAILABLE ${SANITIZER_THREAD_FLAG} )
109
+ if (SANITIZER_THREAD_AVAILABLE )
110
+ message (STATUS " Building with Thread sanitizer" )
111
+ append ("${SANITIZER_THREAD_FLAG} " SANITIZER_SELECTED_FLAGS )
112
+ else ()
113
+ message (FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER} " )
63
114
endif ()
64
- elseif (USE_SANITIZER MATCHES "([Tt]hread)" )
65
- message (STATUS "Building with Thread sanitizer" )
66
- append ("-fsanitize=thread" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
67
- elseif (USE_SANITIZER MATCHES "([Ll]eak)" )
68
- message (STATUS "Building with Leak sanitizer" )
69
- append ("-fsanitize=leak" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
115
+ endif ()
116
+
117
+ if (USE_SANITIZER MATCHES "([Ll]eak)" )
118
+ message (STATUS "Testing with Leak sanitizer" )
119
+ set (SANITIZER_LEAK_FLAG "-fsanitize=leak" )
120
+ test_san_flags (SANITIZER_LEAK_AVAILABLE ${SANITIZER_LEAK_FLAG} )
121
+ if (SANITIZER_LEAK_AVAILABLE )
122
+ message (STATUS " Building with Leak sanitizer" )
123
+ append ("${SANITIZER_LEAK_FLAG} " SANITIZER_SELECTED_FLAGS )
124
+ else ()
125
+ message (FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER} " )
126
+ endif ()
127
+ endif ()
128
+
129
+ message (STATUS "Sanitizer flags: ${SANITIZER_SELECTED_FLAGS} " )
130
+ test_san_flags (SANITIZER_SELECTED_COMPATIBLE ${SANITIZER_SELECTED_FLAGS} )
131
+ if (SANITIZER_SELECTED_COMPATIBLE )
132
+ message (STATUS " Building with ${SANITIZER_SELECTED_FLAGS} " )
133
+ append ("${SANITIZER_SELECTED_FLAGS} " CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
70
134
else ()
71
- message (
72
- FATAL_ERROR "Unsupported value of USE_SANITIZER: ${USE_SANITIZER} " )
135
+ message (FATAL_ERROR " Sanitizer flags ${SANITIZER_SELECTED_FLAGS} are not compatible." )
73
136
endif ()
74
137
elseif (MSVC )
75
138
if (USE_SANITIZER MATCHES "([Aa]ddress)" )
0 commit comments