llvm-project/libcxx
Louis Dionne 84b0b52b03 [libc++] Refactor how basic_string and vector hoist exception-throwing functions
In basic_string and vector, we've been encapsulating all exception
throwing code paths in helper functions of a base class, which are defined
in the compiled library. For example, __vector_base_common defines two
methods, __throw_length_error() and __throw_out_of_range(), and the class
is externally instantiated in the library. This was done a long time ago,
but after investigating, I believe the goal of the current design was to:

1. Encapsulate the code to throw an exception (which is non-trivial) in
   an externally-defined function so that the important code paths that
   call it (e.g. vector::at) are free from that code. Basically, the
   intent is for the "hot" code path to contain a single conditional jump
   (based on checking the error condition) to an externally-defined function,
   which handles all the exception-throwing business.

2. Avoid defining this exception-throwing function once per instantiation
   of the class template. In other words, we want a single copy of
   __throw_length_error even if we have vector<int>, vector<char>, etc.

3. Encapsulate the passing of the container-specific string (i.e. "vector"
   and "basic_string") to the underlying exception-throwing function
   so that object files don't contain those duplicated string literals.
   For example, we'd like to have a single "vector" string literal for
   passing to `std::__throw_length_error` in the library, instead of
   having one per translation unit.

However, the way this is achieved right now has two problems:

- Using a base class and exporting it is really weird - I've been confused
  about this ever since I first saw it. It's just a really unusual way of
  achieving the above goals. Also, it's made even worse by the fact that
  the definitions of __throw_length_error and __throw_out_of_range appear
  in the headers despite always being intended to be defined in the compiled
  library (via the extern template instantiation).

- We end up exporting those functions as weak symbols, which isn't great
  for load times. Instead, it would be better to export those as strong
  symbols from the library.

This patch fixes those issues while retaining ABI compatibility (e.g. we
still export the exact same symbols as before). Note that we need to
keep the base classes as-is to avoid breaking the ABI of someone who
might inherit from std::basic_string or std::vector.

Differential Revision: https://reviews.llvm.org/D111173
2021-10-05 20:53:40 -04:00
..
benchmarks [libc++][format] Implement Unicode support. 2021-10-02 11:57:40 +02:00
cmake Revert "[libc++][libc++abi] Add tests for vendor-specific properties" 2021-09-30 11:03:59 -07:00
docs libc++: document in the release notes that a C++20 compiler is expected 2021-10-04 19:03:05 +02:00
include [libc++] Refactor how basic_string and vector hoist exception-throwing functions 2021-10-05 20:53:40 -04:00
lib [libc++][NFC] Add missing commits to the ABI changelog 2021-07-20 09:19:52 -04:00
src [libc++] Refactor how basic_string and vector hoist exception-throwing functions 2021-10-05 20:53:40 -04:00
test [libc++] Pickle substitutions to pass them to dsl.sh.py 2021-10-05 19:51:23 -04:00
utils [runtimes] Allow FOO_TEST_CONFIG to be a relative path 2021-10-05 19:45:50 -04:00
.clang-format [NFC][libc++] Update clang-format style. 2021-09-24 19:28:07 +02:00
.gitignore [libcxx] Fix .gitignore to not exclude test directories 2020-03-25 17:52:23 -07:00
CMakeLists.txt [runtimes] Allow FOO_TEST_CONFIG to be a relative path 2021-10-05 19:45:50 -04:00
CREDITS.TXT [NFC] Add contributor name to CREDITS.TXT 2021-09-29 14:48:32 -04:00
LICENSE.TXT
TODO.TXT [libc++] Disallow volatile types in std::allocator 2021-09-22 11:47:38 -04:00
appveyor-reqs-install.cmd
appveyor.yml