From 5fc89ae7a2bcf083d1229e2acce9ec92a34d1062 Mon Sep 17 00:00:00 2001 From: Sam James Date: Tue, 2 Jan 2024 02:16:28 +0000 Subject: [PATCH] compilers: cpp: wire up stdlib assertions None of the options set here affect ABI and are intended for detecting constraint violations. For GCC, we simply need to set -D_GLIBCXX_ASSERTIONS. For Clang, the situation is far more complicated: * LLVM 18 uses a 'hardened mode' (https://libcxx.llvm.org/Hardening.html). There are several levels of severity available here. I've chosen _LIBCPP_HARDENING_MODE_EXTENSIVE as the strongest-but-one. The strongest one (_DEBUG) doesn't affect ABI still but is reserved for stldebug. * LLVM 15 uses a similar approach to libstdc++ called '_LIBCPP_ENABLE_ASSERTIONS' Note that LLVM 17 while in development had fully deprecated _LIBCPP_ENABLE_ASSERTIONS in favour of hardened, but changed its mind last-minute: https://discourse.llvm.org/t/rfc-hardening-in-libc/73925/4. Signed-off-by: Sam James --- docs/markdown/snippets/cpp-debug.md | 10 ++++++++++ mesonbuild/compilers/cpp.py | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 docs/markdown/snippets/cpp-debug.md diff --git a/docs/markdown/snippets/cpp-debug.md b/docs/markdown/snippets/cpp-debug.md new file mode 100644 index 000000000000..2a62b93994b4 --- /dev/null +++ b/docs/markdown/snippets/cpp-debug.md @@ -0,0 +1,10 @@ +## `ndebug` setting now controls C++ stdlib assertions + +The `ndebug` setting, if disabled, now passes preprocessor defines to enable +debugging assertions within the C++ standard library. + +For GCC, `-D_GLIBCXX_ASSERTIONS=1` is set. + +For Clang, `-D_GLIBCXX_ASSERTIONS=1` is set to cover libstdc++ usage, +and `-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE` or +`-D_LIBCPP_ENABLE_ASSERTIONS=1` is used depending on the Clang version. diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 226605390356..54e691f98b9f 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -293,6 +293,20 @@ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return libs return [] + def get_assert_args(self, disable: bool) -> T.List[str]: + args: T.List[str] = [] + if disable: + return args + + # Clang supports both libstdc++ and libc++ + args.append('-D_GLIBCXX_ASSERTIONS=1') + if version_compare(self.version, '>=18'): + args.append('-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE') + elif version_compare(self.version, '>=15'): + args.append('-D_LIBCPP_ENABLE_ASSERTIONS=1') + + return args + class ArmLtdClangCPPCompiler(ClangCPPCompiler): @@ -462,6 +476,14 @@ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return libs return [] + def get_assert_args(self, disable: bool) -> T.List[str]: + if disable: + return [] + + # XXX: This needs updating if/when GCC starts to support libc++. + # It currently only does so via an experimental configure arg. + return ['-D_GLIBCXX_ASSERTIONS=1'] + def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return ['-fpch-preprocess', '-include', os.path.basename(header)] @@ -625,6 +647,7 @@ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str] args.append('-fno-exceptions') if not options[key.evolve('rtti')].value: args.append('-fno-rtti') + if options[key.evolve('debugstl')].value: args.append('-D_GLIBCXX_DEBUG=1') return args