llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.59k stars 11.34k forks source link

Regression in "cstdlib" file #98906

Closed mouse07410 closed 1 month ago

mouse07410 commented 1 month ago

I think this patch is explanatory:

diff -uw /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib
--- /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib.orig 2024-07-09 13:43:11
+++ /opt/local/libexec/gcc14/libc++/include/c++/v1/cstdlib  2024-07-10 09:41:58
@@ -142,7 +142,7 @@
 using ::mbstowcs _LIBCPP_USING_IF_EXISTS;
 using ::wcstombs _LIBCPP_USING_IF_EXISTS;
 #endif
-#if !defined(_LIBCPP_CXX03_LANG)
+#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
 using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
 using ::quick_exit _LIBCPP_USING_IF_EXISTS;
 #endif

Basically, check for _LIBCPP_HAS_QUICK_EXIT was lost, and that broke GCC -stdlib=libc++.

philnik777 commented 1 month ago

This macro has been removed years ago, since all somewhat modern platforms support quick_exit and we don't support partial implementations of the libc on gcc. What libc are you trying to use?

mouse07410 commented 1 month ago

Unfortunately, not all modern platforms support quick_exit. Specifically, GCC12, GCC13, and GCC14 apparently do not (or at least, not in the way your code expect).

GCC traditionally uses libstdc++ .

Starting with GCC12, GCC supports libc++ via -stdlib=libc++ flag, which allows C++ programs compiled with GCC, to link against Clang-compiled libraries.

GCC1{2,3,4} fails to compile without the && defined(_LIBCPP_HAS_QUICK_EXIT) present. See https://trac.macports.org/timeline?from=2024-07-08T20%3A35%3A00Z&precision=second, for example.

ldionne commented 1 month ago

@mouse07410 I don't fully understand the problem yet, but can you provide more details about the setup you're using? Is this GCC on mac?

GCC (on Linux at least) doesn't seem to have any issue with quick_exit: https://godbolt.org/z/frbP64Ehe

mouse07410 commented 1 month ago

can you provide more details about the setup you're using? Is this GCC on Mac?

I think all the details are in the issue https://trac.macports.org/ticket/70341 , but if you need more, or something specific - please let me know, and I'll post it here. And yes, this is on Mac, so affected by what Apple does with Xcode.

Frankly, I don't see a downside to restoring that check - even if it's unnecessary on some platforms (e.g., Linux), it's clearly needed on others (e.g., Mac). And it's not like I'm asking to maintain a ton of dead code. ;-)

Update

I checked your goldbot - GCC it's invoking doesn't even know the option -stdlib=libc++. And if goldbot GCC uses libstdc++, there's no problem (except, of course, when you need to link your object files with libraries compiled by system C++ compiler or Clang++).

mouse07410 commented 1 month ago

Some more experiments (macOS Sonoma 14.5, Xcode-15.4:

$ cat t8.cpp
#include <vector>
#include <cstdlib>

using zz = decltype(std::quick_exit);
$ clang++ -o /dev/null -c t8.cpp
t8.cpp:4:12: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
using zz = decltype(std::quick_exit);
           ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/__config:625:27: note: expanded from macro 'decltype'
#    define decltype(...) __decltype(__VA_ARGS__)
                          ^
t8.cpp:4:26: error: no member named 'quick_exit' in namespace 'std'
using zz = decltype(std::quick_exit);
                    ~~~~~^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/__config:625:38: note: expanded from macro 'decltype'
#    define decltype(...) __decltype(__VA_ARGS__)
                                     ^~~~~~~~~~~
1 warning and 1 error generated.
$ clang++ -v
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: x86_64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ g++ -o /dev/null -c t8.cpp
t8.cpp:4:26: error: 'quick_exit' is not a member of 'std'
    4 | using zz = decltype(std::quick_exit);
      |                          ^~~~~~~~~~
t8.cpp:4:26: error: 'quick_exit' is not a member of 'std'
$ g++ -std=c++20 -o /dev/null -c t8.cpp 
t8.cpp:4:26: error: 'quick_exit' is not a member of 'std'
    4 | using zz = decltype(std::quick_exit);
      |                          ^~~~~~~~~~
t8.cpp:4:26: error: 'quick_exit' is not a member of 'std'
$ g++ -std=c++20 -stdlib=libc++ -o /dev/null -c t8.cpp 
t8.cpp:4:26: error: 'quick_exit' is not a member of 'std'
    4 | using zz = decltype(std::quick_exit);
      |                          ^~~~~~~~~~
t8.cpp:4:26: error: 'quick_exit' is not a member of 'std'
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin23/14.1.0/lto-wrapper
Target: x86_64-apple-darwin23
Configured with: /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_gcc14/gcc14/work/gcc-14.1.0/configure --prefix=/opt/local --build=x86_64-apple-darwin23 --enable-languages=c,c++,objc,obj-c++,lto,fortran,jit --libdir=/opt/local/lib/gcc14 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-14 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-14 --with-gxx-include-dir=/opt/local/include/gcc14/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-isl=/opt/local --with-zstd=/opt/local --enable-checking=release --disable-multilib --enable-lto --enable-libstdcxx-time --with-build-config=bootstrap-debug --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld-classic --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --enable-host-shared --with-darwin-extra-rpath=/opt/local/lib/libgcc --with-libiconv-prefix=/opt/local --disable-tls --with-gxx-libcxx-include-dir=/opt/local/libexec/gcc14/libc++/include/c++/v1 --with-pkgversion='MacPorts gcc14 14.1.0_1+stdlib_flag' --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.1.0 (MacPorts gcc14 14.1.0_1+stdlib_flag) 
$ 
ldionne commented 1 month ago

Can you try with the SDK shipped in Xcode 16 beta 3? I see that quick_exit is provided by stdlib.h in that version.

Also, make sure you use the right version of GCC based on the version of libc++ you're using. If you're using LLVM 18, our documented and tested GCC was GCC 13, so things should work if you use GCC 13 but not other versions.

For tip-of-trunk, we now support GCC 14 (and only that), so that's the only version that will work reliably.

mouse07410 commented 1 month ago

Can you try with the SDK shipped in Xcode 16 beta 3? I see that quick_exit is provided by stdlib.h in that version.

I'm sorry, I cannot.

make sure you use the right version of GCC based on the version of libc++ you're using. If you're using LLVM 18, our documented and tested GCC was GCC 13, so things should work if you use GCC 13 but not other versions.

Oh yes. LLVM-18 for GCC 13 and 14.

And no, it did not work with GCC 13 and LLVM 18 without the patch I'm asking to merge (restore). (Nor did it work with GCC 14 and LLVM 18.)

ldionne commented 1 month ago

And no, it did not work with GCC 13 and LLVM 18 without the patch I'm asking to merge (restore). (Nor did it work with GCC 14 and LLVM 18.)

Right. I am 90% certain it would work with GCC 13 / LLVM 18 and the Xcode 16 SDK -- that's why I am suggesting this.

As a general statement, I'll say that libc++ with GCC only works on platforms with a fully conforming C Standard Library because supporting not-fully-complete C libraries requires the using_if_exists attribute, which GCC doesn't implement. We're happy to support these platforms on Clang, though.

By the way, this is not a philosophical opinion -- it exists due to practical concerns. Indeed, while the patch you posted above may seem small (by the way it doesn't actually work because you never define _LIBCPP_HAS_QUICK_EXIT), in reality many platforms are subtly non-conforming, so we'd have to maintain a large number of these _LIBCPP_HAS_FOO macros. All of these enablement macros also depend on system versions, which is something that we must keep evolving to avoid code rot. Long story short, we don't want to get into that business and the using_if_exists attribute is a nice and simple solution to that, so we rely on it and plan to keep doing so. Even though it means that GCC unfortunately doesn't get first class citizen support on all platforms.

I'll close this since we don't plan on reintroducing the macro for the reasons stated above.

mouse07410 commented 1 month ago

the patch you posted above may seem small (by the way it doesn't actually work because you never define _LIBCPP_HAS_QUICK_EXIT),

I don't know why you say "it doesn't actually work", because it definitely works and resolves the compilation problem on my Macs (MacOS Sonoma, Xcode-15.4).

Are you trying to say that the new platforms stopped defining those _LIBCPP_HAS_FOO?!

philnik777 commented 1 month ago

the patch you posted above may seem small (by the way it doesn't actually work because you never define _LIBCPP_HAS_QUICK_EXIT),

I don't know why you say "it doesn't actually work", because it definitely works and resolves the compilation problem on my Macs (MacOS Sonoma, Xcode-15.4).

Are you trying to say that the new platforms stopped defining those _LIBCPP_HAS_FOO?!

Platforms have never defined these macros. They were maintained by libc++.

mouse07410 commented 1 month ago

Platforms have never defined these macros. They were maintained by libc++.

OK, thanks - I stand corrected. But my question stands: does libc++ still define these macros, or did it stop...?

philnik777 commented 1 month ago

Platforms have never defined these macros. They were maintained by libc++.

OK, thanks - I stand corrected. But my question stands: does libc++ still define these macros, or did it stop...?

No, we don't define these macros anymore.

mouse07410 commented 1 month ago

I am 90% certain it would work with GCC 13 / LLVM 18 and the Xcode 16 SDK

Could you please help me understand the relationship between LLVM (say, LLVM-18) and Xcode - I am assuming that LLVM uses its own libc++ header files, and only links to Xcode libraries as needed?

If that's the case - then how could upgrade of Xcode from, e.g., 15 to 16, help with LLVM libc++ header files? I'm not arguing - just trying to understand (so I could intelligently discuss this issue in the Macports ticket).

philnik777 commented 1 month ago

I am 90% certain it would work with GCC 13 / LLVM 18 and the Xcode 16 SDK

Could you please help me understand the relationship between LLVM (say, LLVM-18) and Xcode - I am assuming that LLVM uses its own libc++ header files, and only links to Xcode libraries as needed?

If that's the case - then how could upgrade of Xcode from, e.g., 15 to 16, help with LLVM libc++ header files? I'm not arguing - just trying to understand (so I could intelligently discuss this issue in the Macports ticket).

The libc++ headers include some of the SDK headers. When updating XCode you get new (more recent) SDK headers, which should (apparently) now include declarations for quick_exit and friends.

Louis: Minor edit for clarity.