From 0087196f3cb6ade6b401e16e66a9aeb3b5f6f89d Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:14:40 +0700 Subject: [PATCH 01/10] fix(esp_driver_usb_serial_jtag): fix warnings found by GNU static analyzer --- .../esp_driver_usb_serial_jtag/src/usb_serial_jtag.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c index e03b4efc76..f7623139dd 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c @@ -155,15 +155,15 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se ESP_RETURN_ON_FALSE((usb_serial_jtag_config->rx_buffer_size > USB_SER_JTAG_RX_MAX_SIZE), ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "RX buffer prepared is so small, should larger than 64"); ESP_RETURN_ON_FALSE((usb_serial_jtag_config->tx_buffer_size > 0), ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "TX buffer is not prepared"); p_usb_serial_jtag_obj = (usb_serial_jtag_obj_t*) heap_caps_calloc(1, sizeof(usb_serial_jtag_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - p_usb_serial_jtag_obj->rx_buf_size = usb_serial_jtag_config->rx_buffer_size; - p_usb_serial_jtag_obj->tx_buf_size = usb_serial_jtag_config->tx_buffer_size; - p_usb_serial_jtag_obj->tx_stash_cnt = 0; - p_usb_serial_jtag_obj->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; if (p_usb_serial_jtag_obj == NULL) { ESP_LOGE(USB_SERIAL_JTAG_TAG, "memory allocate error"); err = ESP_ERR_NO_MEM; goto _exit; } + p_usb_serial_jtag_obj->rx_buf_size = usb_serial_jtag_config->rx_buffer_size; + p_usb_serial_jtag_obj->tx_buf_size = usb_serial_jtag_config->tx_buffer_size; + p_usb_serial_jtag_obj->tx_stash_cnt = 0; + p_usb_serial_jtag_obj->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; p_usb_serial_jtag_obj->rx_ring_buf = xRingbufferCreate(p_usb_serial_jtag_obj->rx_buf_size, RINGBUF_TYPE_BYTEBUF); if (p_usb_serial_jtag_obj->rx_ring_buf == NULL) { From b85736f6a60eb33502253d0119983d7c7c18cd19 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:15:29 +0700 Subject: [PATCH 02/10] fix(esp_hw_support): fix warnings found by GNU static analyzer --- components/esp_hw_support/dma/gdma.c | 2 +- components/esp_hw_support/esp_clock_output.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index 1686d46dc8..4f4d8893c8 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -135,8 +135,8 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear for (int i = start_group_id; i < end_group_id && search_code; i++) { // loop to search group group = gdma_acquire_group_handle(i, search_info->hal_init); - group->bus_id = search_info->bus_id; ESP_GOTO_ON_FALSE(group, ESP_ERR_NO_MEM, err, TAG, "no mem for group(%d)", i); + group->bus_id = search_info->bus_id; for (int j = 0; j < pairs_per_group && search_code; j++) { // loop to search pair pair = gdma_acquire_pair_handle(group, j); ESP_GOTO_ON_FALSE(pair, ESP_ERR_NO_MEM, err, TAG, "no mem for pair(%d,%d)", i, j); diff --git a/components/esp_hw_support/esp_clock_output.c b/components/esp_hw_support/esp_clock_output.c index e8e3179fa9..9ad86ce4cf 100644 --- a/components/esp_hw_support/esp_clock_output.c +++ b/components/esp_hw_support/esp_clock_output.c @@ -63,7 +63,9 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } - allocated_channel->channel_id = (clock_out_channel_t)IONUM_TO_CLKOUT_CHANNEL(gpio_num); + if (allocated_channel != NULL) { + allocated_channel->channel_id = (clock_out_channel_t)IONUM_TO_CLKOUT_CHANNEL(gpio_num); + } portEXIT_CRITICAL(&s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].clkout_channel_lock); #elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX for (uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { @@ -117,6 +119,9 @@ static esp_clock_output_mapping_t* clkout_mapping_alloc(clkout_channel_handle_t* if (allocated_mapping == NULL) { allocated_mapping = (esp_clock_output_mapping_t *)malloc(sizeof(esp_clock_output_mapping_t)); + if (!allocated_mapping) { + return NULL; + } allocated_mapping->mapped_io = gpio_num; allocated_mapping->clkout_channel_hdl = channel_hdl; allocated_mapping->ref_cnt = 0; From 505647292d701a1d1e5f4760f699ec544c284f9c Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:17:27 +0700 Subject: [PATCH 03/10] fix(esp_mm): fix warnings found by GNU static analyzer --- components/esp_mm/esp_cache.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/components/esp_mm/esp_cache.c b/components/esp_mm/esp_cache.c index 84a265a219..81fb0d98e0 100644 --- a/components/esp_mm/esp_cache.c +++ b/components/esp_mm/esp_cache.c @@ -147,7 +147,7 @@ esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *a *out_ptr = NULL; while (flag_nums--) { - flags = va_arg(argp, uint32_t); + flags = va_arg(argp, int); ret = esp_cache_aligned_malloc_internal(size, flags, out_ptr, actual_size); if (ret == ESP_OK) { break; @@ -201,8 +201,6 @@ esp_err_t esp_cache_aligned_calloc_prefer(size_t n, size_t size, void **out_ptr, if (ret == ESP_OK) { memset(ptr, 0, size_bytes); *out_ptr = ptr; - - arg = va_arg(argp, int); break; } From fcd2aee74d7b42b27a7fcc2400255ae07d5ce0cb Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:18:04 +0700 Subject: [PATCH 04/10] fix(heap): fix warnings found by GNU static analyzer --- components/heap/heap_caps_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/heap/heap_caps_init.c b/components/heap/heap_caps_init.c index a096471e6c..22e0b2436d 100644 --- a/components/heap/heap_caps_init.c +++ b/components/heap/heap_caps_init.c @@ -101,6 +101,7 @@ void heap_caps_init(void) const soc_memory_type_desc_t *type = &soc_memory_types[region->type]; heap_t *heap = &temp_heaps[heap_idx]; if (region->type == -1) { + memset(heap, 0, sizeof(*heap)); continue; } heap_idx++; From 0815f6ab8cdf7af92283f3b2907f2ef2f2de14cf Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:18:30 +0700 Subject: [PATCH 05/10] fix(sdmmc): fix warnings found by GNU static analyzer --- components/sdmmc/sdmmc_io.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/sdmmc/sdmmc_io.c b/components/sdmmc/sdmmc_io.c index 86f471b8ac..ae0225b260 100644 --- a/components/sdmmc/sdmmc_io.c +++ b/components/sdmmc/sdmmc_io.c @@ -327,7 +327,9 @@ esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int func, return ESP_ERR_INVALID_ARG; } memset(card->host.dma_aligned_buffer, 0xcc, SDMMC_IO_BLOCK_SIZE); - memcpy(card->host.dma_aligned_buffer, datap, datalen); + if (arg & SD_ARG_CMD53_WRITE) { + memcpy(card->host.dma_aligned_buffer, datap, datalen); + } cmd.data = card->host.dma_aligned_buffer; cmd.buflen = SDMMC_IO_BLOCK_SIZE; } @@ -362,7 +364,8 @@ esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int func, err = sdmmc_send_cmd(card, &cmd); - if (datalen > 0 && cmd.data == card->host.dma_aligned_buffer) { + if (arg & SD_ARG_CMD53_READ && + datalen > 0 && cmd.data == card->host.dma_aligned_buffer) { assert(datalen <= SDMMC_IO_BLOCK_SIZE); memcpy(datap, card->host.dma_aligned_buffer, datalen); } From edbf6130db48649cb6c0c05cd4182646ed7c7308 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:18:52 +0700 Subject: [PATCH 06/10] fix(vfs): fix warnings found by GNU static analyzer --- components/vfs/vfs_eventfd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components/vfs/vfs_eventfd.c b/components/vfs/vfs_eventfd.c index a9a979cf9c..a8ae79d1b9 100644 --- a/components/vfs/vfs_eventfd.c +++ b/components/vfs/vfs_eventfd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -107,12 +107,16 @@ static esp_err_t event_start_select(int nfds, for (int i = 0; i < nfds; i++) { _lock_acquire_recursive(&s_events[i].lock); if (s_events[i].fd == i && (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))) { + event_select_args_t *event_select_args = + (event_select_args_t *)malloc(sizeof(event_select_args_t)); + if (!event_select_args) { + _lock_release_recursive(&s_events[i].lock); + return ESP_ERR_NO_MEM; + } if (s_events[i].support_isr) { portENTER_CRITICAL(&s_events[i].data_spin_lock); } - event_select_args_t *event_select_args = - (event_select_args_t *)malloc(sizeof(event_select_args_t)); event_select_args->fd = i; event_select_args->signal_sem = signal_sem; From f328e06ed472aaeb0b5155aaf05297e2b064921c Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:20:06 +0700 Subject: [PATCH 07/10] fix(wpa_supplicant): fix warnings found by GNU static analyzer --- components/wpa_supplicant/src/ap/ieee802_1x.c | 2 ++ components/wpa_supplicant/src/common/ieee802_11_common.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/components/wpa_supplicant/src/ap/ieee802_1x.c b/components/wpa_supplicant/src/ap/ieee802_1x.c index 5e3c078baf..eb623cecab 100644 --- a/components/wpa_supplicant/src/ap/ieee802_1x.c +++ b/components/wpa_supplicant/src/ap/ieee802_1x.c @@ -433,6 +433,8 @@ int ieee802_1x_init(struct hostapd_data *hapd) os_memset(&conf, 0, sizeof(conf)); eap_cfg = os_zalloc(sizeof(struct eap_config)); + if (!eap_cfg) + return -1; eap_cfg->max_auth_rounds = 100; eap_cfg->max_auth_rounds_short = 50; //eap_cfg->backend_auth = 1; diff --git a/components/wpa_supplicant/src/common/ieee802_11_common.c b/components/wpa_supplicant/src/common/ieee802_11_common.c index ed44d3532e..61a753f442 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_common.c +++ b/components/wpa_supplicant/src/common/ieee802_11_common.c @@ -202,6 +202,10 @@ static int ieee802_11_parse_vendor_specific(struct wpa_supplicant *wpa_s, const case SAE_PK_OUI_TYPE: wpa_s->sae_pk_elems.sae_pk_len = elem->datalen - 4; wpa_s->sae_pk_elems.sae_pk = (u8*)os_zalloc(sizeof(u8)*(elem->datalen-4)); + if (!wpa_s->sae_pk_elems.sae_pk) { + wpa_printf(MSG_EXCESSIVE, "Can not allocate memory for sae_pk"); + return -1; + } os_memcpy(wpa_s->sae_pk_elems.sae_pk, pos+4, elem->datalen-4); break; default: From 75277a9419e88e3729ef10db788ab5ddf7a09794 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Mon, 17 Jun 2024 23:06:30 +0700 Subject: [PATCH 08/10] fix(esp_driver_parlio): fix warnings found by GNU static analyzer --- components/esp_driver_parlio/src/parlio_tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index 20a0fdc4bc..3dfeb9f9d0 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -389,10 +389,12 @@ static void IRAM_ATTR parlio_tx_mount_dma_data(parlio_tx_unit_t *tx_unit, const { size_t prepared_length = 0; uint8_t *data = (uint8_t *)buffer; + uint32_t mount_bytes = 0; parlio_dma_desc_t *desc_nc = tx_unit->dma_nodes_nc; while (len) { - uint32_t mount_bytes = len > DMA_DESCRIPTOR_BUFFER_MAX_SIZE ? DMA_DESCRIPTOR_BUFFER_MAX_SIZE : len; + assert(desc_nc); + mount_bytes = len > DMA_DESCRIPTOR_BUFFER_MAX_SIZE ? DMA_DESCRIPTOR_BUFFER_MAX_SIZE : len; len -= mount_bytes; desc_nc->dw0.suc_eof = (len == 0); // whether the last frame desc_nc->dw0.size = mount_bytes; From e1b9985bd0bcb2c5733474dada483852ae4c8a83 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Tue, 18 Jun 2024 00:17:15 +0700 Subject: [PATCH 09/10] fix(usb): fix warnings found by GNU static analyzer --- components/usb/hcd_dwc.c | 5 ++++- components/usb/usb_phy.c | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/components/usb/hcd_dwc.c b/components/usb/hcd_dwc.c index ebfd2c8e79..8187eea967 100644 --- a/components/usb/hcd_dwc.c +++ b/components/usb/hcd_dwc.c @@ -1593,9 +1593,12 @@ static dma_buffer_block_t *buffer_block_alloc(usb_transfer_type_t type) break; } dma_buffer_block_t *buffer = calloc(1, sizeof(dma_buffer_block_t)); + if (buffer == NULL) { + return NULL; + } size_t real_len = 0; void *xfer_desc_list = transfer_descriptor_list_alloc(desc_list_len, &real_len); - if (buffer == NULL || xfer_desc_list == NULL) { + if (xfer_desc_list == NULL) { free(buffer); heap_caps_free(xfer_desc_list); return NULL; diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index cfaf90abd2..7ae5e5f382 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -340,8 +340,10 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r return ESP_OK; cleanup: - free(phy_context->iopins); - free(phy_context); + if (phy_context) { + free(phy_context->iopins); + free(phy_context); + } if (p_phy_ctrl_obj->ref_count == 0) { free(p_phy_ctrl_obj); p_phy_ctrl_obj = NULL; From ed6e497c6f96ab3740e057413e8355e875879b1e Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 6 Jun 2024 15:23:02 +0700 Subject: [PATCH 10/10] feat(build): add COMPILER_STATIC_ANALYZER option --- .gitlab/ci/build.yml | 16 ++++++++++ CMakeLists.txt | 8 +++-- Kconfig | 11 +++++++ components/console/CMakeLists.txt | 4 +++ components/driver/CMakeLists.txt | 5 +++ components/driver/deprecated/rmt_legacy.c | 5 ++- .../deprecated/rtc_temperature_legacy.c | 3 ++ components/efuse/CMakeLists.txt | 7 ++++ components/esp-tls/esp_tls_error_capture.c | 3 ++ components/esp_common/include/esp_compiler.h | 32 +++++++++++++++++-- components/esp_driver_rmt/src/rmt_tx.c | 2 ++ components/esp_hw_support/CMakeLists.txt | 4 +++ .../esp_lcd/i2c/esp_lcd_panel_io_i2c_v1.c | 6 +++- .../esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c | 5 +++ .../esp_lcd/src/esp_lcd_panel_nt35510.c | 6 +++- .../esp_lcd/src/esp_lcd_panel_ssd1306.c | 6 +++- components/esp_lcd/src/esp_lcd_panel_st7789.c | 6 +++- .../src/esp_local_ctrl_handler.c | 21 +++++------- components/esp_mm/esp_cache.c | 3 ++ components/esp_mm/esp_mmu_map.c | 3 ++ components/esp_netif/lwip/esp_netif_lwip.c | 4 +++ components/esp_ringbuf/ringbuf.c | 14 ++------ components/esp_system/panic.c | 5 ++- components/esp_system/startup.c | 6 +++- components/esp_timer/src/esp_timer.c | 5 ++- components/freertos/CMakeLists.txt | 8 +++++ .../freertos_tasks_c_additions.h | 3 ++ components/hal/CMakeLists.txt | 5 +++ components/hal/esp32s2/include/hal/spi_ll.h | 3 ++ components/mbedtls/CMakeLists.txt | 3 ++ components/newlib/scandir.c | 5 ++- components/nvs_flash/CMakeLists.txt | 4 +++ components/pthread/pthread.c | 4 +++ components/tcp_transport/transport.c | 3 ++ components/tcp_transport/transport_ssl.c | 12 +++++++ components/tcp_transport/transport_ws.c | 4 ++- components/usb/CMakeLists.txt | 4 +++ components/wear_levelling/CMakeLists.txt | 4 +++ components/wpa_supplicant/CMakeLists.txt | 4 +++ docs/en/api-guides/code-quality/index.rst | 14 ++++++++ .../code-quality/static-analyzer.rst | 31 ++++++++++++++++++ docs/en/api-guides/index.rst | 1 + docs/zh_CN/api-guides/code-quality/index.rst | 1 + .../code-quality/static-analyzer.rst | 1 + docs/zh_CN/api-guides/index.rst | 1 + tools/ci/check_copyright_ignore.txt | 1 - 46 files changed, 265 insertions(+), 41 deletions(-) create mode 100644 docs/en/api-guides/code-quality/index.rst create mode 100644 docs/en/api-guides/code-quality/static-analyzer.rst create mode 100644 docs/zh_CN/api-guides/code-quality/index.rst create mode 100644 docs/zh_CN/api-guides/code-quality/static-analyzer.rst diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index d426199070..ae74e4165f 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -112,6 +112,22 @@ fast_template_app: BUILD_COMMAND_ARGS: "-p" #------------------------------------------------------------------------------ +####################### +# gnu_static_analyzer # +####################### +gcc_static_analyzer: + extends: + - .build_template_app_template + - .rules:build:target_test + stage: pre_check + tags: [build, shiny] + variables: + CI_CCACHE_DISABLE: 1 + ANALYZING_APP: "examples/get-started/hello_world" + script: + - echo "CONFIG_COMPILER_STATIC_ANALYZER=y" >> ${ANALYZING_APP}/sdkconfig.defaults + - python -m idf_build_apps build -vv -p ${ANALYZING_APP} -t all + ######################################## # Clang Build Apps Without Tests Cases # ######################################## diff --git a/CMakeLists.txt b/CMakeLists.txt index 722b07b973..ef957586dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang") list(APPEND compile_options "-Wno-pointer-bool-conversion") # mbedTLS md5.c triggers this warning in md5_test_buf (false positive) list(APPEND compile_options "-Wno-string-concatenation") - # multiple cases of implict convertions between unrelated enum types + # multiple cases of implicit conversions between unrelated enum types list(APPEND compile_options "-Wno-enum-conversion") # When IRAM_ATTR is specified both in function declaration and definition, # it produces different section names, since section names include __COUNTER__. @@ -203,8 +203,10 @@ endif() # GCC-specific options if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - list(APPEND compile_options "-fstrict-volatile-bitfields" - ) + list(APPEND compile_options "-fstrict-volatile-bitfields") + if(CONFIG_COMPILER_STATIC_ANALYZER) + list(APPEND compile_options "-fanalyzer") + endif() endif() if(CONFIG_ESP_SYSTEM_USE_EH_FRAME) diff --git a/Kconfig b/Kconfig index f99751e7a1..26584d0aad 100644 --- a/Kconfig +++ b/Kconfig @@ -48,6 +48,10 @@ mainmenu "Espressif IoT Development Framework Configuration" bool default "y" if IDF_TOOLCHAIN="clang" + config IDF_TOOLCHAIN_GCC + bool + default "y" if IDF_TOOLCHAIN="gcc" + config IDF_TARGET_ARCH_RISCV bool default "n" @@ -606,6 +610,13 @@ mainmenu "Espressif IoT Development Framework Configuration" Places orphan sections without a warning/error message. endchoice + config COMPILER_STATIC_ANALYZER + bool "Enable compiler static analyzer" + default "n" + depends on IDF_TOOLCHAIN_GCC + help + Enable compiler static analyzer. This may produce false-positive results and increases compile time. + endmenu # Compiler Options menu "Component config" diff --git a/components/console/CMakeLists.txt b/components/console/CMakeLists.txt index 2343e088ff..09eecbd209 100644 --- a/components/console/CMakeLists.txt +++ b/components/console/CMakeLists.txt @@ -37,3 +37,7 @@ idf_component_register(SRCS ${srcs} PRIV_REQUIRES esp_driver_uart esp_driver_usb_serial_jtag ) + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10085 + target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer") +endif() diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index e350e1a72f..16cebcc432 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -111,4 +111,9 @@ else() esp_driver_uart esp_driver_ledc esp_driver_parlio esp_driver_usb_serial_jtag LDFRAGMENTS ${ldfragments} ) + if(CONFIG_SOC_ADC_SUPPORTED AND + CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO GCC-366 + set_source_files_properties(deprecated/adc_legacy.c + PROPERTIES COMPILE_FLAGS "-Wno-analyzer-use-of-uninitialized-value") + endif() endif() diff --git a/components/driver/deprecated/rmt_legacy.c b/components/driver/deprecated/rmt_legacy.c index 16d120725b..67e8133df2 100644 --- a/components/driver/deprecated/rmt_legacy.c +++ b/components/driver/deprecated/rmt_legacy.c @@ -27,6 +27,7 @@ #include "hal/rmt_ll.h" #include "hal/gpio_hal.h" #include "esp_rom_gpio.h" +#include "esp_compiler.h" #define RMT_CHANNEL_ERROR_STR "RMT CHANNEL ERR" #define RMT_ADDR_ERROR_STR "RMT ADDRESS ERR" @@ -1061,6 +1062,7 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr #if SOC_RMT_SUPPORT_RX_PINGPONG if (p_rmt_obj[channel]->rx_item_buf == NULL && rx_buf_size > 0) { + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // False-positive detection. TODO GCC-366 #if !CONFIG_SPIRAM_USE_MALLOC p_rmt_obj[channel]->rx_item_buf = calloc(1, rx_buf_size); #else @@ -1074,6 +1076,7 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr ESP_LOGE(TAG, "RMT malloc fail"); return ESP_FAIL; } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") p_rmt_obj[channel]->rx_item_buf_size = rx_buf_size; } #endif @@ -1237,7 +1240,7 @@ esp_err_t rmt_translator_get_context(const size_t *item_num, void **context) { ESP_RETURN_ON_FALSE(item_num && context, ESP_ERR_INVALID_ARG, TAG, "invalid arguments"); - // the address of tx_len_rem is directlly passed to the callback, + // the address of tx_len_rem is directly passed to the callback, // so it's possible to get the object address from that rmt_obj_t *obj = __containerof(item_num, rmt_obj_t, tx_len_rem); *context = obj->tx_context; diff --git a/components/driver/deprecated/rtc_temperature_legacy.c b/components/driver/deprecated/rtc_temperature_legacy.c index 97e700fa80..d0da188faa 100644 --- a/components/driver/deprecated/rtc_temperature_legacy.c +++ b/components/driver/deprecated/rtc_temperature_legacy.c @@ -11,6 +11,7 @@ #include "esp_types.h" #include "esp_log.h" #include "esp_check.h" +#include "esp_compiler.h" #include "freertos/FreeRTOS.h" #include "esp_private/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" @@ -110,7 +111,9 @@ esp_err_t temp_sensor_stop(void) esp_err_t temp_sensor_read_raw(uint32_t *tsens_out) { ESP_RETURN_ON_FALSE(tsens_out != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens_out specified"); + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-use-of-uninitialized-value") // False-positive detection. TODO GCC-366 *tsens_out = temperature_sensor_ll_get_raw_value(); + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-use-of-uninitialized-value") return ESP_OK; } diff --git a/components/efuse/CMakeLists.txt b/components/efuse/CMakeLists.txt index e0f57b1d34..b42eb753de 100644 --- a/components/efuse/CMakeLists.txt +++ b/components/efuse/CMakeLists.txt @@ -94,3 +94,10 @@ set(EFUSE_TEST_TABLE_CSV_PATH "${COMPONENT_DIR}/test/esp_efuse_test_table.csv") add_custom_target(efuse_test_table COMMAND "${python}" "${CMAKE_CURRENT_SOURCE_DIR}/efuse_table_gen.py" ${EFUSE_TEST_TABLE_CSV_PATH} ${GEN_EFUSE_TABLE_ARG}) + +################### +# GNU analyzer excludes +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10086 + set_source_files_properties(src/esp_efuse_utility.c + PROPERTIES COMPILE_FLAGS "-fno-analyzer") +endif() diff --git a/components/esp-tls/esp_tls_error_capture.c b/components/esp-tls/esp_tls_error_capture.c index 67d6ec90cb..f5dbcf5dbe 100644 --- a/components/esp-tls/esp_tls_error_capture.c +++ b/components/esp-tls/esp_tls_error_capture.c @@ -7,6 +7,7 @@ #include #include "esp_tls.h" #include "esp_tls_error_capture_internal.h" +#include "esp_compiler.h" typedef struct esp_tls_error_storage { struct esp_tls_last_error parent; /*!< standard esp-tls last error container */ @@ -34,11 +35,13 @@ void esp_tls_internal_event_tracker_capture(esp_tls_error_handle_t h, uint32_t t esp_tls_error_handle_t esp_tls_internal_event_tracker_create(void) { + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // Allocating internal error storage which extends the parent type // `esp_tls_last_error` defined at interface level struct esp_tls_error_storage* storage = calloc(1, sizeof(struct esp_tls_error_storage)); return &storage->parent; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } void esp_tls_internal_event_tracker_destroy(esp_tls_error_handle_t h) diff --git a/components/esp_common/include/esp_compiler.h b/components/esp_common/include/esp_compiler.h index 3e278aa9c0..6c82a407cc 100644 --- a/components/esp_common/include/esp_compiler.h +++ b/components/esp_common/include/esp_compiler.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,7 @@ /* * The likely and unlikely macro pairs: * These macros are useful to place when application - * knows the majority ocurrence of a decision paths, + * knows the majority occurrence of a decision paths, * placing one of these macros can hint the compiler * to reorder instructions producing more optimized * code. @@ -52,3 +52,31 @@ #define ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(member, value) .member = value, #define ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(member) #endif + +#define __COMPILER_PRAGMA__(string) _Pragma(#string) +#define _COMPILER_PRAGMA_(string) __COMPILER_PRAGMA__(string) + +#if __clang__ +#define ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE(warning) \ + __COMPILER_PRAGMA__(clang diagnostic push) \ + __COMPILER_PRAGMA__(clang diagnostic ignored "-Wunknown-warning-option") \ + __COMPILER_PRAGMA__(clang diagnostic ignored warning) +#define ESP_COMPILER_DIAGNOSTIC_POP(warning) \ + __COMPILER_PRAGMA__(clang diagnostic pop) +#elif __GNUC__ +#define ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE(warning) \ + __COMPILER_PRAGMA__(GCC diagnostic push) \ + __COMPILER_PRAGMA__(GCC diagnostic ignored "-Wpragmas") \ + __COMPILER_PRAGMA__(GCC diagnostic ignored warning) +#define ESP_COMPILER_DIAGNOSTIC_POP(warning) \ + __COMPILER_PRAGMA__(GCC diagnostic pop) +#else +#define ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE(warning) +#define ESP_COMPILER_DIAGNOSTIC_POP(warning) +#endif + +#if __clang_analyzer__ || CONFIG_COMPILER_STATIC_ANALYZER +#define ESP_STATIC_ANALYZER_CHECK(_expr_, _ret_) do { if ((_expr_)) { return (_ret_); } } while(0) +#else +#define ESP_STATIC_ANALYZER_CHECK(_expr_, _ret_) +#endif diff --git a/components/esp_driver_rmt/src/rmt_tx.c b/components/esp_driver_rmt/src/rmt_tx.c index 2b3478967f..915b68d0d3 100644 --- a/components/esp_driver_rmt/src/rmt_tx.c +++ b/components/esp_driver_rmt/src/rmt_tx.c @@ -1106,6 +1106,7 @@ static void IRAM_ATTR rmt_tx_default_isr(void *args) } #if SOC_RMT_SUPPORT_DMA +ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-dereference") // TODO IDF-10235 static bool IRAM_ATTR rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { rmt_tx_channel_t *tx_chan = (rmt_tx_channel_t *)user_data; @@ -1132,4 +1133,5 @@ static bool IRAM_ATTR rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_eve } return false; } +ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-dereference") #endif // SOC_RMT_SUPPORT_DMA diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 12a05f4682..45eb393269 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -189,6 +189,10 @@ idf_build_get_property(target IDF_TARGET) add_subdirectory(port/${target}) add_subdirectory(lowpower) +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10229 + target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer") +endif() + if(NOT BOOTLOADER_BUILD) if(CONFIG_SPIRAM) idf_component_optional_requires(PRIVATE esp_psram) diff --git a/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v1.c b/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v1.c index 3928d81ed9..b50814dd67 100644 --- a/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v1.c +++ b/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v1.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ #include "driver/gpio.h" #include "esp_log.h" #include "esp_check.h" +#include "esp_compiler.h" static const char *TAG = "lcd_panel.io.i2c"; @@ -47,6 +48,8 @@ typedef struct { esp_err_t esp_lcd_new_panel_io_i2c_v1(uint32_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io) { + // leak detection of i2c_panel_io because saving i2c_panel_io->base address + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") #if CONFIG_LCD_ENABLE_DEBUG_LOG esp_log_level_set(TAG, ESP_LOG_DEBUG); #endif @@ -78,6 +81,7 @@ esp_err_t esp_lcd_new_panel_io_i2c_v1(uint32_t bus, const esp_lcd_panel_io_i2c_c return ESP_OK; err: return ret; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } static esp_err_t panel_io_i2c_del(esp_lcd_panel_io_t *io) diff --git a/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c b/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c index 77e2e54c63..9dde28921d 100644 --- a/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c +++ b/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c @@ -21,6 +21,8 @@ #include "esp_check.h" #include "freertos/FreeRTOS.h" #include "esp_heap_caps.h" +#include "esp_compiler.h" + static const char *TAG = "lcd_panel.io.i2c"; #define BYTESHIFT(VAR, IDX) (((VAR) >> ((IDX) * 8)) & 0xFF) @@ -56,6 +58,8 @@ esp_err_t esp_lcd_new_panel_io_i2c_v2(i2c_master_bus_handle_t bus, const esp_lcd i2c_master_dev_handle_t i2c_handle = NULL; ESP_GOTO_ON_FALSE(io_config && ret_io, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(io_config->control_phase_bytes * 8 > io_config->dc_bit_offset, ESP_ERR_INVALID_ARG, err, TAG, "D/C bit exceeds control bytes"); + // leak detection of i2c_panel_io because saving i2c_panel_io->base address + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") i2c_panel_io = calloc(1, sizeof(lcd_panel_io_i2c_t)); ESP_GOTO_ON_FALSE(i2c_panel_io, ESP_ERR_NO_MEM, err, TAG, "no mem for i2c panel io"); @@ -88,6 +92,7 @@ err: free(i2c_panel_io); } return ret; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } static esp_err_t panel_io_i2c_del(esp_lcd_panel_io_t *io) diff --git a/components/esp_lcd/src/esp_lcd_panel_nt35510.c b/components/esp_lcd/src/esp_lcd_panel_nt35510.c index 5a9e342738..06e3079912 100644 --- a/components/esp_lcd/src/esp_lcd_panel_nt35510.c +++ b/components/esp_lcd/src/esp_lcd_panel_nt35510.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "driver/gpio.h" #include "esp_log.h" #include "esp_check.h" +#include "esp_compiler.h" static const char *TAG = "lcd_panel.nt35510"; @@ -61,6 +62,8 @@ esp_lcd_new_panel_nt35510(const esp_lcd_panel_io_handle_t io, const esp_lcd_pane esp_err_t ret = ESP_OK; nt35510_panel_t *nt35510 = NULL; ESP_GOTO_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + // leak detection of nt35510 because saving nt35510->base address + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") nt35510 = calloc(1, sizeof(nt35510_panel_t)); ESP_GOTO_ON_FALSE(nt35510, ESP_ERR_NO_MEM, err, TAG, "no mem for nt35510 panel"); @@ -131,6 +134,7 @@ err: free(nt35510); } return ret; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } static esp_err_t panel_nt35510_del(esp_lcd_panel_t *panel) diff --git a/components/esp_lcd/src/esp_lcd_panel_ssd1306.c b/components/esp_lcd/src/esp_lcd_panel_ssd1306.c index fbac5c0884..05bc317cd8 100644 --- a/components/esp_lcd/src/esp_lcd_panel_ssd1306.c +++ b/components/esp_lcd/src/esp_lcd_panel_ssd1306.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,7 @@ #include "driver/gpio.h" #include "esp_log.h" #include "esp_check.h" +#include "esp_compiler.h" static const char *TAG = "lcd_panel.ssd1306"; @@ -73,6 +74,8 @@ esp_err_t esp_lcd_new_panel_ssd1306(const esp_lcd_panel_io_handle_t io, const es ESP_GOTO_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(panel_dev_config->bits_per_pixel == 1, ESP_ERR_INVALID_ARG, err, TAG, "bpp must be 1"); esp_lcd_panel_ssd1306_config_t *ssd1306_spec_config = (esp_lcd_panel_ssd1306_config_t *)panel_dev_config->vendor_config; + // leak detection of ssd1306 because saving ssd1306->base address + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") ssd1306 = calloc(1, sizeof(ssd1306_panel_t)); ESP_GOTO_ON_FALSE(ssd1306, ESP_ERR_NO_MEM, err, TAG, "no mem for ssd1306 panel"); @@ -111,6 +114,7 @@ err: free(ssd1306); } return ret; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } static esp_err_t panel_ssd1306_del(esp_lcd_panel_t *panel) diff --git a/components/esp_lcd/src/esp_lcd_panel_st7789.c b/components/esp_lcd/src/esp_lcd_panel_st7789.c index 8076fce67a..5c3625cf07 100644 --- a/components/esp_lcd/src/esp_lcd_panel_st7789.c +++ b/components/esp_lcd/src/esp_lcd_panel_st7789.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "driver/gpio.h" #include "esp_log.h" #include "esp_check.h" +#include "esp_compiler.h" #define ST7789_CMD_RAMCTRL 0xb0 #define ST7789_DATA_LITTLE_ENDIAN_BIT (1 << 3) @@ -66,6 +67,8 @@ esp_lcd_new_panel_st7789(const esp_lcd_panel_io_handle_t io, const esp_lcd_panel esp_err_t ret = ESP_OK; st7789_panel_t *st7789 = NULL; ESP_GOTO_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + // leak detection of st7789 because saving st7789->base address + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") st7789 = calloc(1, sizeof(st7789_panel_t)); ESP_GOTO_ON_FALSE(st7789, ESP_ERR_NO_MEM, err, TAG, "no mem for st7789 panel"); @@ -139,6 +142,7 @@ err: free(st7789); } return ret; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } static esp_err_t panel_st7789_del(esp_lcd_panel_t *panel) diff --git a/components/esp_local_ctrl/src/esp_local_ctrl_handler.c b/components/esp_local_ctrl/src/esp_local_ctrl_handler.c index 53db309c71..65a6b4ed7a 100644 --- a/components/esp_local_ctrl/src/esp_local_ctrl_handler.c +++ b/components/esp_local_ctrl/src/esp_local_ctrl_handler.c @@ -1,22 +1,15 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include #include #include +#include "esp_compiler.h" #include "esp_local_ctrl.h" #include "esp_local_ctrl_priv.h" #include "esp_local_ctrl.pb-c.h" @@ -127,11 +120,13 @@ static esp_err_t cmd_get_prop_vals_handler(LocalCtrlMessage *req, if (ret == ESP_OK) { resp_payload->n_props = 0; for (size_t i = 0; i < req->cmd_get_prop_vals->n_indices; i++) { + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // False-positive detection. TODO GCC-366 resp_payload->props[i] = malloc(sizeof(PropertyInfo)); if (!resp_payload->props[i]) { resp_payload->status = STATUS__InternalError; break; } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") resp_payload->n_props++; property_info__init(resp_payload->props[i]); resp_payload->props[i]->name = descs[i].name; diff --git a/components/esp_mm/esp_cache.c b/components/esp_mm/esp_cache.c index 81fb0d98e0..b87925bb7d 100644 --- a/components/esp_mm/esp_cache.c +++ b/components/esp_mm/esp_cache.c @@ -17,6 +17,7 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" #include "esp_cache.h" +#include "esp_compiler.h" #include "esp_private/esp_cache_private.h" #include "esp_private/critical_section.h" @@ -199,8 +200,10 @@ esp_err_t esp_cache_aligned_calloc_prefer(size_t n, size_t size, void **out_ptr, arg = va_arg(argp, int); ret = esp_cache_aligned_malloc_internal(size_bytes, arg, &ptr, actual_size); if (ret == ESP_OK) { + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-argument") memset(ptr, 0, size_bytes); *out_ptr = ptr; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-argument") break; } diff --git a/components/esp_mm/esp_mmu_map.c b/components/esp_mm/esp_mmu_map.c index 226ec38e0c..498497a4ce 100644 --- a/components/esp_mm/esp_mmu_map.c +++ b/components/esp_mm/esp_mmu_map.c @@ -14,6 +14,7 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_heap_caps.h" +#include "esp_compiler.h" #include "soc/soc_caps.h" #include "hal/cache_types.h" @@ -630,9 +631,11 @@ esp_err_t esp_mmu_unmap(void *ptr) size_t slot_len = 0; for (int i = 0; i < s_mmu_ctx.num_regions; i++) { + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-out-of-bounds") if (ptr_laddr >= s_mmu_ctx.mem_regions[i].free_head && ptr_laddr < s_mmu_ctx.mem_regions[i].end) { region = &s_mmu_ctx.mem_regions[i]; } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-out-of-bounds") } ESP_RETURN_ON_FALSE(region, ESP_ERR_NOT_FOUND, TAG, "munmap target pointer is outside external memory regions"); diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 11f377f957..bc057075d9 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -9,6 +9,7 @@ #include #include +#include "esp_compiler.h" #include "esp_check.h" #include "esp_netif_lwip_internal.h" #include "lwip/esp_netif_net_stack.h" @@ -859,12 +860,15 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif) static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif) { + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak"); // False-positive detection. TODO GCC-366 if (esp_netif->lwip_netif == NULL) { esp_netif->lwip_netif = calloc(1, sizeof(struct netif)); if (esp_netif->lwip_netif == NULL) { return ESP_ERR_NO_MEM; } } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak"); + if (esp_netif->flags & ESP_NETIF_FLAG_IS_PPP) { #if CONFIG_PPP_SUPPORT err_t err = esp_netif->lwip_init_fn(NULL); diff --git a/components/esp_ringbuf/ringbuf.c b/components/esp_ringbuf/ringbuf.c index 18ff802a3c..aa877f38d2 100644 --- a/components/esp_ringbuf/ringbuf.c +++ b/components/esp_ringbuf/ringbuf.c @@ -822,12 +822,7 @@ static BaseType_t prvReceiveGeneric(Ringbuffer_t *pxRingbuffer, BaseType_t xEntryTimeSet = pdFALSE; TimeOut_t xTimeOut; -#ifdef __clang_analyzer__ - // Teach clang-tidy that if NULL pointers are provided, this function will never dereference them - if (!pvItem1 || !pvItem2 || !xItemSize1 || !xItemSize2) { - return pdFALSE; - } -#endif /*__clang_analyzer__ */ + ESP_STATIC_ANALYZER_CHECK(!pvItem1 || !pvItem2 || !xItemSize1 || !xItemSize2, pdFALSE); while (xExitLoop == pdFALSE) { portENTER_CRITICAL(&pxRingbuffer->mux); @@ -888,12 +883,7 @@ static BaseType_t prvReceiveGenericFromISR(Ringbuffer_t *pxRingbuffer, { BaseType_t xReturn = pdFALSE; -#ifdef __clang_analyzer__ - // Teach clang-tidy that if NULL pointers are provided, this function will never dereference them - if (!pvItem1 || !pvItem2 || !xItemSize1 || !xItemSize2) { - return pdFALSE; - } -#endif /*__clang_analyzer__ */ + ESP_STATIC_ANALYZER_CHECK(!pvItem1 || !pvItem2 || !xItemSize1 || !xItemSize2, pdFALSE); portENTER_CRITICAL_ISR(&pxRingbuffer->mux); if (prvCheckItemAvail(pxRingbuffer) == pdTRUE) { diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index fd28c7695c..20851d554c 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -8,6 +8,7 @@ #include "esp_err.h" #include "esp_attr.h" +#include "esp_compiler.h" #include "esp_private/system_internal.h" #include "esp_private/usb_console.h" @@ -221,7 +222,7 @@ static inline void disable_all_wdts(void) wdt_hal_write_protect_enable(&wdt0_context); #if SOC_TIMER_GROUPS >= 2 - //Interupt WDT is the Main Watchdog Timer of Timer Group 1 + //Interrupt WDT is the Main Watchdog Timer of Timer Group 1 wdt_hal_write_protect_disable(&wdt1_context); wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); @@ -460,7 +461,9 @@ void IRAM_ATTR __attribute__((noreturn, no_sanitize_undefined)) panic_abort(cons #endif #endif + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-dereference") *((volatile int *) 0) = 0; // NOLINT(clang-analyzer-core.NullDereference) should be an invalid operation on targets + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-dereference") while (1); } diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index e9af973ff2..f242a2db77 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -9,6 +9,7 @@ #include "esp_attr.h" #include "esp_err.h" +#include "esp_compiler.h" #include "esp_system.h" #include "esp_log.h" @@ -21,7 +22,7 @@ #include "esp_private/startup_internal.h" // Ensure that system configuration matches the underlying number of cores. -// This should enable us to avoid checking for both everytime. +// This should enable us to avoid checking for both every time. #if !(SOC_CPU_CORES_NUM > 1) && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE #error "System has been configured to run on multiple cores, but target SoC only has a single core." #endif @@ -96,10 +97,13 @@ static void do_global_ctors(void) } #endif + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-out-of-bounds") for (p = &__init_array_end - 1; p >= &__init_array_start; --p) { ESP_LOGD(TAG, "calling init function: %p", *p); (*p)(); } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-out-of-bounds") + } /** diff --git a/components/esp_timer/src/esp_timer.c b/components/esp_timer/src/esp_timer.c index 5c0ec368cc..71698b335e 100644 --- a/components/esp_timer/src/esp_timer.c +++ b/components/esp_timer/src/esp_timer.c @@ -18,6 +18,7 @@ #include "esp_ipc.h" #include "esp_timer.h" #include "esp_timer_impl.h" +#include "esp_compiler.h" #include "esp_private/startup_internal.h" #include "esp_private/esp_timer_private.h" @@ -215,7 +216,7 @@ esp_err_t IRAM_ATTR esp_timer_start_once(esp_timer_handle_t timer, uint64_t time timer_list_lock(dispatch_method); /* Check if the timer is armed once the list is locked. - * Otherwise another task may arm the timer inbetween the check + * Otherwise another task may arm the timer between the checks * and us locking the list, resulting in us inserting the * timer to s_timers a second time. This will create a loop * in s_timers. */ @@ -418,9 +419,11 @@ static bool timer_process_alarm(esp_timer_dispatch_t dispatch_method) while (1) { it = LIST_FIRST(&s_timers[dispatch_method]); int64_t now = esp_timer_impl_get_time(); + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-use-after-free") // False-positive detection. TODO GCC-366 if (it == NULL || it->alarm > now) { break; } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-use-after-free") processed = true; LIST_REMOVE(it, list_entry); if (it->event_id == EVENT_ID_DELETE_TIMER) { diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index f640414770..79e11d0c45 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -248,4 +248,12 @@ else() idf_component_optional_requires(PRIVATE esp_pm) endif() + if(CONFIG_IDF_TARGET_ESP32P4 AND NOT CONFIG_FREERTOS_SMP AND + CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # suppress false-positive warning + set_source_files_properties( + "${kernel_impl}/queue.c" + PROPERTIES COMPILE_OPTIONS + "-Wno-analyzer-null-argument" + ) + endif() endif() diff --git a/components/freertos/esp_additions/freertos_tasks_c_additions.h b/components/freertos/esp_additions/freertos_tasks_c_additions.h index ec2236b87a..8c9ce93d78 100644 --- a/components/freertos/esp_additions/freertos_tasks_c_additions.h +++ b/components/freertos/esp_additions/freertos_tasks_c_additions.h @@ -7,6 +7,7 @@ #include "sdkconfig.h" #include "esp_assert.h" #include "esp_heap_caps.h" +#include "esp_compiler.h" #include "freertos/idf_additions.h" #if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT #include "esp_private/freertos_debug.h" @@ -1041,6 +1042,8 @@ int xTaskGetNext( TaskIterator_t * xIterator ) BaseType_t vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t * pxTaskSnapshot ) { + ESP_STATIC_ANALYZER_CHECK(!pxTask, pdFALSE); + if( ( portVALID_TCB_MEM( pxTask ) == false ) || ( pxTaskSnapshot == NULL ) ) { return pdFALSE; diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 2cc5191546..6cc4319dc2 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -326,3 +326,8 @@ if(CONFIG_HAL_DEFAULT_ASSERTION_LEVEL EQUAL 1) elseif(CONFIG_HAL_DEFAULT_ASSERTION_LEVEL EQUAL 2) target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __assert_func") endif() + +if((CONFIG_IDF_TARGET_ESP32H2 OR CONFIG_IDF_TARGET_ESP32S2 OR CONFIG_IDF_TARGET_ESP32S3) AND + CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10234 + target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer") +endif() diff --git a/components/hal/esp32s2/include/hal/spi_ll.h b/components/hal/esp32s2/include/hal/spi_ll.h index 67adaefd0b..efb690877c 100644 --- a/components/hal/esp32s2/include/hal/spi_ll.h +++ b/components/hal/esp32s2/include/hal/spi_ll.h @@ -19,6 +19,7 @@ #include "esp_types.h" #include "esp_attr.h" #include "esp_bit_defs.h" +#include "esp_compiler.h" #include "soc/spi_periph.h" #include "soc/spi_struct.h" #include "soc/spi_reg.h" @@ -1336,6 +1337,7 @@ static inline void spi_dma_ll_rx_enable_burst_desc(spi_dma_dev_t *dma_in, uint32 __attribute__((always_inline)) static inline uint32_t spi_dma_ll_get_in_suc_eof_desc_addr(spi_dma_dev_t *dma_in, uint32_t channel) { + ESP_STATIC_ANALYZER_CHECK(!dma_in, -1); return dma_in->dma_in_suc_eof_des_addr; } @@ -1437,6 +1439,7 @@ static inline void spi_dma_ll_enable_out_auto_wrback(spi_dma_dev_t *dma_out, uin __attribute__((always_inline)) static inline uint32_t spi_dma_ll_get_out_eof_desc_addr(spi_dma_dev_t *dma_out, uint32_t channel) { + ESP_STATIC_ANALYZER_CHECK(!dma_out, -1); return dma_out->dma_out_eof_des_addr; } diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index ad0ca7151d..6791015b81 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -293,6 +293,9 @@ endif() foreach(target ${mbedtls_targets}) target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h") + if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10087 + target_compile_options(${target} PRIVATE "-fno-analyzer") + endif() endforeach() if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) diff --git a/components/newlib/scandir.c b/components/newlib/scandir.c index cf5d85e738..d4db252cbb 100644 --- a/components/newlib/scandir.c +++ b/components/newlib/scandir.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -71,8 +71,11 @@ out: } free(entries); } + + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // Ignore intended return of allocated *out_dirlist if (dir_ptr) { closedir(dir_ptr); } return ret; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } diff --git a/components/nvs_flash/CMakeLists.txt b/components/nvs_flash/CMakeLists.txt index 1d03a68a19..6e7c6544b4 100644 --- a/components/nvs_flash/CMakeLists.txt +++ b/components/nvs_flash/CMakeLists.txt @@ -41,3 +41,7 @@ else() target_sources(${COMPONENT_LIB} PRIVATE "src/nvs_encrypted_partition.cpp") target_link_libraries(${COMPONENT_LIB} PRIVATE idf::mbedtls) endif() + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10088 + target_compile_options(${COMPONENT_LIB} PUBLIC "-fno-analyzer") +endif() diff --git a/components/pthread/pthread.c b/components/pthread/pthread.c index 3fbda12195..c0a6f10db6 100644 --- a/components/pthread/pthread.c +++ b/components/pthread/pthread.c @@ -25,6 +25,7 @@ #include "pthread_internal.h" #include "esp_pthread.h" +#include "esp_compiler.h" #include "esp_log.h" const static char *TAG = "pthread"; @@ -165,7 +166,10 @@ esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) *p = *cfg; p->stack_alloc_caps = heap_caps; pthread_setspecific(s_pthread_cfg_key, p); + + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // ignore leak of 'p' return 0; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p) diff --git a/components/tcp_transport/transport.c b/components/tcp_transport/transport.c index 5ec2195125..de1924e4af 100644 --- a/components/tcp_transport/transport.c +++ b/components/tcp_transport/transport.c @@ -271,6 +271,9 @@ int esp_transport_get_errno(esp_transport_handle_t t) void capture_tcp_transport_error(esp_transport_handle_t t, enum esp_tcp_transport_err_t error) { esp_tls_last_error_t *err_handle = esp_transport_get_error_handle(t); + if (err_handle == NULL) { + return; + } switch (error) { case ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN: err_handle->last_error = ESP_ERR_ESP_TLS_TCP_CLOSED_FIN; diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index 7f0a4d78f3..a11f160fbc 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -61,6 +61,8 @@ static inline transport_esp_tls_t *ssl_get_context_data(esp_transport_handle_t t static int esp_tls_connect_async(esp_transport_handle_t t, const char *host, int port, int timeout_ms, bool is_plain_tcp) { transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); + if (ssl->conn_state == TRANS_SSL_INIT) { ssl->cfg.timeout_ms = timeout_ms; ssl->cfg.is_plain_tcp = is_plain_tcp; @@ -101,6 +103,7 @@ static inline int tcp_connect_async(esp_transport_handle_t t, const char *host, static int ssl_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms) { transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); ssl->cfg.timeout_ms = timeout_ms; @@ -139,6 +142,7 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int { transport_esp_tls_t *ssl = ssl_get_context_data(t); esp_tls_last_error_t *err_handle = esp_transport_get_error_handle(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); ssl->cfg.timeout_ms = timeout_ms; esp_err_t err = esp_tls_plain_tcp_connect(host, strlen(host), port, &ssl->cfg, err_handle, &ssl->sockfd); @@ -154,6 +158,7 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int static int base_poll_read(esp_transport_handle_t t, int timeout_ms) { transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); int ret = -1; int remain = 0; struct timeval timeout; @@ -185,6 +190,7 @@ static int base_poll_read(esp_transport_handle_t t, int timeout_ms) static int base_poll_write(esp_transport_handle_t t, int timeout_ms) { transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); int ret = -1; struct timeval timeout; fd_set writeset; @@ -211,6 +217,7 @@ static int ssl_write(esp_transport_handle_t t, const char *buffer, int len, int { int poll; transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); if ((poll = esp_transport_poll_write(t, timeout_ms)) <= 0) { ESP_LOGW(TAG, "Poll timeout or error, errno=%s, fd=%d, timeout_ms=%d", strerror(errno), ssl->sockfd, timeout_ms); @@ -233,6 +240,7 @@ static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int { int poll; transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); if ((poll = esp_transport_poll_write(t, timeout_ms)) <= 0) { ESP_LOGW(TAG, "Poll timeout or error, errno=%s, fd=%d, timeout_ms=%d", strerror(errno), ssl->sockfd, timeout_ms); @@ -249,6 +257,7 @@ static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int static int ssl_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms) { transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); int poll = esp_transport_poll_read(t, timeout_ms); if (poll == -1) { @@ -284,6 +293,7 @@ static int ssl_read(esp_transport_handle_t t, char *buffer, int len, int timeout static int tcp_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms) { transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); int poll = esp_transport_poll_read(t, timeout_ms); if (poll == -1) { @@ -316,6 +326,8 @@ static int base_close(esp_transport_handle_t t) { int ret = -1; transport_esp_tls_t *ssl = ssl_get_context_data(t); + ESP_STATIC_ANALYZER_CHECK(ssl == NULL, -1); + if (ssl && ssl->ssl_initialized) { ret = esp_tls_conn_destroy(ssl->tls); ssl->tls = NULL; diff --git a/components/tcp_transport/transport_ws.c b/components/tcp_transport/transport_ws.c index 529494ca09..f7434aa02f 100644 --- a/components/tcp_transport/transport_ws.c +++ b/components/tcp_transport/transport_ws.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,6 +104,8 @@ static esp_transport_handle_t ws_get_payload_transport_handle(esp_transport_hand static int esp_transport_read_internal(transport_ws_t *ws, char *buffer, int len, int timeout_ms) { + ESP_STATIC_ANALYZER_CHECK(buffer == NULL, 0); + // No buffered data to read from, directly attempt to read from the transport. if (ws->buffer_len == 0) { return esp_transport_read(ws->parent, buffer, len, timeout_ms); diff --git a/components/usb/CMakeLists.txt b/components/usb/CMakeLists.txt index ce87157e50..8eca16596f 100644 --- a/components/usb/CMakeLists.txt +++ b/components/usb/CMakeLists.txt @@ -34,3 +34,7 @@ idf_component_register(SRCS ${srcs} PRIV_INCLUDE_DIRS ${priv_includes} PRIV_REQUIRES ${priv_requires} ) + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO GCC-366 (segfault) + set_property(SOURCE usb_host.c PROPERTY COMPILE_FLAGS -fno-analyzer) +endif() diff --git a/components/wear_levelling/CMakeLists.txt b/components/wear_levelling/CMakeLists.txt index 2ca00a42b3..28e98bbb2f 100644 --- a/components/wear_levelling/CMakeLists.txt +++ b/components/wear_levelling/CMakeLists.txt @@ -9,3 +9,7 @@ idf_component_register(SRCS "Partition.cpp" PRIV_INCLUDE_DIRS private_include REQUIRES esp_partition PRIV_REQUIRES spi_flash) + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10089 + target_compile_options(${COMPONENT_LIB} PUBLIC -fno-analyzer) +endif() diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index ebbe874f2f..f0a67dbceb 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -231,6 +231,10 @@ idf_component_register(SRCS "${srcs}" "${esp_srcs}" "${tls_src}" "${roaming_src} PRIV_REQUIRES mbedtls esp_timer esp_wifi) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-strict-aliasing -Wno-write-strings -Werror) +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10090 + target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer") +endif() + target_compile_definitions(${COMPONENT_LIB} PRIVATE __ets__ ESP_SUPPLICANT diff --git a/docs/en/api-guides/code-quality/index.rst b/docs/en/api-guides/code-quality/index.rst new file mode 100644 index 0000000000..527e6b8915 --- /dev/null +++ b/docs/en/api-guides/code-quality/index.rst @@ -0,0 +1,14 @@ +Code Quality +============ + +:link_to_translation:`zh_CN:[中文]` + +Code quality refers to how well-written and maintainable a piece of software code is. It encompasses aspects like readability, efficiency, reliability, and adherence to coding standards. High-quality code is easier to understand, modify, and extend, leading to reduced development time and fewer bugs. + +Guides +------ + +.. toctree:: + :maxdepth: 2 + + static-analyzer diff --git a/docs/en/api-guides/code-quality/static-analyzer.rst b/docs/en/api-guides/code-quality/static-analyzer.rst new file mode 100644 index 0000000000..5bea438423 --- /dev/null +++ b/docs/en/api-guides/code-quality/static-analyzer.rst @@ -0,0 +1,31 @@ +Static Analyzer +=============== + +:link_to_translation:`zh_CN:[中文]` + +A static analyzer is a tool that checks source code for errors and vulnerabilities without running it. It helps developers find issues early, improving code quality. + +GNU Static Analyzer +------------------- + +The GNU Static Analyzer is distributed with GCC (refer to `GCC documentation `_). It can be enabled with :ref:`CONFIG_COMPILER_STATIC_ANALYZER` to perform code checks during application builds. + +Suppressing Warnings +^^^^^^^^^^^^^^^^^^^^ + +GNU Static Analyzer is still under development and may give some false-positive warnings. Here is an example of how to suppress unwanted warnings using IDF: + +.. code-block:: c + + #include "esp_compiler.h" + /* .... */ + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-null-dereference") + *((volatile int *) 0) = 0; + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-null-dereference") + /* .... */ + + +Clang Static Analyzer +--------------------- + +See :doc:`IDF Clang-Tidy <../../api-guides/tools/idf-clang-tidy>` diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index e2d46e436c..ffc491c00d 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -14,6 +14,7 @@ API Guides :SOC_SUPPORT_COEXISTENCE: coexist c cplusplus + code-quality/index core_dump current-consumption-measurement-modules :SOC_RTC_MEM_SUPPORTED: deep-sleep-stub diff --git a/docs/zh_CN/api-guides/code-quality/index.rst b/docs/zh_CN/api-guides/code-quality/index.rst new file mode 100644 index 0000000000..ca7ea3741c --- /dev/null +++ b/docs/zh_CN/api-guides/code-quality/index.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-guides/code-quality/index.rst diff --git a/docs/zh_CN/api-guides/code-quality/static-analyzer.rst b/docs/zh_CN/api-guides/code-quality/static-analyzer.rst new file mode 100644 index 0000000000..74131eedf6 --- /dev/null +++ b/docs/zh_CN/api-guides/code-quality/static-analyzer.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-guides/code-quality/static-analyzer.rst diff --git a/docs/zh_CN/api-guides/index.rst b/docs/zh_CN/api-guides/index.rst index 4286f98823..74f41e5ae6 100644 --- a/docs/zh_CN/api-guides/index.rst +++ b/docs/zh_CN/api-guides/index.rst @@ -14,6 +14,7 @@ API 指南 :SOC_SUPPORT_COEXISTENCE: coexist c cplusplus + code-quality/index core_dump current-consumption-measurement-modules :SOC_RTC_MEM_SUPPORTED: deep-sleep-stub diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 9016a55af8..287137abcb 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -407,7 +407,6 @@ components/esp_hid/include/esp_hidh_bluedroid.h components/esp_hid/include/esp_hidh_gattc.h components/esp_hid/private/bt_hidd.h components/esp_hid/private/bt_hidh.h -components/esp_local_ctrl/src/esp_local_ctrl_handler.c components/esp_local_ctrl/src/esp_local_ctrl_priv.h components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c components/esp_phy/test/test_phy_rtc.c