[libc-commits] [libc] [libc][test] Condition out tests that can't work on bare metal (PR #215830)

via libc-commits libc-commits at lists.llvm.org
Wed Aug 12 08:54:44 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Simon Tatham (statham-arm)

<details>
<summary>Changes</summary>

In bare-metal builds of libc, the `EXPECT_DEATH` macro may not be defined. Also, `signal-macros.h` may not define the values needed for the rest of `<signal.h>` to work. So tests that rely on either of those things will fail to compile.

I've conditioned out the `EXPECT_DEATH` tests completely if `EXPECT_DEATH` isn't defined. There's inherently no reliable way to define it: you can't rely on finding out about segmentation faults by a signal, because accessing memory outside valid C objects might silently succeed (valid unused memory), or generate a CPU fault that no kernel traps for you, or overwrite something important outside your program.

The check for signals in `FPExceptMatcher.cpp` can be more lenient, and just condition out the signal-handling code, leaving the test of cumulative FP exception flags in place, so that the checker simply returns "no signal was caught" unconditionally.

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


4 Files Affected:

- (modified) libc/test/UnitTest/FPExceptMatcher.cpp (+20-1) 
- (modified) libc/test/src/compiler/stack_chk_guard_test.cpp (+7) 
- (modified) libc/test/src/time/localtime_r_test.cpp (+2) 
- (modified) libc/test/src/time/localtime_test.cpp (+2) 


``````````diff
diff --git a/libc/test/UnitTest/FPExceptMatcher.cpp b/libc/test/UnitTest/FPExceptMatcher.cpp
index 10b6ff9f91da1..863811841124f 100644
--- a/libc/test/UnitTest/FPExceptMatcher.cpp
+++ b/libc/test/UnitTest/FPExceptMatcher.cpp
@@ -20,7 +20,15 @@
 #include "hdr/types/fenv_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include <setjmp.h>
+
+// To make this test work on bare-metal targets without working signal.h, find
+// out if signal-macros.h did anything, before including the full signal.h. It
+// doesn't define a specific macro of the form HAVE_SIGNALS, so we just test
+// for one of the macros it _does_ define.
+#include "llvm-libc-macros/signal-macros.h"
+#ifdef __NSIGSET_WORDS
 #include <signal.h>
+#endif
 
 #if LIBC_TEST_HAS_MATCHERS()
 
@@ -37,27 +45,38 @@ namespace testing {
 using sighandler_t = __sighandler_t *;
 #endif
 
-static thread_local sigjmp_buf jumpBuffer;
 static thread_local bool caughtExcept;
 
+#ifdef __NSIGSET_WORDS
+
+static thread_local sigjmp_buf jumpBuffer;
+
 static void sigfpeHandler([[maybe_unused]] int sig) {
   caughtExcept = true;
   siglongjmp(jumpBuffer, -1);
 }
 
+#endif // __NSIGSET_WORDS
+
 FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
+#ifdef __NSIGSET_WORDS
   auto *oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
+#endif
 
   caughtExcept = false;
   fenv_t oldEnv;
   fputil::get_env(&oldEnv);
+#ifdef __NSIGSET_WORDS
   if (sigsetjmp(jumpBuffer, 1) == 0)
+#endif
     func->call();
   delete func;
   // We restore the previous floating point environment after
   // the call to the function which can potentially raise SIGFPE.
   fputil::set_env(&oldEnv);
+#ifdef __NSIGSET_WORDS
   signal(SIGFPE, oldSIGFPEHandler);
+#endif
   exceptionRaised = caughtExcept;
 }
 
diff --git a/libc/test/src/compiler/stack_chk_guard_test.cpp b/libc/test/src/compiler/stack_chk_guard_test.cpp
index 301031ff47bd5..978e889263405 100644
--- a/libc/test/src/compiler/stack_chk_guard_test.cpp
+++ b/libc/test/src/compiler/stack_chk_guard_test.cpp
@@ -10,6 +10,13 @@
 #include "src/compiler/__stack_chk_fail.h"
 #include "test/UnitTest/Test.h"
 
+#ifdef EXPECT_DEATH
 TEST(LlvmLibcStackChkFail, Death) {
   EXPECT_DEATH([] { __stack_chk_fail(); }, WITH_SIGNAL(SIGABRT));
 }
+#else
+TEST(LlvmLibcStackChkFail, Dummy) {
+  // Need at least one test, because a completely empty test file
+  // counts as failure
+}
+#endif // EXPECT_DEATH
diff --git a/libc/test/src/time/localtime_r_test.cpp b/libc/test/src/time/localtime_r_test.cpp
index bc71419d68c64..e3c3b96278b89 100644
--- a/libc/test/src/time/localtime_r_test.cpp
+++ b/libc/test/src/time/localtime_r_test.cpp
@@ -27,6 +27,7 @@ TEST(LlvmLibcLocaltimeR, ValidUnixTimestamp0) {
   ASSERT_EQ(0, result->tm_isdst);
 }
 
+#ifdef EXPECT_DEATH
 TEST(LlvmLibcLocaltimeR, NullPtr) {
   struct tm input;
   time_t timer = 0;
@@ -37,6 +38,7 @@ TEST(LlvmLibcLocaltimeR, NullPtr) {
   EXPECT_DEATH([&] { LIBC_NAMESPACE::localtime_r(&timer, nullptr); },
                WITH_SIGNAL(-1));
 }
+#endif // EXPECT_DEATH
 
 // TODO(zimirza): These tests does not expect the correct output of localtime as
 // per specification. This is due to timezone functions removed from
diff --git a/libc/test/src/time/localtime_test.cpp b/libc/test/src/time/localtime_test.cpp
index 37974d27771dc..6e1116b98eeb1 100644
--- a/libc/test/src/time/localtime_test.cpp
+++ b/libc/test/src/time/localtime_test.cpp
@@ -25,9 +25,11 @@ TEST(LlvmLibcLocaltime, ValidUnixTimestamp0) {
   ASSERT_EQ(0, result->tm_isdst);
 }
 
+#ifdef EXPECT_DEATH
 TEST(LlvmLibcLocaltime, NullPtr) {
   EXPECT_DEATH([] { LIBC_NAMESPACE::localtime(nullptr); }, WITH_SIGNAL(-1));
 }
+#endif // EXPECT_DEATH
 
 // TODO(zimirza): These tests does not expect the correct output of localtime as
 // per specification. This is due to timezone functions removed from

``````````

</details>


https://github.com/llvm/llvm-project/pull/215830


More information about the libc-commits mailing list