diff --git a/CMakeLists.txt b/CMakeLists.txt index 3eee64ec288..2758a1ff599 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,22 @@ if(compiler_supports_wunused_but_set_variable_eq_1) list(APPEND compile_options "-Wunused-but-set-variable=1") endif() +if(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_UNINITIALIZED) + set(compiler_cxx_trivial_auto_var_init "uninitialized") +elseif(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_PATTERN) + set(compiler_cxx_trivial_auto_var_init "pattern") +elseif(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_ZERO) + set(compiler_cxx_trivial_auto_var_init "zero") +endif() +if(compiler_cxx_trivial_auto_var_init) + idf_toolchain_remove_flags(CXX_COMPILE_OPTIONS "-ftrivial-auto-var-init") + check_cxx_compiler_flag("-ftrivial-auto-var-init=${compiler_cxx_trivial_auto_var_init}" + compiler_supports_ftrivial_auto_var_init) + if(compiler_supports_ftrivial_auto_var_init) + idf_toolchain_add_flags(CXX_COMPILE_OPTIONS "-ftrivial-auto-var-init=${compiler_cxx_trivial_auto_var_init}") + endif() +endif() + # Clang finds some warnings in IDF code which GCC doesn't. # All these warnings should be fixed before Clang is presented # as a toolchain choice for users. diff --git a/Kconfig b/Kconfig index 0ccdeb5cc6e..eceb0e90268 100644 --- a/Kconfig +++ b/Kconfig @@ -585,6 +585,41 @@ mainmenu "Espressif IoT Development Framework Configuration" This increases binary size (typically by tens of kB) but allows using dynamic_cast conversion and typeid operator. + choice COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT + prompt "C++ trivial automatic variable initialization" + default COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_UNINITIALIZED + depends on !IDF_TARGET_LINUX + help + Controls initialization of trivial automatic variables in C++ code + (-ftrivial-auto-var-init). The 'uninitialized' setting reduces overall + binary size compared to 'zero' or 'pattern'. + + config COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_UNINITIALIZED + bool "Uninitialized" + help + Does not initialize automatic variables. This matches the traditional C and + C++ behavior and yields the smallest code of the three modes. + + When compiling as C++26, compilers may zero-initialize automatic variables + and temporaries unless -ftrivial-auto-var-init is set explicitly. This + option passes -ftrivial-auto-var-init=uninitialized to preserve the + traditional behavior. Padding bits in objects are not initialized. + + config COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_PATTERN + bool "Pattern" + help + Initialize automatic variables with values which will likely transform logic + bugs into crashes down the line, are easily recognized in a crash dump and + without being values that programmers can rely on for useful program semantics. + The current value is byte-repeatable pattern with byte "0xFE". The values used + for pattern initialization might be changed in the future. + + config COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_ZERO + bool "Zero" + help + Initialize automatic variables with zeroes. + endchoice + choice COMPILER_STACK_CHECK_MODE prompt "Stack smashing protection mode" default COMPILER_STACK_CHECK_MODE_NONE diff --git a/tools/cmakev2/project.cmake b/tools/cmakev2/project.cmake index 7aa49957a79..f11718504c6 100644 --- a/tools/cmakev2/project.cmake +++ b/tools/cmakev2/project.cmake @@ -242,6 +242,22 @@ function(__init_project_configuration) list(APPEND compile_options "-Wunused-but-set-variable=1") endif() + if(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_UNINITIALIZED) + set(compiler_cxx_trivial_auto_var_init "uninitialized") + elseif(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_PATTERN) + set(compiler_cxx_trivial_auto_var_init "pattern") + elseif(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_ZERO) + set(compiler_cxx_trivial_auto_var_init "zero") + endif() + if(compiler_cxx_trivial_auto_var_init) + idf_toolchain_remove_flags(CXX_COMPILE_OPTIONS "-ftrivial-auto-var-init") + check_cxx_compiler_flag("-ftrivial-auto-var-init=${compiler_cxx_trivial_auto_var_init}" + compiler_supports_ftrivial_auto_var_init) + if(compiler_supports_ftrivial_auto_var_init) + idf_toolchain_add_flags(CXX_COMPILE_OPTIONS "-ftrivial-auto-var-init=${compiler_cxx_trivial_auto_var_init}") + endif() + endif() + # Clang finds some warnings in IDF code which GCC doesn't. # All these warnings should be fixed before Clang is presented # as a toolchain choice for users.