clang-tidy: fixes and improvements
No binary (build failed)
—
(log yok)
| @@ -0,0 +1,16 @@ | |
| + | # Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | # |
| + | # SPDX-License-Identifier: curl |
| + | --- |
| + | # https://clang.llvm.org/extra/clang-tidy/checks/list.html |
| + | |
| + | # -clang-analyzer-security.insecureAPI.bzero: for FD_ZERO() (seen on macOS) |
| + | # -clang-analyzer-security.ArrayBound: due to false positives with clang-tidy v21.1.0 |
| + | Checks: >- |
| + | -clang-analyzer-security.insecureAPI.bzero, |
| + | -clang-analyzer-optin.performance.Padding, |
| + | -clang-analyzer-security.ArrayBound, |
| + | -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, |
| + | -clang-diagnostic-nullability-extension, |
| + | misc-const-correctness, |
| + | portability-* |
| @@ -33,7 +33,6 @@ env: | |
| MAKEFLAGS: -j 5 | |
| CURL_CI: github | |
| CURL_TEST_MIN: 1600 | |
| - | CURL_CLANG_TIDYFLAGS: '-checks=-clang-analyzer-security.insecureAPI.bzero,-clang-analyzer-optin.performance.Padding,-clang-analyzer-security.ArrayBound,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-clang-analyzer-valist.Uninitialized' |
| # renovate: datasource=github-tags depName=libressl/portable versioning=semver registryUrl=https://github.com | |
| LIBRESSL_VERSION: 4.2.1 | |
| # renovate: datasource=github-tags depName=wolfSSL/wolfssl versioning=semver extractVersion=^v?(?<version>.+)-stable$ registryUrl=https://github.com | |
| @@ -277,13 +276,15 @@ jobs: | |
| -DCURL_DISABLE_LDAP=ON -DUSE_LIBIDN2=OFF -DCURL_USE_LIBSSH2=OFF | |
| - name: 'clang-tidy' | |
| - | install_packages: clang-tidy libssl-dev libidn2-dev libssh2-1-dev libnghttp2-dev libldap-dev libkrb5-dev librtmp-dev libgnutls28-dev |
| + | install_packages: clang-19 clang-tidy-19 libssl-dev libidn2-dev libssh2-1-dev libnghttp2-dev libldap-dev libkrb5-dev librtmp-dev libgnutls28-dev |
| install_steps: skipall mbedtls-latest-intel rustls wolfssl-opensslextra-intel | |
| install_steps_brew: gsasl | |
| make-custom-target: tidy | |
| LDFLAGS: -Wl,-rpath,/home/runner/wolfssl-opensslextra/lib -Wl,-rpath,/home/linuxbrew/.linuxbrew/opt/gsasl/lib | |
| PKG_CONFIG_PATH: /home/linuxbrew/.linuxbrew/opt/gsasl/lib/pkgconfig | |
| + | CC: clang-19 |
| configure: >- | |
| + | CLANG_TIDY=clang-tidy-19 |
| --with-wolfssl=/home/runner/wolfssl-opensslextra --with-openssl --with-rustls --with-mbedtls=/home/runner/mbedtls --with-gnutls --with-libgsasl | |
| --with-librtmp --with-libssh2 --with-libidn2 | |
| --enable-ech --with-gssapi --enable-ssls-export --disable-typecheck | |
| @@ -115,6 +115,10 @@ macro(curl_collect_target_options _target) | |
| if(_val) | |
| list(APPEND _definitions ${_val}) | |
| endif() | |
| + | get_target_property(_val ${_target} COMPILE_OPTIONS) |
| + | if(_val) |
| + | list(APPEND _options ${_val}) |
| + | endif() |
| get_target_property(_val ${_target} LINK_LIBRARIES) | |
| if(_val) | |
| foreach(_lib IN LISTS _val) | |
| @@ -132,6 +136,7 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) | |
| set(_includes "") | |
| set(_definitions "") | |
| + | set(_options "") |
| # Collect header directories and macro definitions applying to the directory | |
| get_directory_property(_val INCLUDE_DIRECTORIES) | |
| @@ -142,13 +147,24 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) | |
| if(_val) | |
| list(APPEND _definitions ${_val}) | |
| endif() | |
| + | get_directory_property(_val COMPILE_OPTIONS) |
| + | if(_val) |
| + | list(APPEND _options ${_val}) |
| + | endif() |
| unset(_val) | |
| # Collect header directories and macro definitions from lib dependencies | |
| curl_collect_target_options(${_target}) | |
| - | list(REMOVE_ITEM _includes "") |
| - | string(REPLACE ";" ";-I" _includes ";${_includes}") |
| + | set(_includes_tmp ${_includes}) |
| + | set(_includes) |
| + | foreach(_inc IN LISTS _includes_tmp) |
| + | # Avoid empty and '$<INSTALL_INTERFACE:include>' items. The latter also |
| + | # evaluates to an empty path in this context. |
| + | if(_inc AND NOT _inc MATCHES "INSTALL_INTERFACE:") |
| + | list(APPEND _includes "-I${_inc}") |
| + | endif() |
| + | endforeach() |
| list(REMOVE_DUPLICATES _includes) | |
| list(REMOVE_ITEM _definitions "") | |
| @@ -156,6 +172,12 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) | |
| list(REMOVE_DUPLICATES _definitions) | |
| list(SORT _definitions) # Sort like CMake does | |
| + | if(CMAKE_C_COMPILER_ID MATCHES "Clang") |
| + | list(REMOVE_DUPLICATES _options) # Keep the first of duplicates to imitate CMake |
| + | else() |
| + | set(_options) |
| + | endif() |
| + | |
| # Assemble source list | |
| set(_sources "") | |
| foreach(_source IN ITEMS ${ARGN}) | |
| @@ -165,14 +187,18 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) | |
| list(APPEND _sources "${_source}") | |
| endforeach() | |
| + | # Pass -clang-diagnostic-unused-function to disable -Wunused-function implied by -Wunused |
| add_custom_target(${_target_clang_tidy} USES_TERMINAL | |
| WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" | |
| - | COMMAND ${CMAKE_C_CLANG_TIDY} ${_sources} -- ${_includes} ${_definitions} |
| + | COMMAND ${CMAKE_C_CLANG_TIDY} |
| + | "--checks=-clang-diagnostic-unused-function" |
| + | ${_sources} -- ${_includes} ${_definitions} ${_options} |
| DEPENDS ${_sources}) | |
| add_dependencies(tests-clang-tidy ${_target_clang_tidy}) | |
| unset(_includes) | |
| unset(_definitions) | |
| + | unset(_options) |
| unset(_sources) | |
| endif() | |
| endmacro() | |
| @@ -251,8 +251,6 @@ if(NOT DOS AND NOT AMIGA) | |
| option(ENABLE_THREADED_RESOLVER "Enable threaded DNS lookup" ${_enable_threaded_resolver_default}) | |
| endif() | |
| - | include(PickyWarnings) |
| - | |
| if(CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "GNU") | |
| set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "_GNU_SOURCE") # Required for accept4(), pipe2(), sendmmsg() | |
| list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") # Apply to all feature checks | |
| @@ -270,22 +268,21 @@ endif() | |
| option(CURL_CLANG_TIDY "Run the build through clang-tidy" OFF) | |
| if(CURL_CLANG_TIDY) | |
| + | find_program(CLANG_TIDY NAMES "clang-tidy" REQUIRED) |
| + | if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang") |
| + | set(PICKY_COMPILER OFF) # Do a best effort and skip passing non-clang warning options to clang-tidy. |
| + | # This lets through warning options enabled via CURL_WERROR=ON, affecting lib and src. |
| + | endif() |
| set(CMAKE_UNITY_BUILD OFF) # clang-tidy is not looking into #included sources, thus not compatible with unity builds. | |
| set(CURL_DISABLE_TYPECHECK ON) # to improve performance and avoid potential interference. | |
| - | set(_tidy_checks "") |
| - | list(APPEND _tidy_checks "-clang-analyzer-security.insecureAPI.bzero") # for FD_ZERO() (seen on macOS) |
| - | list(APPEND _tidy_checks "-clang-analyzer-optin.performance.Padding") |
| - | list(APPEND _tidy_checks "-clang-analyzer-security.ArrayBound") # false positives with clang-tidy v21.1.0 |
| - | list(APPEND _tidy_checks "-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling") |
| - | string(REPLACE ";" "," _tidy_checks "${_tidy_checks}") |
| - | find_program(CLANG_TIDY NAMES "clang-tidy" REQUIRED) |
| - | set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY}" "-checks=${_tidy_checks}" "-quiet") |
| - | unset(_tidy_checks) |
| + | set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY}") |
| + | list(APPEND CMAKE_C_CLANG_TIDY "--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy.yml") |
| if(CURL_WERROR) | |
| list(APPEND CMAKE_C_CLANG_TIDY "--warnings-as-errors=*") | |
| endif() | |
| if(CURL_CLANG_TIDYFLAGS) | |
| - | list(APPEND CMAKE_C_CLANG_TIDY ${CURL_CLANG_TIDYFLAGS}) |
| + | string(REPLACE " " ";" _tidy_flags_list "${CURL_CLANG_TIDYFLAGS}") |
| + | list(APPEND CMAKE_C_CLANG_TIDY ${_tidy_flags_list}) |
| endif() | |
| endif() | |
| @@ -309,6 +306,8 @@ if(CURL_CODE_COVERAGE) | |
| endif() | |
| endif() | |
| + | include(PickyWarnings) |
| + | |
| set(CURL_CFLAGS "") # C flags set for libcurl and curl tool (aka public binaries) only | |
| option(CURL_DROP_UNUSED "Drop unused code and data from built binaries" OFF) | |
| @@ -64,7 +64,7 @@ CMAKE_DIST = \ | |
| tests/cmake/test.c \ | |
| tests/cmake/test.sh | |
| - | EXTRA_DIST = CHANGES.md COPYING RELEASE-NOTES Dockerfile .editorconfig $(CMAKE_DIST) |
| + | EXTRA_DIST = CHANGES.md COPYING RELEASE-NOTES Dockerfile .clang-tidy.yml .editorconfig $(CMAKE_DIST) |
| DISTCLEANFILES = buildinfo.txt | |
| @@ -120,6 +120,11 @@ AC_SUBST([AR]) | |
| AC_SUBST(libext) | |
| + | if test -z "$CLANG_TIDY"; then |
| + | CLANG_TIDY=clang-tidy |
| + | fi |
| + | AC_SUBST(CLANG_TIDY) |
| + | |
| dnl figure out the libcurl version | |
| CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)".*/\1/p' ${srcdir}/include/curl/curlver.h` | |
| XC_CHECK_PROG_CC | |
| @@ -681,6 +686,8 @@ case $host_os in | |
| ;; | |
| esac | |
| + | AM_CONDITIONAL(CLANG, test "$compiler_id" = "APPLECLANG" || test "$compiler_id" = "CLANG") |
| + | |
| dnl ********************************************************************** | |
| dnl Compilation based checks should not be done before this point. | |
| dnl ********************************************************************** | |
| @@ -49,6 +49,7 @@ When writing code (mostly for generating stuff included in release tarballs) | |
| we use a few "build tools" and we make sure that we remain functional with | |
| these versions: | |
| + | - clang-tidy 14.0.0 (2022-03-23), recommended: 19.1.0 or later (2024-09-17) |
| - cmake 3.7 (2016-11-11) | |
| - GNU autoconf 2.59 (2003-11-06) | |
| - GNU automake 1.7 (2002-09-25) | |
| @@ -163,17 +163,18 @@ UNITV_ = $(UNITV_0) | |
| $(UNITPROTOS): $(CSOURCES) | |
| $(UNIT_V)(cd $(srcdir) && @PERL@ ../scripts/extract-unit-protos $(CSOURCES)) > $(top_builddir)/lib/$(UNITPROTOS) | |
| - | # disable the tests that are mostly causing false positives |
| - | TIDYFLAGS := -checks=-clang-analyzer-security.insecureAPI.bzero,-clang-analyzer-optin.performance.Padding,-clang-analyzer-security.ArrayBound,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling -quiet |
| + | _tidy_cflags := |
| + | TIDYFLAGS := |
| if CURL_WERROR | |
| - | TIDYFLAGS += --warnings-as-errors=* |
| + | TIDYFLAGS += '--warnings-as-errors=*' |
| + | endif |
| + | if CLANG |
| + | _tidy_cflags += $(CFLAGS) |
| endif | |
| - | |
| - | TIDY := clang-tidy |
| tidy: | |
| (_csources=`echo ' $(CSOURCES)' | sed -E -e 's/ +$$//' -e 's/ +/ /g' -e 's| | $(srcdir)/|g'`; \ | |
| - | $(TIDY) $$_csources $(TIDYFLAGS) $(CURL_CLANG_TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H) |
| + | @CLANG_TIDY@ --config-file=$(top_srcdir)/.clang-tidy.yml $(TIDYFLAGS) $(CURL_CLANG_TIDYFLAGS) $$_csources -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H $(_tidy_cflags)) |
| optiontable: | |
| @PERL@ $(srcdir)/optiontable.pl < $(top_srcdir)/include/curl/curl.h > $(srcdir)/easyoptions.c | |
| @@ -215,17 +215,18 @@ all-local: checksrc | |
| endif | |
| endif | |
| - | # disable the tests that are mostly causing false positives |
| - | TIDYFLAGS := -checks=-clang-analyzer-security.insecureAPI.bzero,-clang-analyzer-optin.performance.Padding,-clang-analyzer-security.ArrayBound,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling -quiet |
| + | _tidy_cflags := |
| + | TIDYFLAGS = |
| if CURL_WERROR | |
| - | TIDYFLAGS += --warnings-as-errors=* |
| + | TIDYFLAGS += '--warnings-as-errors=*' |
| + | endif |
| + | if CLANG |
| + | _tidy_cflags += $(CFLAGS) |
| endif | |
| - | |
| - | TIDY := clang-tidy |
| tidy: $(HUGE) $(CA_EMBED_CSOURCE) | |
| (_curl_cfiles=`echo ' $(CURL_CFILES)' | sed -e 's/ +/ /g' -e 's| | $(srcdir)/|g'`; \ | |
| - | $(TIDY) $$_curl_cfiles $(curl_cfiles_gen) $(TIDYFLAGS) $(CURL_CLANG_TIDYFLAGS) -- $(curl_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS) -DHAVE_CONFIG_H) |
| + | @CLANG_TIDY@ --config-file=$(top_srcdir)/.clang-tidy.yml $(TIDYFLAGS) $(CURL_CLANG_TIDYFLAGS) $$_curl_cfiles $(curl_cfiles_gen) -- $(curl_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS) -DHAVE_CONFIG_H $(_tidy_cflags)) |
| listhelp: | |
| (cd $(top_srcdir)/docs/cmdline-opts && make listhelp) | |
| @@ -253,6 +253,8 @@ ParameterError parseconfig(const char *filename, int max_recursive, | |
| curlx_dyn_free(&pbuf); | |
| if(file != stdin) | |
| curlx_fclose(file); | |
| + | /* Silence false positive about failing to close stdin. |
| + | NOLINTNEXTLINE(clang-analyzer-unix.Stream) */ |
| if(fileerror) | |
| err = PARAM_READ_ERROR; | |
| } | |