From 1d5c16d7805806e920feee2b4ec93d5800293837 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 22 Jan 2024 14:55:51 -0800 Subject: [PATCH] [libc] default enable -ftrivial-auto-var-init=pattern (#78776) Usage of uninitialized memory is a top memory safety issue in C++ codebases. Help mitigate this somewhat by default initialize stack allocations to a pattern (0xAA repeating). Clang has received optimizations to sink these into control flow paths that access such values to minimize the overhead of these added initializations. If there's a measurable slowdown, we can add -ftrivial-auto-var-init-max-size= for some value N bytes if we have any large stack allocations, or add attribute uninitialized to any variable declarations. Unsupported until GCC 12.1 / Clang 8. Increases file size of libc.a from a full build by +8.79Ki (+0.2%). --- libc/cmake/modules/CheckCompilerFeatures.cmake | 5 +++++ libc/cmake/modules/LLVMLibCObjectRules.cmake | 3 +++ utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl | 7 ++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake index 1ad81bbb5f666ce..c99a98d1567d325 100644 --- a/libc/cmake/modules/CheckCompilerFeatures.cmake +++ b/libc/cmake/modules/CheckCompilerFeatures.cmake @@ -57,3 +57,8 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES) endforeach() message(STATUS "Compiler features available: ${AVAILABLE_COMPILER_FEATURES}") + +### Compiler Feature Detection ### + +# clang-8+, gcc-12+ +check_cxx_compiler_flag("-ftrivial-auto-var-init=pattern" LIBC_CC_SUPPORTS_PATTERN_INIT) diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake index 6eba17ae9201c83..b6c2f2d53e88d29 100644 --- a/libc/cmake/modules/LLVMLibCObjectRules.cmake +++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake @@ -41,6 +41,9 @@ function(_get_common_compile_options output_var flags) list(APPEND compile_options "-fno-unwind-tables") list(APPEND compile_options "-fno-asynchronous-unwind-tables") list(APPEND compile_options "-fno-rtti") + if (LIBC_CC_SUPPORTS_PATTERN_INIT) + list(APPEND compile_options "-ftrivial-auto-var-init=pattern") + endif() list(APPEND compile_options "-Wall") list(APPEND compile_options "-Wextra") # -DLIBC_WNO_ERROR=ON if you can't build cleanly with -Werror. diff --git a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl index cf27001be9dfed6..a28fa51a39f99de 100644 --- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl +++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl @@ -81,7 +81,12 @@ def libc_function( # We use the explicit equals pattern here because append and += mutate the # original list, where this creates a new list and stores it in deps. copts = copts or [] - copts = copts + ["-O3", "-fno-builtin", "-fno-lax-vector-conversions"] + copts = copts + [ + "-O3", + "-fno-builtin", + "-fno-lax-vector-conversions", + "-ftrivial-auto-var-init=pattern" + ] # We compile the code twice, the first target is suffixed with ".__internal__" and contains the # C++ functions in the "LIBC_NAMESPACE" namespace. This allows us to test the function in the