[compiler-rt] [asan] Enable exceptions for asan_new_delete.cpp translation unit (PR #200719)

Justin T. Gibbs via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 10:53:27 PDT 2026


https://github.com/scsiguy updated https://github.com/llvm/llvm-project/pull/200719

>From 9be5d2e801d8d8934b160b35434f1ef0e8e6e1ef Mon Sep 17 00:00:00 2001
From: "Justin T. Gibbs" <gibbs at scsiguy.com>
Date: Sat, 30 May 2026 15:51:01 -0700
Subject: [PATCH] [asan] Enable exceptions for asan_new_delete.cpp translation
 unit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Preparation for a follow-up change that lets the throwing operator
new wrappers in asan_new_delete.cpp throw std::bad_alloc on OOM. To
support that, asan_new_delete.cpp must be compiled with -fexceptions
and must be able to include <new> (i.e. without -nostdinc++). The
rest of the ASan runtime stays compiled with -fno-exceptions and
-nostdinc++.

NOTE: Comments in CMakeLists.txt are written assuming the follow-on
      changes to use exceptions land, thus avoiding the need to update
      this file again.

Build-system changes:

  * Define ASAN_CXX_CFLAGS as ASAN_CFLAGS minus -fno-exceptions and
    -nostdinc++ plus -fexceptions. Define ASAN_DYNAMIC_CXX_CFLAGS
    likewise relative to ASAN_DYNAMIC_CFLAGS. RTTI stays disabled;
    libstdc++ / libc++abi supply the bad_alloc typeinfo.

  * Static build: switch RTAsan_cxx (which already contains only
    ${ASAN_CXX_SOURCES} = asan_new_delete.cpp) from ASAN_CFLAGS to
    ASAN_CXX_CFLAGS. RTAsan (the C slice) is unchanged.

  * Dynamic build: split the previous single RTAsan_dynamic object
    library into two — RTAsan_dynamic keeps ${ASAN_SOURCES} (no
    change in flags) and a new RTAsan_dynamic_cxx carries
    ${ASAN_CXX_SOURCES} with ASAN_DYNAMIC_CXX_CFLAGS. Both shared
    clang_rt.asan link rules pull in RTAsan_dynamic_cxx alongside
    RTAsan_dynamic so the linked .so retains the same set of object
    files; only the compile flags for asan_new_delete.cpp change.

NFC at runtime — the asan_new_delete.cpp source as of this commit
does not yet use exceptions or include <new>, so the new flags are
inert. The follow-up commit makes use of them.

Assisted by: Claude Opus 4.7
---
 compiler-rt/lib/asan/CMakeLists.txt | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt
index 6085f18426dff..3fa9e3f778b3d 100644
--- a/compiler-rt/lib/asan/CMakeLists.txt
+++ b/compiler-rt/lib/asan/CMakeLists.txt
@@ -143,6 +143,19 @@ set(ASAN_DYNAMIC_CFLAGS ${ASAN_CFLAGS})
 append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
   -ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS)
 
+# asan_new_delete.cpp throws std::bad_alloc, so the translation units that
+# build it need -fexceptions and access to <new> (drop -nostdinc++). Only
+# the C++ slices (RTAsan_cxx in the static build and RTAsan_dynamic_cxx in
+# the dynamic build) opt into these flags — the rest of the runtime keeps
+# -fno-exceptions / -nostdinc++.
+set(ASAN_CXX_CFLAGS ${ASAN_CFLAGS})
+list(REMOVE_ITEM ASAN_CXX_CFLAGS -fno-exceptions -nostdinc++)
+append_list_if(COMPILER_RT_HAS_FEXCEPTIONS_FLAG -fexceptions ASAN_CXX_CFLAGS)
+set(ASAN_DYNAMIC_CXX_CFLAGS ${ASAN_DYNAMIC_CFLAGS})
+list(REMOVE_ITEM ASAN_DYNAMIC_CXX_CFLAGS -fno-exceptions -nostdinc++)
+append_list_if(COMPILER_RT_HAS_FEXCEPTIONS_FLAG -fexceptions
+  ASAN_DYNAMIC_CXX_CFLAGS)
+
 # LLVM turns /OPT:ICF back on when LLVM_ENABLE_PDBs is set
 # we _REALLY_ need to turn it back off for ASAN, because the way
 # asan emulates weak functions from DLLs requires NOICF
@@ -165,11 +178,20 @@ append_list_if(MINGW "${MINGW_LIBRARIES}" ASAN_DYNAMIC_LIBS)
 add_compiler_rt_object_libraries(RTAsan_dynamic
   OS ${SANITIZER_COMMON_SUPPORTED_OS}
   ARCHS ${ASAN_SUPPORTED_ARCH}
-  SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
+  SOURCES ${ASAN_SOURCES}
   ADDITIONAL_HEADERS ${ASAN_HEADERS}
   CFLAGS ${ASAN_DYNAMIC_CFLAGS}
   DEFS ${ASAN_DYNAMIC_DEFINITIONS})
 
+# Separate object library for the dynamic build's C++ slice.
+add_compiler_rt_object_libraries(RTAsan_dynamic_cxx
+  OS ${SANITIZER_COMMON_SUPPORTED_OS}
+  ARCHS ${ASAN_SUPPORTED_ARCH}
+  SOURCES ${ASAN_CXX_SOURCES}
+  ADDITIONAL_HEADERS ${ASAN_HEADERS}
+  CFLAGS ${ASAN_DYNAMIC_CXX_CFLAGS}
+  DEFS ${ASAN_DYNAMIC_DEFINITIONS})
+
 if(NOT APPLE)
   add_compiler_rt_object_libraries(RTAsan
     ARCHS ${ASAN_SUPPORTED_ARCH}
@@ -181,7 +203,7 @@ if(NOT APPLE)
     ARCHS ${ASAN_SUPPORTED_ARCH}
     SOURCES ${ASAN_CXX_SOURCES}
     ADDITIONAL_HEADERS ${ASAN_HEADERS}
-    CFLAGS ${ASAN_CFLAGS}
+    CFLAGS ${ASAN_CXX_CFLAGS}
     DEFS ${ASAN_COMMON_DEFINITIONS})
   add_compiler_rt_object_libraries(RTAsan_static
     ARCHS ${ASAN_SUPPORTED_ARCH}
@@ -219,6 +241,7 @@ if(APPLE)
     OS ${SANITIZER_COMMON_SUPPORTED_OS}
     ARCHS ${ASAN_SUPPORTED_ARCH}
     OBJECT_LIBS RTAsan_dynamic
+                RTAsan_dynamic_cxx
                 RTInterception
                 RTSanitizerCommon
                 RTSanitizerCommonLibc
@@ -319,6 +342,7 @@ else()
       ARCHS ${arch}
       OBJECT_LIBS ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
               RTAsan_dynamic
+              RTAsan_dynamic_cxx
               # The only purpose of RTAsan_dynamic_version_script_dummy is to
               # carry a dependency of the shared runtime on the version script.
               # Replacing it with a straightforward



More information about the llvm-commits mailing list