[compiler-rt] [asan] Keep -nostdinc++ for asan_new_delete.cpp, add explicit libc++ … (PR #202816)

Justin T. Gibbs via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 18:55:34 PDT 2026


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

>From 33a23b030043f4b636018a0e1b8a10fff6652f13 Mon Sep 17 00:00:00 2001
From: "Justin T. Gibbs" <gibbs at scsiguy.com>
Date: Tue, 9 Jun 2026 14:50:44 -0700
Subject: [PATCH] [asan] Fix asan_new_delete.cpp C++ header resolution under
 -nostdinc++
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The COMPILER_RT_ASAN_ENABLE_EXCEPTIONS gate in asan/CMakeLists.txt
enables -fexceptions on the C++ slice (RTAsan_cxx /
RTAsan_dynamic_cxx — asan_new_delete.cpp) and tries to expose C++
standard headers to that TU (for forthcoming std::bad_alloc support)
by stripping -nostdinc++ from its cflags. The strip works for native
standalone builds but is wrong for cross builds: the host C++ headers
aren't valid for the target.

Split the C++-slice flag handling into two paths inside the existing
EXCEPTIONS gate:

  * In-tree libc++ available (TARGET cxx-headers OR HAVE_LIBCXX):
    keep -nostdinc++, append ${COMPILER_RT_CXX_CFLAGS} (a generator
    expression that expands to "-isystem <prepared cxx-headers dir>"),
    and add cxx-headers to DEPS so the header tree is staged before
    the compile. Mirrors the pattern in orc / fuzzer / memprof /
    tsan / xray.

  * No in-tree libc++ (typical standalone build): drop -nostdinc++
    for the C++ slice TU only so the host toolchain supplies C++ headers.

Reject COMPILER_RT_CXX_LIBRARY=none + COMPILER_RT_ASAN_ENABLE_EXCEPTIONS=ON
at configure time: that combination opts out of any C++ stdlib while
asking for an exception-enabled C++ slice, silently leaking host headers
into a `none`-mode build.

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

diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt
index 142b0e01a1d59..6d25cdc367742 100644
--- a/compiler-rt/lib/asan/CMakeLists.txt
+++ b/compiler-rt/lib/asan/CMakeLists.txt
@@ -157,18 +157,45 @@ endif()
 option(COMPILER_RT_ASAN_ENABLE_EXCEPTIONS
   "Enable exceptions in ASan C++ runtime" ${ASAN_ENABLE_EXCEPTIONS_DEFAULT})
 
-# 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++.
+# Flags for the C++ slice (asan_new_delete.cpp). When exceptions are enabled
+# it throws std::bad_alloc, so the TU needs -fexceptions and access to <new>.
+
+# COMPILER_RT_CXX_LIBRARY=none opts out of CXX library support. Reject its
+# combination with enabled exception handling at configure time rather than
+# silently leaking host C++ headers into the build.
+if(COMPILER_RT_ASAN_ENABLE_EXCEPTIONS AND
+   COMPILER_RT_CXX_LIBRARY STREQUAL "none")
+  message(FATAL_ERROR
+    "COMPILER_RT_ASAN_ENABLE_EXCEPTIONS=ON requires a C++ standard "
+    "library (for <new> and std::bad_alloc), but "
+    "COMPILER_RT_CXX_LIBRARY=none. Set "
+    "-DCOMPILER_RT_ASAN_ENABLE_EXCEPTIONS=OFF or pick a different "
+    "COMPILER_RT_CXX_LIBRARY.")
+endif()
+
+# Two paths for resolving <new>:
+#   * in-tree libc++ available (e.g. runtimes build, cross toolchain): keep
+#     -nostdinc++ so host headers stay out, route <new> through the prepared
+#     libc++ via COMPILER_RT_CXX_CFLAGS, and add cxx-headers to DEPS so the
+#     header tree is staged first.
+#   * Otherwise (standalone build using the host toolchain): drop
+#     -nostdinc++ for this TU only so the host C++ headers can supply <new>.
 set(ASAN_CXX_CFLAGS ${ASAN_CFLAGS})
 set(ASAN_DYNAMIC_CXX_CFLAGS ${ASAN_DYNAMIC_CFLAGS})
+set(ASAN_CXX_DEPS "")
 if(COMPILER_RT_ASAN_ENABLE_EXCEPTIONS AND COMPILER_RT_HAS_FEXCEPTIONS_FLAG)
-  list(REMOVE_ITEM ASAN_CXX_CFLAGS -fno-exceptions -nostdinc++)
+  list(REMOVE_ITEM ASAN_CXX_CFLAGS -fno-exceptions)
   list(APPEND ASAN_CXX_CFLAGS -fexceptions)
-  list(REMOVE_ITEM ASAN_DYNAMIC_CXX_CFLAGS -fno-exceptions -nostdinc++)
+  list(REMOVE_ITEM ASAN_DYNAMIC_CXX_CFLAGS -fno-exceptions)
   list(APPEND ASAN_DYNAMIC_CXX_CFLAGS -fexceptions)
+  if(TARGET cxx-headers OR HAVE_LIBCXX)
+    list(APPEND ASAN_CXX_CFLAGS ${COMPILER_RT_CXX_CFLAGS})
+    list(APPEND ASAN_DYNAMIC_CXX_CFLAGS ${COMPILER_RT_CXX_CFLAGS})
+    set(ASAN_CXX_DEPS cxx-headers)
+  else()
+    list(REMOVE_ITEM ASAN_CXX_CFLAGS -nostdinc++)
+    list(REMOVE_ITEM ASAN_DYNAMIC_CXX_CFLAGS -nostdinc++)
+  endif()
 endif()
 
 # LLVM turns /OPT:ICF back on when LLVM_ENABLE_PDBs is set
@@ -205,7 +232,8 @@ add_compiler_rt_object_libraries(RTAsan_dynamic_cxx
   SOURCES ${ASAN_CXX_SOURCES}
   ADDITIONAL_HEADERS ${ASAN_HEADERS}
   CFLAGS ${ASAN_DYNAMIC_CXX_CFLAGS}
-  DEFS ${ASAN_DYNAMIC_DEFINITIONS})
+  DEFS ${ASAN_DYNAMIC_DEFINITIONS}
+  DEPS ${ASAN_CXX_DEPS})
 
 if(NOT APPLE)
   add_compiler_rt_object_libraries(RTAsan
@@ -219,7 +247,8 @@ if(NOT APPLE)
     SOURCES ${ASAN_CXX_SOURCES}
     ADDITIONAL_HEADERS ${ASAN_HEADERS}
     CFLAGS ${ASAN_CXX_CFLAGS}
-    DEFS ${ASAN_COMMON_DEFINITIONS})
+    DEFS ${ASAN_COMMON_DEFINITIONS}
+    DEPS ${ASAN_CXX_DEPS})
   add_compiler_rt_object_libraries(RTAsan_static
     ARCHS ${ASAN_SUPPORTED_ARCH}
     SOURCES ${ASAN_STATIC_SOURCES}



More information about the llvm-commits mailing list