[lldb] Fix libstdc++ std::string formatter after #147835 (#152993) https://github.com/llvm/llvm-project/pull/147835 made changes that caused libstdc++ std::string tests to fail: ``` ====================================================================== FAIL: test_unavailable_summary_libstdcxx_dwo (TestDataFormatterStdString.StdStringDataFormatterTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1805, in test_method return attrvalue(self) File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py", line 223, in test_unavailable_summary_libstdcxx self.do_test_summary_unavailable() File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py", line 213, in do_test_summary_unavailable self.assertEqual(summary, "Summary Unavailable", "No summary for bad value") AssertionError: '(null)' != 'Summary Unavailable' - (null) + Summary Unavailable : No summary for bad value Config=aarch64-/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang ---------------------------------------------------------------------- ``` This test constructs an invalid std::string by starting with a null pointer. Somehow this improvement in Clang uncovered a bug in the formatter. Perhaps because we now know the type of the field we tried to access is char *, so fall back to a C string formatter that produces `(null)`. The formatter tries to access `_M_p` and checked whether the resulting ValueObjectSP was null, but not that it did not contain an error value. I think that error value can be there if you are able to access one part of the path, `_M_dataplus`, but another part fails. Since the layout looks like this: ``` struct _Alloc_hider : { pointer _M_p; // The actual data. }; _Alloc_hider _M_dataplus; void _M_data(pointer __p) { _M_dataplus._M_p = __p; } ``` So I think we were able to read `_M_dataplus` just by offset, but then failed because it contains, or points to something containing nulls or a null pointer. Or perhaps an error value means we know what the class member is, but could not read from it. I found this by comparing with the libcxx formatter, so I've copied the same handling from there to fix the issue.
Welcome to the LLVM project!
This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.
The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.
C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.
Other components include: the libc++ C++ standard library, the LLD linker, and more.
Consult the Getting Started with LLVM page for information on building and running LLVM.
For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.
Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.
The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.