diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index 4b60714f3b43e3..e3032092d7e3da 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -486,6 +486,7 @@ function(add_integration_test test_name) ${LIBC_BUILD_DIR} ${LIBC_BUILD_DIR}/include ) + target_compile_options(${fq_target_name} PRIVATE -ffreestanding) # We set a number of link options to prevent picking up system libc binaries. # Also, we restrict the integration tests to fully static executables. The # rtlib is set to compiler-rt to make the compiler drivers pick up the compiler diff --git a/libc/test/integration/loader/linux/args_test.cpp b/libc/test/integration/loader/linux/args_test.cpp index 24d19cbf420a83..6b99521ba1e86e 100644 --- a/libc/test/integration/loader/linux/args_test.cpp +++ b/libc/test/integration/loader/linux/args_test.cpp @@ -17,7 +17,7 @@ static bool my_streq(const char *lhs, const char *rhs) { return *l == '\0' && *r == '\0'; } -int main(int argc, char **argv, char **envp) { +TEST_MAIN(int argc, char **argv, char **envp) { ASSERT_TRUE(argc == 4); ASSERT_TRUE(my_streq(argv[1], "1")); ASSERT_TRUE(my_streq(argv[2], "2")); diff --git a/libc/test/integration/loader/linux/main_without_args.cpp b/libc/test/integration/loader/linux/main_without_args.cpp index c2f28bf25f422c..8c70c3d7f46eaa 100644 --- a/libc/test/integration/loader/linux/main_without_args.cpp +++ b/libc/test/integration/loader/linux/main_without_args.cpp @@ -6,4 +6,6 @@ // //===----------------------------------------------------------------------===// -int main() { return 0; } +#include "utils/IntegrationTest/test.h" + +TEST_MAIN() { return 0; } diff --git a/libc/test/integration/loader/linux/main_without_envp.cpp b/libc/test/integration/loader/linux/main_without_envp.cpp index 70d78c0d921d1c..4127990fdc0123 100644 --- a/libc/test/integration/loader/linux/main_without_envp.cpp +++ b/libc/test/integration/loader/linux/main_without_envp.cpp @@ -6,4 +6,6 @@ // //===----------------------------------------------------------------------===// -int main(int argc, char **argv) { return 0; } +#include "utils/IntegrationTest/test.h" + +TEST_MAIN(int argc, char **argv) { return 0; } diff --git a/libc/test/integration/loader/linux/tls_test.cpp b/libc/test/integration/loader/linux/tls_test.cpp index 8cd408f491dea0..82141ce1d46ba8 100644 --- a/libc/test/integration/loader/linux/tls_test.cpp +++ b/libc/test/integration/loader/linux/tls_test.cpp @@ -16,7 +16,7 @@ constexpr int threadLocalDataSize = 101; _Thread_local int a[threadLocalDataSize] = {123}; -int main(int argc, char **argv, char **envp) { +TEST_MAIN(int argc, char **argv, char **envp) { ASSERT_TRUE(a[0] == 123); for (int i = 1; i < threadLocalDataSize; ++i) diff --git a/libc/test/integration/src/__support/threads/thread_detach_test.cpp b/libc/test/integration/src/__support/threads/thread_detach_test.cpp index 8358998b4ef031..6257335a38d8dc 100644 --- a/libc/test/integration/src/__support/threads/thread_detach_test.cpp +++ b/libc/test/integration/src/__support/threads/thread_detach_test.cpp @@ -50,7 +50,7 @@ void detach_cleanup_test() { ASSERT_EQ(th.detach(), int(__llvm_libc::DetachType::CLEANUP)); } -int main() { +TEST_MAIN() { detach_simple_test(); detach_cleanup_test(); return 0; diff --git a/libc/test/integration/src/__support/threads/thread_tls_test.cpp b/libc/test/integration/src/__support/threads/thread_tls_test.cpp index 3fdd2ae15f9fc0..93f8d4df00cd75 100644 --- a/libc/test/integration/src/__support/threads/thread_tls_test.cpp +++ b/libc/test/integration/src/__support/threads/thread_tls_test.cpp @@ -35,7 +35,7 @@ void thread_local_test() { ASSERT_EQ(retval, INIT_VAL); } -int main() { +TEST_MAIN() { // From the main thread, we will update the main thread's tlval. // This should not affect the child thread's tlval; ASSERT_EQ(tlval, INIT_VAL); diff --git a/libc/test/integration/src/pthread/pthread_equal_test.cpp b/libc/test/integration/src/pthread/pthread_equal_test.cpp index 2f1ff6a8c87304..3e50e37846e105 100644 --- a/libc/test/integration/src/pthread/pthread_equal_test.cpp +++ b/libc/test/integration/src/pthread/pthread_equal_test.cpp @@ -31,7 +31,7 @@ static void *child_func(void *arg) { return nullptr; } -int main() { +TEST_MAIN() { // We init and lock the mutex so that we guarantee that the child thread is // waiting after startup. ASSERT_EQ(__llvm_libc::pthread_mutex_init(&mutex, nullptr), 0); diff --git a/libc/test/integration/src/pthread/pthread_mutex_test.cpp b/libc/test/integration/src/pthread/pthread_mutex_test.cpp index 823efe393eab45..d7c26c53c2fbee 100644 --- a/libc/test/integration/src/pthread/pthread_mutex_test.cpp +++ b/libc/test/integration/src/pthread/pthread_mutex_test.cpp @@ -185,7 +185,7 @@ void multiple_waiters() { __llvm_libc::pthread_mutex_destroy(&counter_lock); } -int main() { +TEST_MAIN() { relay_counter(); wait_and_step(); multiple_waiters(); diff --git a/libc/test/integration/src/pthread/pthread_test.cpp b/libc/test/integration/src/pthread/pthread_test.cpp index f5be1c67f35365..e9ac5ad7770609 100644 --- a/libc/test/integration/src/pthread/pthread_test.cpp +++ b/libc/test/integration/src/pthread/pthread_test.cpp @@ -55,7 +55,7 @@ void spawn_and_join() { } } -int main() { +TEST_MAIN() { create_and_join(); spawn_and_join(); return 0; diff --git a/libc/test/integration/src/stdlib/getenv_test.cpp b/libc/test/integration/src/stdlib/getenv_test.cpp index a4b3ff53572ec0..879d2f13cecf9a 100644 --- a/libc/test/integration/src/stdlib/getenv_test.cpp +++ b/libc/test/integration/src/stdlib/getenv_test.cpp @@ -27,7 +27,7 @@ static bool my_streq(const char *lhs, const char *rhs) { return *l == '\0' && *r == '\0'; } -int main(int argc, char **argv, char **envp) { +TEST_MAIN(int argc, char **argv, char **envp) { ASSERT_TRUE(my_streq(__llvm_libc::getenv(""), static_cast(nullptr))); ASSERT_TRUE(my_streq(__llvm_libc::getenv("="), static_cast(nullptr))); ASSERT_TRUE(my_streq(__llvm_libc::getenv("MISSING ENV VARIABLE"), diff --git a/libc/test/integration/src/threads/call_once_test.cpp b/libc/test/integration/src/threads/call_once_test.cpp index cf853372f3a933..1de8a621779a2b 100644 --- a/libc/test/integration/src/threads/call_once_test.cpp +++ b/libc/test/integration/src/threads/call_once_test.cpp @@ -114,7 +114,7 @@ void test_synchronization() { __llvm_libc::mtx_destroy(&once_func_blocker); } -int main() { +TEST_MAIN() { call_from_5_threads(); test_synchronization(); return 0; diff --git a/libc/test/integration/src/threads/cnd_test.cpp b/libc/test/integration/src/threads/cnd_test.cpp index 605bc72dd40c34..3690a979fe759c 100644 --- a/libc/test/integration/src/threads/cnd_test.cpp +++ b/libc/test/integration/src/threads/cnd_test.cpp @@ -145,7 +145,7 @@ void single_waiter_test() { } // namespace single_waiter_test -int main() { +TEST_MAIN() { wait_notify_broadcast_test::wait_notify_broadcast_test(); single_waiter_test::single_waiter_test(); return 0; diff --git a/libc/test/integration/src/threads/mtx_test.cpp b/libc/test/integration/src/threads/mtx_test.cpp index 2d927cdf3d59d4..34e060a4a0d55c 100644 --- a/libc/test/integration/src/threads/mtx_test.cpp +++ b/libc/test/integration/src/threads/mtx_test.cpp @@ -192,7 +192,7 @@ void multiple_waiters() { __llvm_libc::mtx_destroy(&counter_lock); } -int main() { +TEST_MAIN() { relay_counter(); wait_and_step(); multiple_waiters(); diff --git a/libc/test/integration/src/threads/thrd_equal_test.cpp b/libc/test/integration/src/threads/thrd_equal_test.cpp index 4058d0d1418158..e743836fd78771 100644 --- a/libc/test/integration/src/threads/thrd_equal_test.cpp +++ b/libc/test/integration/src/threads/thrd_equal_test.cpp @@ -31,7 +31,7 @@ static int child_func(void *arg) { return 0; } -int main() { +TEST_MAIN() { // We init and lock the mutex so that we guarantee that the child thread is // waiting after startup. ASSERT_EQ(__llvm_libc::mtx_init(&mutex, mtx_plain), int(thrd_success)); diff --git a/libc/test/integration/src/threads/thrd_test.cpp b/libc/test/integration/src/threads/thrd_test.cpp index 69df0302788945..63ddb1798a6a5c 100644 --- a/libc/test/integration/src/threads/thrd_test.cpp +++ b/libc/test/integration/src/threads/thrd_test.cpp @@ -53,7 +53,8 @@ void spawn_and_join() { } } -int main() { +TEST_MAIN() { create_and_join(); spawn_and_join(); + return 0; } diff --git a/libc/utils/IntegrationTest/test.h b/libc/utils/IntegrationTest/test.h index 556265052dfad5..8dff1980f9236e 100644 --- a/libc/utils/IntegrationTest/test.h +++ b/libc/utils/IntegrationTest/test.h @@ -58,4 +58,14 @@ #define ASSERT_NE(val1, val2) \ __CHECK_NE(__FILE__, __LINE__, (val1), (val2), true) +// Integration tests are compiled with -ffreestanding which stops treating +// the main function as a non-overloadable special function. Hence, we use a +// convenience macro which declares it 'extern "C"'. +// +// When we are able to reuse the unit test infrastructure for integration +// tests, then we should not need to explicitly declare/define the main +// function in individual integration tests. We will not need this macro +// then. +#define TEST_MAIN extern "C" int main + #endif // LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H