File: detect-sanitizer.cmake

package info (click to toggle)
node-yarnpkg 4.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 24,752 kB
  • sloc: javascript: 38,953; ansic: 26,035; cpp: 7,247; sh: 2,829; makefile: 724; perl: 493
file content (157 lines) | stat: -rw-r--r-- 5,337 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags
# Licensed under the Zlib license, see LICENSE.md for details

macro(add_common_sanitizer_flags)
    if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
        add_compile_options(-g3)
    endif()
    check_c_compiler_flag(-fno-omit-frame-pointer HAVE_NO_OMIT_FRAME_POINTER)
    if(HAVE_NO_OMIT_FRAME_POINTER)
        add_compile_options(-fno-omit-frame-pointer)
        add_link_options(-fno-omit-frame-pointer)
    endif()
    check_c_compiler_flag(-fno-optimize-sibling-calls HAVE_NO_OPTIMIZE_SIBLING_CALLS)
    if(HAVE_NO_OPTIMIZE_SIBLING_CALLS)
        add_compile_options(-fno-optimize-sibling-calls)
        add_link_options(-fno-optimize-sibling-calls)
    endif()
endmacro()

macro(check_sanitizer_support known_checks supported_checks)
    set(available_checks "")

    # Build list of supported sanitizer flags by incrementally trying compilation with
    # known sanitizer checks

    foreach(check ${known_checks})
        if(available_checks STREQUAL "")
            set(compile_checks "${check}")
        else()
            set(compile_checks "${available_checks},${check}")
        endif()

        set(CMAKE_REQUIRED_FLAGS -fsanitize=${compile_checks})

        check_c_source_compiles("int main() { return 0; }" HAVE_SANITIZER_${check}
            FAIL_REGEX "not supported|unrecognized command|unknown option")

        set(CMAKE_REQUIRED_FLAGS)

        if(HAVE_SANITIZER_${check})
            set(available_checks ${compile_checks})
        endif()
    endforeach()

    set(${supported_checks} ${available_checks})
endmacro()

macro(add_address_sanitizer)
    set(known_checks
        address
        pointer-compare
        pointer-subtract
        )

    check_sanitizer_support("${known_checks}" supported_checks)
    if(NOT ${supported_checks} STREQUAL "")
        message(STATUS "Address sanitizer is enabled: ${supported_checks}")
        add_compile_options(-fsanitize=${supported_checks})
        add_link_options(-fsanitize=${supported_checks})
        add_common_sanitizer_flags()
    else()
        message(STATUS "Address sanitizer is not supported")
    endif()

    if(CMAKE_CROSSCOMPILING_EMULATOR)
        # Only check for leak sanitizer if not cross-compiling due to qemu crash
        message(WARNING "Leak sanitizer is not supported when cross compiling")
    else()
        # Leak sanitizer requires address sanitizer
        check_sanitizer_support("leak" supported_checks)
        if(NOT ${supported_checks} STREQUAL "")
            message(STATUS "Leak sanitizer is enabled: ${supported_checks}")
            add_compile_options(-fsanitize=${supported_checks})
            add_link_options(-fsanitize=${supported_checks})
            add_common_sanitizer_flags()
        else()
            message(STATUS "Leak sanitizer is not supported")
        endif()
    endif()
endmacro()

macro(add_memory_sanitizer)
    check_sanitizer_support("memory" supported_checks)
    if(NOT ${supported_checks} STREQUAL "")
        message(STATUS "Memory sanitizer is enabled: ${supported_checks}")
        add_compile_options(-fsanitize=${supported_checks})
        add_link_options(-fsanitize=${supported_checks})
        add_common_sanitizer_flags()

        check_c_compiler_flag(-fsanitize-memory-track-origins HAVE_MEMORY_TRACK_ORIGINS)
        if(HAVE_MEMORY_TRACK_ORIGINS)
            add_compile_options(-fsanitize-memory-track-origins)
            add_link_options(-fsanitize-memory-track-origins)
        endif()
    else()
        message(STATUS "Memory sanitizer is not supported")
    endif()
endmacro()

macro(add_thread_sanitizer)
    check_sanitizer_support("thread" supported_checks)
    if(NOT ${supported_checks} STREQUAL "")
        message(STATUS "Thread sanitizer is enabled: ${supported_checks}")
        add_compile_options(-fsanitize=${supported_checks})
        add_link_options(-fsanitize=${supported_checks})
        add_common_sanitizer_flags()
    else()
        message(STATUS "Thread sanitizer is not supported")
    endif()
endmacro()

macro(add_undefined_sanitizer)
    set(known_checks
        alignment
        array-bounds
        bool
        bounds
        builtin
        enum
        float-cast-overflow
        float-divide-by-zero
        function
        integer-divide-by-zero
        local-bounds
        null
        nonnull-attribute
        pointer-overflow
        return
        returns-nonnull-attribute
        shift
        shift-base
        shift-exponent
        signed-integer-overflow
        undefined
        unsigned-integer-overflow
        unsigned-shift-base
        vla-bound
        vptr
        )

    # Object size sanitizer has no effect at -O0 and produces compiler warning if enabled
    if(NOT CMAKE_C_FLAGS MATCHES "-O0")
        list(APPEND known_checks object-size)
    endif()

    check_sanitizer_support("${known_checks}" supported_checks)

    if(NOT ${supported_checks} STREQUAL "")
        message(STATUS "Undefined behavior sanitizer is enabled: ${supported_checks}")
        add_compile_options(-fsanitize=${supported_checks})
        add_link_options(-fsanitize=${supported_checks})

        add_common_sanitizer_flags()
    else()
        message(STATUS "Undefined behavior sanitizer is not supported")
    endif()
endmacro()