diff --git a/components/bootloader_support/src/bootloader_panic.c b/components/bootloader_support/src/bootloader_panic.c index aac9e726386..47f48b2d461 100644 --- a/components/bootloader_support/src/bootloader_panic.c +++ b/components/bootloader_support/src/bootloader_panic.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,8 +17,7 @@ void __assert_func(const char *file, int line, const char *func, const char *exp esp_rom_printf("Assert failed in %s, %s:%d (%s)\r\n", func, file, line, expr); #endif - while (1) { - } + ESP_INFINITE_LOOP(); } void abort(void) @@ -31,6 +30,5 @@ void abort(void) esp_cpu_dbgr_break(); } #endif - while (1) { - } + ESP_INFINITE_LOOP(); } diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 0916ae9a3d5..fbfd8d86c85 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -9,6 +9,7 @@ #include #include "esp_attr.h" +#include "esp_macros.h" #include "esp_log.h" #include "esp_rom_sys.h" @@ -1162,7 +1163,7 @@ void bootloader_reset(void) bootloader_atexit(); esp_rom_delay_us(1000); /* Allow last byte to leave FIFO */ esp_rom_software_reset_system(); - while (1) { } /* This line will never be reached, used to keep gcc happy */ + ESP_INFINITE_LOOP(); /* This line will never be reached, used to keep gcc happy */ #else abort(); /* This function should really not be called from application code */ #endif diff --git a/components/esp_common/include/esp_macros.h b/components/esp_common/include/esp_macros.h index 0893878e7eb..5400bf4fc4a 100644 --- a/components/esp_common/include/esp_macros.h +++ b/components/esp_common/include/esp_macros.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ This header contains various general purpose helper macros used across ESP-IDF */ #include +#include "esp_attr.h" #include "esp_assert.h" #include "esp_compiler.h" @@ -80,12 +81,15 @@ extern "C" { #define ESP_UNUSED(x) ((void)(x)) #endif -#define ESP_INFINITE_LOOP() \ - do { \ - ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") \ - while(1); \ - ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-infinite-loop") \ - } while(1) +IRAM_ATTR +static inline __attribute__((always_inline, __noreturn__)) void esp_infinite_loop(void) +{ + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") + while (1) { + } + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-infinite-loop") +} +#define ESP_INFINITE_LOOP() esp_infinite_loop() #ifdef __cplusplus } diff --git a/components/esp_driver_dac/dac_continuous.c b/components/esp_driver_dac/dac_continuous.c index b3f8f9c25e0..f7d995b8c28 100644 --- a/components/esp_driver_dac/dac_continuous.c +++ b/components/esp_driver_dac/dac_continuous.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -418,7 +418,9 @@ esp_err_t dac_continuous_start_async_writing(dac_continuous_handle_t handle) } } /* Wait for the previous DMA stop */ + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (atomic_load(&handle->is_running)) {} + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-infinite-loop") /* Link all descriptors as a ring */ for (int i = 0; i < handle->cfg.desc_num; i++) { @@ -441,7 +443,10 @@ esp_err_t dac_continuous_stop_async_writing(dac_continuous_handle_t handle) STAILQ_NEXT(handle->desc[i], qe) = NULL; } /* Wait for the previous DMA stop */ + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (atomic_load(&handle->is_running)) {} + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-infinite-loop") + atomic_store(&handle->is_async, false); return ESP_OK; @@ -515,7 +520,10 @@ esp_err_t dac_continuous_write_cyclically(dac_continuous_handle_t handle, uint8_ } } /* Wait for the previous DMA stop */ + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (atomic_load(&handle->is_running)) {} + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-infinite-loop") + atomic_store(&handle->is_cyclic, true); size_t src_buf_size = buf_size; @@ -604,7 +612,10 @@ esp_err_t dac_continuous_write(dac_continuous_handle_t handle, uint8_t *buf, siz /* When there is no descriptor in the chain, DMA has stopped, load data and start the DMA link */ if (STAILQ_FIRST(&handle->head) == NULL) { /* Wait for the previous DMA stop */ + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (atomic_load(&handle->is_running)) {} + ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-infinite-loop") + for (int i = 0; i < handle->cfg.desc_num && buf_size > 0; i++, buf += w_size, buf_size -= w_size) { diff --git a/components/esp_driver_i2c/CMakeLists.txt b/components/esp_driver_i2c/CMakeLists.txt index 55df31758ee..6addeee859d 100644 --- a/components/esp_driver_i2c/CMakeLists.txt +++ b/components/esp_driver_i2c/CMakeLists.txt @@ -28,3 +28,5 @@ idf_component_register(SRCS ${srcs} PRIV_REQUIRES "${priv_requires}" LDFRAGMENTS "linker.lf" ) +set_source_files_properties("i2c_master.c" + PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable") diff --git a/components/esp_driver_touch_sens/CMakeLists.txt b/components/esp_driver_touch_sens/CMakeLists.txt index 502baa5af0f..4308bae0a9e 100644 --- a/components/esp_driver_touch_sens/CMakeLists.txt +++ b/components/esp_driver_touch_sens/CMakeLists.txt @@ -25,3 +25,9 @@ idf_component_register(SRCS ${srcs} REQUIRES esp_hal_touch_sens # public require because hal/touch_sens_type.h needs to be public INCLUDE_DIRS ${public_inc} ) + +# GCC -fanalyzer false positives on version-specific register writes (-Werror=analyzer-out-of-bounds). +if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED AND CONFIG_COMPILER_STATIC_ANALYZER AND CONFIG_IDF_TOOLCHAIN_GCC) + set_source_files_properties("${version_folder}/touch_version_specific.c" + PROPERTIES COMPILE_FLAGS "-Wno-analyzer-out-of-bounds") +endif() diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 728b91040d0..0a20075f431 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -231,3 +231,11 @@ endif() # Required in `adc_share_hw_ctrl.h` idf_component_optional_requires(PUBLIC esp_hal_ana_conv) + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CONFIG_IDF_TOOLCHAIN_GCC) + set_source_files_properties( + sleep_retention.c + PROPERTIES COMPILE_FLAGS + -Wno-analyzer-null-dereference + ) +endif() diff --git a/components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu.c index b78bc5d1c26..546101cfae1 100644 --- a/components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu.c @@ -489,9 +489,9 @@ static IRAM_ATTR void smp_core_do_retention(void) } // Wait another core start to do retention + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") bool smp_skip_retention = false; smp_retention_state_t another_core_state; - ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (1) { another_core_state = atomic_load(&s_smp_retention_state[!core_id]); if (another_core_state == SMP_SKIP_RETENTION) { diff --git a/components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu.c index b278b24f629..0104d6e55bd 100644 --- a/components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/port/esp32p4/sleep_cpu.c @@ -407,9 +407,9 @@ static SPM_IRAM_ATTR void smp_core_do_retention(void) } // Wait another core start to do retention + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") bool smp_skip_retention = false; smp_retention_state_t another_core_state; - ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (1) { another_core_state = atomic_load(&s_smp_retention_state[!core_id]); if (another_core_state == SMP_SKIP_RETENTION) { diff --git a/components/esp_hw_support/lowpower/port/esp32s31/sleep_cpu.c b/components/esp_hw_support/lowpower/port/esp32s31/sleep_cpu.c index 424239db2a2..138f6066a1f 100644 --- a/components/esp_hw_support/lowpower/port/esp32s31/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/port/esp32s31/sleep_cpu.c @@ -430,9 +430,9 @@ static IRAM_ATTR void smp_core_do_retention(void) } // Wait another core start to do retention + ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") bool smp_skip_retention = false; smp_retention_state_t another_core_state; - ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-infinite-loop") while (1) { another_core_state = atomic_load(&s_smp_retention_state[!core_id]); if (another_core_state == SMP_SKIP_RETENTION) { diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index 795856ff2fc..2ba87a4e842 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -53,3 +53,14 @@ idf_component_register(SRCS ${srcs} PRIV_REQUIRES ${priv_requires} REQUIRES ${public_requires} LDFRAGMENTS linker.lf) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + # GCC -fanalyzer false positives on early-return cleanup paths (see build logs with -Werror=analyzer-malloc-leak). + set_source_files_properties("src/esp_lcd_panel_ssd1306.c" + "src/esp_lcd_panel_st7789.c" + PROPERTIES COMPILE_FLAGS "-Wno-analyzer-malloc-leak") + if(CONFIG_SOC_I2C_SUPPORTED) + set_source_files_properties("i2c/esp_lcd_panel_io_i2c.c" + PROPERTIES COMPILE_FLAGS "-Wno-analyzer-malloc-leak") + endif() +endif() diff --git a/components/esp_system/task_wdt/task_wdt.c b/components/esp_system/task_wdt/task_wdt.c index 04d0d020649..f41eb0b1d44 100644 --- a/components/esp_system/task_wdt/task_wdt.c +++ b/components/esp_system/task_wdt/task_wdt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ #include "freertos/task.h" #include "freertos/freertos_debug.h" #include "esp_err.h" +#include "esp_macros.h" #include "esp_attr.h" #include "esp_check.h" #include "esp_log.h" @@ -420,11 +421,11 @@ static void task_wdt_timeout_handling(int cores_fail, bool panic) esp_crosscore_int_send_twdt_abort(other_core); /* We are going to abort, on the other core, we have nothing to * do anymore here, just wait until we crash */ - while (1) {} + ESP_INFINITE_LOOP(); } else if (cores_fail & BIT(other_core)) { /* If only the other core is failing, we can tell it to abort. */ esp_crosscore_int_send_twdt_abort(other_core); - while (1) {} + ESP_INFINITE_LOOP(); } #endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE /* Current core is failing, abort right now */ diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index b929bdb5e2b..310c1e5c45a 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -208,6 +208,14 @@ if(CONFIG_LWIP_ENABLE) -Wno-array-parameter ) + if(CONFIG_COMPILER_STATIC_ANALYZER AND CONFIG_IDF_TOOLCHAIN_GCC) + set_source_files_properties( + lwip/src/core/ipv4/ip4_addr.c + PROPERTIES COMPILE_FLAGS + -Wno-analyzer-use-of-uninitialized-value + ) + endif() + if(CONFIG_OPENTHREAD_ENABLED) idf_component_optional_requires(PRIVATE openthread) endif() diff --git a/components/pthread/pthread.c b/components/pthread/pthread.c index 69f0c440f0d..b7e57ee4d83 100644 --- a/components/pthread/pthread.c +++ b/components/pthread/pthread.c @@ -140,6 +140,7 @@ static void pthread_delete(esp_pthread_t *pthread) } /* Call this function to configure pthread stacks in Pthreads */ +ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // ignore leak of 'p' esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) { if (cfg == NULL) { @@ -167,7 +168,6 @@ esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) /* If a value is already set, update that value */ esp_pthread_cfg_t *p = pthread_getspecific(s_pthread_cfg_key); - ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // ignore leak of 'p' if (!p) { p = malloc(sizeof(esp_pthread_cfg_t)); if (!p) { @@ -179,8 +179,8 @@ esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) pthread_setspecific(s_pthread_cfg_key, p); return ESP_OK; - ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") } +ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p) { diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index e89cf707098..6c100325f50 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -390,3 +390,24 @@ if(CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_SOFTAP) target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_OWE_SOFTAP) endif() set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3) + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CONFIG_IDF_TOOLCHAIN_GCC) + set(eloop_analyzer_flags + -Wno-analyzer-out-of-bounds + -Wno-analyzer-null-dereference + -Wno-analyzer-use-of-uninitialized-value + -Wno-analyzer-free-of-non-heap + ) + list(JOIN eloop_analyzer_flags " " eloop_analyzer_flags) + + set_source_files_properties( + src/rsn_supp/wpa.c + PROPERTIES COMPILE_FLAGS + -Wno-analyzer-use-of-uninitialized-value + ) + set_source_files_properties( + port/eloop.c + PROPERTIES COMPILE_FLAGS + "${eloop_analyzer_flags}" + ) +endif()