Skip to content

[libc] Fix warning on 'extern "C" int main' in test suite #102973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2024

Conversation

jhuber6
Copy link
Contributor

@jhuber6 jhuber6 commented Aug 12, 2024

Summary:
According to the C++ standard, The main function shall not be declared
with a linkage-specification. after some changes in
#101853 this started emitting
warnings when building / testing the C library. This source file is
shared with the overlay tests as well as the full build tests. The full
build tests are compiled with -ffreestanding, as are all the startup /
integration files. The standard says freestanding environment are all
implementation defined, so this is valid in those cases. This patch
simply prevents adding the linkage when we are compiling unit tests,
which are hosted. This is a continuation on
#102825.

@llvmbot
Copy link
Member

llvmbot commented Aug 12, 2024

@llvm/pr-subscribers-libc

Author: Joseph Huber (jhuber6)

Changes

Summary:
According to the C++ standard, The main function shall not be declared
with a linkage-specification. after some changes in
#101853 this started emitting
warnings when building / testing the C library. This source file is
shared with the overlay tests as well as the full build tests. The full
build tests are compiled with -ffreestanding, as are all the startup /
integration files. The standard says freestanding environment are all
implementation defined, so this is valid in those cases. This patch
simply prevents adding the linkage when we are compiling unit tests,
which are hosted. This is a continuation on
#102825.


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

2 Files Affected:

  • (modified) libc/test/UnitTest/CMakeLists.txt (+1)
  • (modified) libc/test/UnitTest/LibcTestMain.cpp (+9-1)
diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index 6427b861580777..9e9fc8153769cf 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -32,6 +32,7 @@ function(add_unittest_framework_library name)
   _get_hermetic_test_compile_options(compile_options -nostdinc++)
   target_include_directories(${name}.hermetic PRIVATE ${LIBC_BUILD_DIR}/include)
   target_compile_options(${name}.hermetic PRIVATE ${compile_options})
+  target_compile_definitions(${name}.hermetic PRIVATE LIBC_HERMETIC_TEST)
 
   if(TEST_LIB_DEPENDS)
     foreach(dep IN ITEMS ${TEST_LIB_DEPENDS})
diff --git a/libc/test/UnitTest/LibcTestMain.cpp b/libc/test/UnitTest/LibcTestMain.cpp
index 94536e97164686..ece5639769d215 100644
--- a/libc/test/UnitTest/LibcTestMain.cpp
+++ b/libc/test/UnitTest/LibcTestMain.cpp
@@ -43,7 +43,15 @@ TestOptions parseOptions(int argc, char **argv) {
 
 } // anonymous namespace
 
-extern "C" int main(int argc, char **argv, char **envp) {
+// The C++ standard forbids declaring the main function with a linkage specifier
+// outisde of 'freestanding' mode, only define the linkage for hermetic tests.
+#ifdef LIBC_HERMETIC_TEST
+#define TEST_MAIN extern "C" int main
+#else
+#define TEST_MAIN int main
+#endif
+
+TEST_MAIN(int argc, char **argv, char **envp) {
   LIBC_NAMESPACE::testing::argc = argc;
   LIBC_NAMESPACE::testing::argv = argv;
   LIBC_NAMESPACE::testing::envp = envp;

@SchrodingerZhu
Copy link
Contributor

I think clang should fix this instead of libc.

@jhuber6
Copy link
Contributor Author

jhuber6 commented Aug 12, 2024

I think clang should fix this instead of libc.

clang is doing its job, according to the standard extern "C" int main is not allowed. During -ffreestanding mode it is implementation defined and thus allowed, that's why it's not a warning in that case. This requires special handling because we compile LibCTestMain in both.

extern "C" int main(int argc, char **argv, char **envp) {
// The C++ standard forbids declaring the main function with a linkage specifier
// outisde of 'freestanding' mode, only define the linkage for hermetic tests.
#ifdef __STDC_HOSTED__
Copy link
Contributor

@lntue lntue Aug 12, 2024

Choose a reason for hiding this comment

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

Do you need to explicitly check if it's not 0? Look like it's always defined.

$ diff <(clang++ -dM -E - < /dev/null) <(clang++ -dM -E -ffreestanding - < /dev/null)
86d85
< #define __GCC_HAVE_DWARF2_CFI_ASM 1
243c242
< #define __STDC_HOSTED__ 1
---
> #define __STDC_HOSTED__ 0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, just noticed once I got undefined references in the GPU tests. Just checking the value is how the clang headers do it.

Summary:
According to the C++ standard, The main function shall not be declared
with a linkage-specification. after some changes in
llvm#101853 this started emitting
warnings when building / testing the C library. This source file is
shared with the overlay tests as well as the full build tests. The full
build tests are compiled with `-ffreestanding`, as are all the startup /
integration files. The standard says freestanding environment are all
implementation defined, so this is valid in those cases. This patch
simply prevents adding the linkage when we are compiling unit tests,
which are hosted. This is a continuation on
llvm#102825.
@jhuber6 jhuber6 merged commit 0889809 into llvm:main Aug 12, 2024
5 of 6 checks passed
@jhuber6 jhuber6 deleted the fix_main branch September 23, 2024 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants