PickyWarnings.cmake (17508B)
1 #*************************************************************************** 2 # _ _ ____ _ 3 # Project ___| | | | _ \| | 4 # / __| | | | |_) | | 5 # | (__| |_| | _ <| |___ 6 # \___|\___/|_| \_\_____| 7 # 8 # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 # 10 # This software is licensed as described in the file COPYING, which 11 # you should have received as part of this distribution. The terms 12 # are also available at https://curl.se/docs/copyright.html. 13 # 14 # You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 # copies of the Software, and permit persons to whom the Software is 16 # furnished to do so, under the terms of the COPYING file. 17 # 18 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 # KIND, either express or implied. 20 # 21 # SPDX-License-Identifier: curl 22 # 23 ########################################################################### 24 include(CheckCCompilerFlag) 25 26 set(_picky "") 27 set(_picky_nocheck "") # not to pass to feature checks 28 29 if(CURL_WERROR) 30 if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) 31 set(CMAKE_COMPILE_WARNING_AS_ERROR ON) 32 else() 33 if(MSVC) 34 list(APPEND _picky_nocheck "-WX") 35 else() # llvm/clang and gcc style options 36 list(APPEND _picky_nocheck "-Werror") 37 endif() 38 endif() 39 40 if((CMAKE_C_COMPILER_ID STREQUAL "GNU" AND 41 NOT DOS AND # Watt-32 headers use the '#include_next' GCC extension 42 CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.0) OR 43 CMAKE_C_COMPILER_ID MATCHES "Clang") 44 list(APPEND _picky_nocheck "-pedantic-errors") 45 endif() 46 endif() 47 48 if(APPLE AND 49 (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.6) OR 50 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.3)) 51 list(APPEND _picky "-Werror=partial-availability") # clang 3.6 appleclang 6.3 52 endif() 53 54 if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") 55 list(APPEND _picky "-Werror-implicit-function-declaration") # clang 1.0 gcc 2.95 56 endif() 57 58 if(MSVC) 59 list(APPEND _picky "-W4") # Use the highest warning level for Visual Studio. 60 elseif(BORLAND) 61 list(APPEND _picky "-w-") # Disable warnings on Borland to avoid changing 3rd party code. 62 endif() 63 64 if(PICKY_COMPILER) 65 if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") 66 67 # https://clang.llvm.org/docs/DiagnosticsReference.html 68 # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html 69 70 # _picky_enable = Options we want to enable as-is. 71 # _picky_detect = Options we want to test first and enable if available. 72 73 # Prefer the -Wextra alias with clang. 74 if(CMAKE_C_COMPILER_ID MATCHES "Clang") 75 set(_picky_enable "-Wextra") 76 else() 77 set(_picky_enable "-W") 78 endif() 79 80 list(APPEND _picky_enable 81 -Wall -pedantic 82 ) 83 84 # ---------------------------------- 85 # Add new options here, if in doubt: 86 # ---------------------------------- 87 set(_picky_detect 88 ) 89 90 # Assume these options always exist with both clang and gcc. 91 # Require clang 3.0 / gcc 2.95 or later. 92 list(APPEND _picky_enable 93 -Wbad-function-cast # clang 2.7 gcc 2.95 94 -Wconversion # clang 2.7 gcc 2.95 95 -Wmissing-declarations # clang 1.0 gcc 2.7 96 -Wmissing-prototypes # clang 1.0 gcc 1.0 97 -Wnested-externs # clang 1.0 gcc 2.7 98 -Wno-long-long # clang 1.0 gcc 2.95 99 -Wno-multichar # clang 1.0 gcc 2.95 100 -Wpointer-arith # clang 1.0 gcc 1.4 101 -Wshadow # clang 1.0 gcc 2.95 102 -Wsign-compare # clang 1.0 gcc 2.95 103 -Wundef # clang 1.0 gcc 2.95 104 -Wunused # clang 1.1 gcc 2.95 105 -Wwrite-strings # clang 1.0 gcc 1.4 106 ) 107 108 # Always enable with clang, version dependent with gcc 109 set(_picky_common_old 110 -Waddress # clang 2.7 gcc 4.3 111 -Wattributes # clang 2.7 gcc 4.1 112 -Wcast-align # clang 1.0 gcc 4.2 113 -Wcast-qual # clang 3.0 gcc 3.4.6 114 -Wdeclaration-after-statement # clang 1.0 gcc 3.4 115 -Wdiv-by-zero # clang 2.7 gcc 4.1 116 -Wempty-body # clang 2.7 gcc 4.3 117 -Wendif-labels # clang 1.0 gcc 3.3 118 -Wfloat-equal # clang 1.0 gcc 2.96 (3.0) 119 -Wformat-security # clang 2.7 gcc 4.1 120 -Wignored-qualifiers # clang 2.8 gcc 4.3 121 -Wmissing-field-initializers # clang 2.7 gcc 4.1 122 -Wmissing-noreturn # clang 2.7 gcc 4.1 123 -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) 124 -Wno-sign-conversion # clang 2.9 gcc 4.3 125 -Wno-system-headers # clang 1.0 gcc 3.0 126 # -Wpadded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs 127 -Wold-style-definition # clang 2.7 gcc 3.4 128 -Wredundant-decls # clang 2.7 gcc 4.1 129 -Wstrict-prototypes # clang 1.0 gcc 3.3 130 # -Wswitch-enum # clang 2.7 gcc 4.1 # Not used: It basically disallows default case 131 -Wtype-limits # clang 2.7 gcc 4.3 132 -Wunreachable-code # clang 2.7 gcc 4.1 133 # -Wunused-macros # clang 2.7 gcc 4.1 # Not practical 134 # -Wno-error=unused-macros # clang 2.7 gcc 4.1 135 -Wunused-parameter # clang 2.7 gcc 4.1 136 -Wvla # clang 2.8 gcc 4.3 137 ) 138 139 if(CMAKE_C_COMPILER_ID MATCHES "Clang") 140 list(APPEND _picky_enable 141 ${_picky_common_old} 142 -Wshift-sign-overflow # clang 2.9 143 -Wshorten-64-to-32 # clang 1.0 144 -Wformat=2 # clang 3.0 gcc 4.8 145 ) 146 if(NOT MSVC) 147 list(APPEND _picky_enable 148 -Wlanguage-extension-token # clang 3.0 149 ) 150 endif() 151 # Enable based on compiler version 152 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.6) OR 153 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.3)) 154 list(APPEND _picky_enable 155 -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3 156 -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0 157 -Wheader-guard # clang 3.4 appleclang 5.1 158 -Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0 159 -Wsometimes-uninitialized # clang 3.2 appleclang 4.6 160 # -Wunreachable-code-break # clang 3.5 appleclang 6.0 # Not used: Silent in "unity" builds 161 -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1 162 ) 163 endif() 164 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9) OR 165 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.3)) 166 list(APPEND _picky_enable 167 -Wcomma # clang 3.9 appleclang 8.3 168 -Wmissing-variable-declarations # clang 3.2 appleclang 4.6 169 ) 170 endif() 171 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0) OR 172 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.3)) 173 list(APPEND _picky_enable 174 -Wassign-enum # clang 7.0 appleclang 10.3 175 -Wextra-semi-stmt # clang 7.0 appleclang 10.3 176 ) 177 endif() 178 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) OR 179 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.4)) 180 list(APPEND _picky_enable 181 -Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 12.4 # We do silencing for clang 10.0 and above only 182 -Wxor-used-as-pow # clang 10.0 gcc 13.0 183 ) 184 endif() 185 else() # gcc 186 # Enable based on compiler version 187 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.3) 188 list(APPEND _picky_enable 189 ${_picky_common_old} 190 -Wclobbered # gcc 4.3 191 -Wmissing-parameter-type # gcc 4.3 192 -Wold-style-declaration # gcc 4.3 193 -Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0 194 -Wstrict-aliasing=3 # gcc 4.0 195 -ftree-vrp # gcc 4.3 (required for -Warray-bounds, included in -Wall) 196 ) 197 endif() 198 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.5) 199 list(APPEND _picky_enable 200 -Wjump-misses-init # gcc 4.5 201 ) 202 if(MINGW) 203 list(APPEND _picky_enable 204 -Wno-pedantic-ms-format # gcc 4.5 (MinGW-only) 205 ) 206 endif() 207 endif() 208 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) 209 list(APPEND _picky_enable 210 -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3 211 -Wformat=2 # clang 3.0 gcc 4.8 212 -Wtrampolines # gcc 4.6 213 ) 214 endif() 215 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.0) 216 list(APPEND _picky_enable 217 -Warray-bounds=2 # clang 3.0 gcc 5.0 (clang default: -Warray-bounds) 218 ) 219 endif() 220 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) 221 list(APPEND _picky_enable 222 -Wduplicated-cond # gcc 6.0 223 -Wnull-dereference # clang 3.0 gcc 6.0 (clang default) 224 -fdelete-null-pointer-checks 225 -Wshift-negative-value # clang 3.7 gcc 6.0 (clang default) 226 -Wshift-overflow=2 # clang 3.0 gcc 6.0 (clang default: -Wshift-overflow) 227 -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1 228 ) 229 endif() 230 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0) 231 list(APPEND _picky_enable 232 -Walloc-zero # gcc 7.0 233 -Wduplicated-branches # gcc 7.0 234 -Wformat-truncation=2 # gcc 7.0 235 -Wimplicit-fallthrough # clang 4.0 gcc 7.0 236 -Wrestrict # gcc 7.0 237 ) 238 endif() 239 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) 240 list(APPEND _picky_enable 241 -Warith-conversion # gcc 10.0 242 -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0 243 ) 244 endif() 245 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) 246 list(APPEND _picky_enable 247 -Warray-compare # clang 20.0 gcc 12.0 248 -Wenum-int-mismatch # gcc 13.0 249 -Wxor-used-as-pow # clang 10.0 gcc 13.0 250 ) 251 endif() 252 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0) 253 list(APPEND _picky_enable 254 -Wleading-whitespace=spaces # gcc 15.0 255 -Wtrailing-whitespace=any # gcc 15.0 256 -Wunterminated-string-initialization # gcc 15.0 257 ) 258 endif() 259 endif() 260 261 # 262 263 set(_picky_skipped "") 264 foreach(_ccopt IN LISTS _picky_enable) 265 string(REGEX MATCH "-W([a-z0-9-]+)" _ccmatch "${_ccopt}") 266 if(_ccmatch AND CMAKE_C_FLAGS MATCHES "-Wno-${CMAKE_MATCH_1}" AND NOT _ccopt STREQUAL "-Wall" AND NOT _ccopt MATCHES "^-Wno-") 267 string(APPEND _picky_skipped " ${_ccopt}") 268 else() 269 list(APPEND _picky "${_ccopt}") 270 endif() 271 endforeach() 272 if(_picky_skipped) 273 message(STATUS "Picky compiler options skipped due to CMAKE_C_FLAGS override:${_picky_skipped}") 274 endif() 275 276 foreach(_ccopt IN LISTS _picky_detect) 277 # Use a unique variable name 1. for meaningful log output 2. to have a fresh, undefined variable for each detection 278 string(MAKE_C_IDENTIFIER "OPT${_ccopt}" _optvarname) 279 # GCC only warns about unknown -Wno- options if there are also other diagnostic messages, 280 # so test for the positive form instead 281 string(REPLACE "-Wno-" "-W" _ccopt_on "${_ccopt}") 282 check_c_compiler_flag(${_ccopt_on} ${_optvarname}) 283 if(${_optvarname}) 284 list(APPEND _picky "${_ccopt}") 285 endif() 286 endforeach() 287 288 if(CMAKE_C_COMPILER_ID STREQUAL "GNU") 289 if(CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5) 290 # Avoid false positives 291 list(APPEND _picky "-Wno-shadow") 292 list(APPEND _picky "-Wno-unreachable-code") 293 endif() 294 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.2 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) 295 # GCC <4.6 do not support #pragma to suppress warnings locally. Disable them globally instead. 296 list(APPEND _picky "-Wno-overlength-strings") 297 endif() 298 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.0 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) 299 list(APPEND _picky "-Wno-missing-field-initializers") # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750 300 endif() 301 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.3 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) 302 list(APPEND _picky "-Wno-type-limits") # Avoid false positives 303 endif() 304 if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.1 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5.5) 305 list(APPEND _picky "-Wno-conversion") # Avoid false positives 306 endif() 307 endif() 308 elseif(MSVC AND MSVC_VERSION LESS_EQUAL 1943) # Skip for untested/unreleased newer versions 309 list(APPEND _picky "-Wall") 310 list(APPEND _picky "-wd4061") # enumerator 'A' in switch of enum 'B' is not explicitly handled by a case label 311 list(APPEND _picky "-wd4191") # 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)(void)' 312 list(APPEND _picky "-wd4255") # no function prototype given: converting '()' to '(void)' (in winuser.h) 313 list(APPEND _picky "-wd4464") # relative include path contains '..' 314 list(APPEND _picky "-wd4548") # expression before comma has no effect; expected expression with side-effect (in FD_SET()) 315 list(APPEND _picky "-wd4574") # 'M' is defined to be '0': did you mean to use '#if M'? (in ws2tcpip.h) 316 list(APPEND _picky "-wd4668") # 'M' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' (in winbase.h) 317 list(APPEND _picky "-wd4710") # 'snprintf': function not inlined 318 list(APPEND _picky "-wd4711") # function 'A' selected for automatic inline expansion 319 # volatile access of '<expression>' is subject to /volatile:<iso|ms> setting; 320 # consider using __iso_volatile_load/store intrinsic functions (ARM64) 321 list(APPEND _picky "-wd4746") 322 list(APPEND _picky "-wd4774") # 'snprintf': format string expected in argument 3 is not a string literal 323 list(APPEND _picky "-wd4820") # 'A': 'N' bytes padding added after data member 'B' 324 if(MSVC_VERSION GREATER_EQUAL 1900) 325 list(APPEND _picky "-wd5045") # Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified 326 endif() 327 endif() 328 endif() 329 330 # clang-cl 331 if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC) 332 list(APPEND _picky "-Wno-language-extension-token") # Allow __int64 333 334 foreach(_wlist IN ITEMS _picky_nocheck _picky) 335 set(_picky_tmp "") 336 foreach(_ccopt IN LISTS "${_wlist}") 337 # Prefix -Wall, otherwise clang-cl interprets it as an MSVC option and translates it to -Weverything 338 if(_ccopt MATCHES "^-W" AND NOT _ccopt STREQUAL "-Wall") 339 list(APPEND _picky_tmp ${_ccopt}) 340 else() 341 list(APPEND _picky_tmp "-clang:${_ccopt}") 342 endif() 343 endforeach() 344 set("${_wlist}" ${_picky_tmp}) # cmake-lint: disable=C0103 345 endforeach() 346 endif() 347 348 if(_picky_nocheck OR _picky) 349 set(_picky_tmp "${_picky_nocheck}" "${_picky}") 350 string(REPLACE ";" " " _picky_tmp "${_picky_tmp}") 351 string(STRIP "${_picky_tmp}" _picky_tmp) 352 message(STATUS "Picky compiler options: ${_picky_tmp}") 353 set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "${_picky_nocheck}" "${_picky}") 354 355 # Apply to all feature checks 356 string(REPLACE ";" " " _picky_tmp "${_picky}") 357 string(APPEND CMAKE_REQUIRED_FLAGS " ${_picky_tmp}") 358 359 unset(_picky) 360 unset(_picky_tmp) 361 endif()