Skip to content
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

_LIBCPP_ENABLE_ASSERTIONS erroneously set with gcc-15 and libc++ #13978

Open
bryceberger opened this issue Dec 3, 2024 · 4 comments
Open

_LIBCPP_ENABLE_ASSERTIONS erroneously set with gcc-15 and libc++ #13978

bryceberger opened this issue Dec 3, 2024 · 4 comments
Assignees

Comments

@bryceberger
Copy link

bryceberger commented Dec 3, 2024

Describe the bug
When using gcc-15 (unreleased, but that's what the version number is if you build from head) and libc++ instead of libstdc++, the macro _LIBCPP_ENABLE_ASSERTIONS is set. Presumably this is due to get_assert_args():

def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]:
if disable:
return ['-DNDEBUG']
# Don't inject the macro if the compiler already has it pre-defined.
for macro in ['_GLIBCXX_ASSERTIONS', '_LIBCPP_HARDENING_MODE', '_LIBCPP_ENABLE_ASSERTIONS']:
if self.defines.get(macro) is not None:
return []
if self.language_stdlib_provider(env) == 'stdc++':
return ['-D_GLIBCXX_ASSERTIONS=1']
else:
if version_compare(self.version, '>=18'):
return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST']
elif version_compare(self.version, '>=15'):
return ['-D_LIBCPP_ENABLE_ASSERTIONS=1']
return []

  • self.language_stdlib_provider() is not "stdc++"
  • self.version is presumably the compiler version, and matches ">=15"

Since llvm/llvm-project#113592, this has been a hard error.

To Reproduce

project('repro', 'cpp')
executable('repro', 'main.cpp')
#include <memory>
int main() { std::make_unique<int>(3); }

Expected behavior
The stdlib assertion macro should be determined based on the stdlib version, not the compiler version. In this case, -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST should be set.

system parameters

  • native build, linux, gcc-15 + libc++-20
  • meson --version 1.6.0
  • ninja --version 1.13.0.git
@bryceberger
Copy link
Author

Note: this can be partially worked around by adding '-U_LIBCPP_ENABLE_ASSERTIONS" to the compiler flags.

@eli-schwartz
Copy link
Member

It's the wrong lines of code, you're referencing ClangCPPCompiler whereas gcc-15 will use GnuCPPCompiler. The bug is still there, though:

def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]:
if disable:
return ['-DNDEBUG']
# Don't inject the macro if the compiler already has it pre-defined.
for macro in ['_GLIBCXX_ASSERTIONS', '_LIBCPP_HARDENING_MODE', '_LIBCPP_ENABLE_ASSERTIONS']:
if self.defines.get(macro) is not None:
return []
if self.language_stdlib_provider(env) == 'stdc++':
return ['-D_GLIBCXX_ASSERTIONS=1']
else:
if version_compare(self.version, '>=18'):
return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST']
elif version_compare(self.version, '>=15'):
return ['-D_LIBCPP_ENABLE_ASSERTIONS=1']

In retrospect, having a copy of this code logic in the GnuCPPCompiler that checks for self.version being 18 / 15 was clearly wrong. ;) But the version in ClangCPPCompiler is probably correct since I would assume that LLVM will demand you use the same version of libc++ and the clang frontend?

@bryceberger
Copy link
Author

LLVM does not require using the same clang and libc++ version, and I don't know of an easy way to get the version of libstdc++ / libc++ other than the provided macros.

Is there a nice way to override the hardening flag? The simplest way seems to be just providing the correct flag as a define, but that doesn't (automatically) work with the debug / release profiles.

image

@thesamesam
Copy link
Collaborator

thesamesam commented Dec 4, 2024

Thanks, and indeed, ouch. I'll handle it.

The only way right now to override is to do that yourself by appending the flag or disabling NDEBUG.

With regard to mix/match: GCC doesn't support mixing newer GCC with older libstdc++ or vice-versa. I don't know about Clang with libc++. Clang, of course, has to support mixing various Clang versions with libstdc++.

But the version (check) doesn't even matter for GCC in its usual configuration (with libstdc++). It does matter with GCC in its unusual, experimental configuration with libc++.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants