Skip to content

Conversation

@chestnykh
Copy link
Contributor

Fix #120003
The patch contains fixes to all the errors described in the issue attachement

@llvmbot llvmbot added cmake Build system in general and CMake in particular compiler-rt compiler-rt:scudo Scudo Hardened Allocator compiler-rt:sanitizer labels Dec 15, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 15, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Dmitry Chestnykh (chestnykh)

Changes

Fix #120003
The patch contains fixes to all the errors described in the issue attachement


Full diff: https://github.com/llvm/llvm-project/pull/120006.diff

5 Files Affected:

  • (modified) compiler-rt/cmake/config-ix.cmake (+2-1)
  • (modified) compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt (+2)
  • (modified) compiler-rt/test/CMakeLists.txt (+66-60)
  • (modified) llvm/CMakeLists.txt (+8-1)
  • (modified) llvm/cmake/modules/HandleLLVMOptions.cmake (+2-1)
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 6d52eecc9a91fe..25b0f6e2f3e2d5 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -931,7 +931,8 @@ endif()
 # calling malloc on first use.
 # TODO(hctim): Enable this on Android again. Looks like it's causing a SIGSEGV
 # for Scudo and GWP-ASan, further testing needed.
-if (GWP_ASAN_SUPPORTED_ARCH AND
+if (COMPILER_RT_HAS_SANITIZER_COMMON AND
+    GWP_ASAN_SUPPORTED_ARCH AND
     COMPILER_RT_BUILD_GWP_ASAN AND
     COMPILER_RT_BUILD_SANITIZERS AND
     "gwp_asan" IN_LIST COMPILER_RT_SANITIZERS_TO_BUILD AND
diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
index a85eb737dba0a8..d33fb051143757 100644
--- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
+++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
@@ -1,5 +1,7 @@
 include_directories(..)
 
+include(CompilerRTCompile)
+
 add_custom_target(ScudoUnitTests)
 set_target_properties(ScudoUnitTests PROPERTIES
   FOLDER "Compiler-RT Tests")
diff --git a/compiler-rt/test/CMakeLists.txt b/compiler-rt/test/CMakeLists.txt
index f9e23710d3e4f7..3f87e69964f91a 100644
--- a/compiler-rt/test/CMakeLists.txt
+++ b/compiler-rt/test/CMakeLists.txt
@@ -46,75 +46,81 @@ if(NOT ANDROID)
   endif()
 endif()
 
-umbrella_lit_testsuite_begin(check-compiler-rt)
-
-function(compiler_rt_test_runtime runtime)
-  string(TOUPPER ${runtime} runtime_uppercase)
-  if(COMPILER_RT_HAS_${runtime_uppercase} AND COMPILER_RT_INCLUDE_TESTS)
-    if (${runtime} STREQUAL cfi AND NOT COMPILER_RT_HAS_UBSAN)
-      # CFI tests require diagnostic mode, which is implemented in UBSan.
-    elseif (${runtime} STREQUAL scudo_standalone)
-      add_subdirectory(scudo/standalone)
-    else()
-      add_subdirectory(${runtime})
+# XXX: Maybe more precise conditions to enable/disable tests
+# But now the below code is broken at least with LLVM_USE_SANITIZER=Undefined
+if(NOT LLVM_USE_SANITIZER)
+
+  umbrella_lit_testsuite_begin(check-compiler-rt)
+
+  function(compiler_rt_test_runtime runtime)
+    string(TOUPPER ${runtime} runtime_uppercase)
+    if(COMPILER_RT_HAS_${runtime_uppercase} AND COMPILER_RT_INCLUDE_TESTS)
+      if (${runtime} STREQUAL cfi AND NOT COMPILER_RT_HAS_UBSAN)
+        # CFI tests require diagnostic mode, which is implemented in UBSan.
+      elseif (${runtime} STREQUAL scudo_standalone)
+        add_subdirectory(scudo/standalone)
+      else()
+        add_subdirectory(${runtime})
+      endif()
     endif()
-  endif()
-endfunction()
+  endfunction()
 
-# Run sanitizer tests only if we're sure that clang would produce
-# working binaries.
-if(COMPILER_RT_CAN_EXECUTE_TESTS)
-  if(COMPILER_RT_BUILD_BUILTINS)
-    add_subdirectory(builtins)
-  endif()
-  if(COMPILER_RT_BUILD_SANITIZERS)
-    compiler_rt_test_runtime(interception)
+  # Run sanitizer tests only if we're sure that clang would produce
+  # working binaries.
+  if(COMPILER_RT_CAN_EXECUTE_TESTS)
+    if(COMPILER_RT_BUILD_BUILTINS)
+      add_subdirectory(builtins)
+    endif()
+    if(COMPILER_RT_BUILD_SANITIZERS)
+      compiler_rt_test_runtime(interception)
 
-    compiler_rt_test_runtime(lsan)
-    compiler_rt_test_runtime(ubsan)
-    compiler_rt_test_runtime(sanitizer_common)
+      compiler_rt_test_runtime(lsan)
+      compiler_rt_test_runtime(ubsan)
+      compiler_rt_test_runtime(sanitizer_common)
 
-    # OpenBSD not supporting asan, cannot run the tests
-    if(COMPILER_RT_BUILD_LIBFUZZER AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD" AND NOT ANDROID)
-      compiler_rt_test_runtime(fuzzer)
+      # OpenBSD not supporting asan, cannot run the tests
+      if(COMPILER_RT_BUILD_LIBFUZZER AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD" AND NOT ANDROID)
+        compiler_rt_test_runtime(fuzzer)
 
-      # These tests don't need an additional runtime but use asan runtime.
-      add_subdirectory(metadata)
-    endif()
+        # These tests don't need an additional runtime but use asan runtime.
+        add_subdirectory(metadata)
+      endif()
 
-    foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD})
-      compiler_rt_test_runtime(${sanitizer})
-    endforeach()
-  endif()
-  if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE)
-    compiler_rt_test_runtime(profile)
-  endif()
-  if(COMPILER_RT_BUILD_CTX_PROFILE)
-    compiler_rt_test_runtime(ctx_profile)
-  endif()
-  if(COMPILER_RT_BUILD_MEMPROF)
-    compiler_rt_test_runtime(memprof)
-  endif()
-  if(COMPILER_RT_BUILD_XRAY)
-    compiler_rt_test_runtime(xray)
+      foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD})
+        compiler_rt_test_runtime(${sanitizer})
+      endforeach()
+    endif()
+    if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE)
+      compiler_rt_test_runtime(profile)
+    endif()
+    if(COMPILER_RT_BUILD_CTX_PROFILE)
+      compiler_rt_test_runtime(ctx_profile)
+    endif()
+    if(COMPILER_RT_BUILD_MEMPROF)
+      compiler_rt_test_runtime(memprof)
+    endif()
+    if(COMPILER_RT_BUILD_XRAY)
+      compiler_rt_test_runtime(xray)
+    endif()
+    if(COMPILER_RT_BUILD_ORC)
+      compiler_rt_Test_runtime(orc)
+    endif()
+    # ShadowCallStack does not yet provide a runtime with compiler-rt, the tests
+    # include their own minimal runtime
+    add_subdirectory(shadowcallstack)
   endif()
-  if(COMPILER_RT_BUILD_ORC)
-    compiler_rt_Test_runtime(orc)
+
+  # Now that we've traversed all the directories and know all the lit testsuites,
+  # introduce a rule to run to run all of them.
+  get_property(LLVM_COMPILER_RT_LIT_DEPENDS GLOBAL PROPERTY LLVM_COMPILER_RT_LIT_DEPENDS)
+  add_custom_target(compiler-rt-test-depends)
+  set_target_properties(compiler-rt-test-depends PROPERTIES FOLDER "Compiler-RT/Tests")
+  if(LLVM_COMPILER_RT_LIT_DEPENDS)
+    add_dependencies(compiler-rt-test-depends ${LLVM_COMPILER_RT_LIT_DEPENDS})
   endif()
-  # ShadowCallStack does not yet provide a runtime with compiler-rt, the tests
-  # include their own minimal runtime
-  add_subdirectory(shadowcallstack)
-endif()
+  umbrella_lit_testsuite_end(check-compiler-rt)
 
-# Now that we've traversed all the directories and know all the lit testsuites,
-# introduce a rule to run to run all of them.
-get_property(LLVM_COMPILER_RT_LIT_DEPENDS GLOBAL PROPERTY LLVM_COMPILER_RT_LIT_DEPENDS)
-add_custom_target(compiler-rt-test-depends)
-set_target_properties(compiler-rt-test-depends PROPERTIES FOLDER "Compiler-RT/Tests")
-if(LLVM_COMPILER_RT_LIT_DEPENDS)
-  add_dependencies(compiler-rt-test-depends ${LLVM_COMPILER_RT_LIT_DEPENDS})
-endif()
-umbrella_lit_testsuite_end(check-compiler-rt)
+endif(LLVM_USE_SANITIZER)
 
 if(COMPILER_RT_STANDALONE_BUILD)
   if(NOT TARGET check-all)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index f14065ab037990..f4bd6ceaa681d1 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -707,8 +707,15 @@ endif( LLVM_USE_PERF )
 set(LLVM_USE_SANITIZER "" CACHE STRING
   "Define the sanitizer used to build binaries and tests.")
 option(LLVM_OPTIMIZE_SANITIZED_BUILDS "Pass -O1 on debug sanitizer builds" ON)
+
+if( CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
+  set(LLVM_UBSAN_FLAGS_CLANG "-fno-sanitize=function")
+else()
+  # gcc doesn't know about -fsanitize=function
+  set(LLVM_UBSAN_FLAGS_CLANG)
+endif()
 set(LLVM_UBSAN_FLAGS
-    "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
+    "-fsanitize=undefined -fno-sanitize=vptr ${LLVM_UBSAN_FLAGS_CLANG} -fno-sanitize-recover=all"
     CACHE STRING
     "Compile flags set to enable UBSan. Only used if LLVM_USE_SANITIZER contains 'Undefined'.")
 set(LLVM_LIB_FUZZING_ENGINE "" CACHE PATH
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index f19125eb6bf273..76ace6a1a951e8 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -1064,7 +1064,8 @@ if(LLVM_USE_SANITIZER)
   if (LLVM_USE_SANITIZE_COVERAGE)
     append("-fsanitize=fuzzer-no-link" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
   endif()
-  if (LLVM_USE_SANITIZER MATCHES ".*Undefined.*")
+  if (LLVM_USE_SANITIZER MATCHES ".*Undefined.*" AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND
+		                                     CMAKE_CXX_COMPILER_ID MATCHES "Clang")
     set(IGNORELIST_FILE "${PROJECT_SOURCE_DIR}/utils/sanitizers/ubsan_ignorelist.txt")
     if (EXISTS "${IGNORELIST_FILE}")
       # Use this option name version since -fsanitize-ignorelist is only

@chestnykh chestnykh requested a review from MaskRay December 15, 2024 15:05
Fix llvm#120003
The patch contains fixes to all the errors described
in the issue attachement
@chestnykh
Copy link
Contributor Author

But gn asserts that host compiler is clang:

  if (use_ubsan) {
    assert(is_clang && (current_os == "ios" || current_os == "linux" ||
                            current_os == "mac"),
           "ubsan only supported on iOS/Clang, Linux/Clang, or macOS/Clang")
    cflags += [
      "-fsanitize=undefined",
      "-fno-sanitize=vptr,function",
      "-fno-sanitize-recover=all",
    ]
    ldflags += [ "-fsanitize=undefined" ]
  }

So probably this PR is not needed and only in the documentation it is necessary to clearly indicate that the compiler should be clang if LLVM_USE_SANITIZER is not empty

@chestnykh
Copy link
Contributor Author

chestnykh commented Dec 16, 2024

UPD:
With clang as host compiler lots of the described errors are also presented

So the patch is needed

endif()
if (LLVM_USE_SANITIZER MATCHES ".*Undefined.*")
if (LLVM_USE_SANITIZER MATCHES ".*Undefined.*" AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GCC supports -fsanitize=undefined: https://clang.godbolt.org/z/nT3bPW766

Maybe you have an old version that predates that support?

Copy link
Contributor Author

@chestnykh chestnykh Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't touch -fsanitize=undefined argument, it passes both to clang and gcc. Here i disable -fsanitize-blacklist=... passing to gcc which doesn't supported by it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh, I think it would help a lot to put that concept in a variable, e.g:

check_cxx_compiler_flag(-fsanitize-blacklist=${IGNORELIST_FILE} COMPILER_RT_CXX_SUPPORTS_FSANITIZE_BLACKLIST)

instead of tying this to the specific compiler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, i've done the same for -fno-sanitize=function flag in llvm/CMakeLists.txt

@chestnykh chestnykh requested a review from jroelofs December 17, 2024 06:47
# TODO(hctim): Enable this on Android again. Looks like it's causing a SIGSEGV
# for Scudo and GWP-ASan, further testing needed.
if (GWP_ASAN_SUPPORTED_ARCH AND
if (COMPILER_RT_HAS_SANITIZER_COMMON AND
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need COMPILER_RT_HAS_SANITIZER_COMMON for GWP_ASAN_SUPPORTED_ARCH?
It should not be a dependency.

if (LLVM_USE_SANITIZER MATCHES ".*Undefined.*")
set(IGNORELIST_FILE "${PROJECT_SOURCE_DIR}/utils/sanitizers/ubsan_ignorelist.txt")
if (EXISTS "${IGNORELIST_FILE}")
check_c_compiler_flag(-fsanitize-blacklist=${IGNORELIST_FILE} C_SUPPORTS_FSANITIZE_BLACKLIST_FLAG)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fsanitize-ignorelist

option(LLVM_OPTIMIZE_SANITIZED_BUILDS "Pass -O1 on debug sanitizer builds" ON)

check_c_compiler_flag(-fno-sanitize=function C_SUPPORTS_FNO_SANITIZE_FUNCTION_FLAG)
check_cxx_compiler_flag(-fno-sanitize=function CXX_SUPPORTS_FNO_SANITIZE_FUNCTION_FLAG)
Copy link
Collaborator

@vitalybuka vitalybuka Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes in llvm/ caused by unsupported flags, cause is different from compiler-rt changes.
Can you please extract them into a separate PR?
I agree with them and happy to approve.

@vitalybuka
Copy link
Collaborator

Please try with LLVM_ENABLE_RUNTIMES.
I suspect LLVM_USE_SANITIZER will not even reach compiler-rt

Copy link
Collaborator

@vitalybuka vitalybuka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to split

@Meinersbur Meinersbur removed their request for review January 21, 2025 16:08
@chestnykh chestnykh closed this Apr 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cmake Build system in general and CMake in particular compiler-rt:sanitizer compiler-rt:scudo Scudo Hardened Allocator compiler-rt

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LLVM build is completely broken if LLVM_USE_SANITIZER is set to "Undefined"

4 participants