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

[libc++] Erroneous internal capacity evaluation causes SIGSEGV in vector<bool> #121726

Open
winner245 opened this issue Jan 6, 2025 · 0 comments · May be fixed by #120577
Open

[libc++] Erroneous internal capacity evaluation causes SIGSEGV in vector<bool> #121726

winner245 opened this issue Jan 6, 2025 · 0 comments · May be fixed by #120577
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Comments

@winner245
Copy link
Contributor

winner245 commented Jan 6, 2025

The internal capacity evaluation in vector<bool> is incorrect when evaluating __external_cap_to_internal(0), resulting in an erroneous return value: __external_cap_to_internal(0) = 288230376151711744 (0x400000000000000), while the correct result should be __external_cap_to_internal(0) = 0. Furthermore, this incorrect evaluation has propagated to other public APIs, causing a SIGSEGV error when compiling a program that calls flip() on vector<bool>, demonstrated as follows:

Godbolt Link

#include <vector>

int main() {
  std::vector<bool> v;
  v.flip();
}

The complication error:

Program returned: 139
Program stderr
Program terminated with signal: SIGSEGV

Root cause analysis

The incorrect evaluation occurs due to the following faulty implementation of __external_cap_to_internal:

__external_cap_to_internal(size_type __n) _NOEXCEPT {
return (__n - 1) / __bits_per_word + 1;
}

The issue arises because __n - 1 wraps around to become size_type(-1) = 18446744073709551615 (0xFFFFFFFFFFFFFFFF) when __n == 0. A correct implementation should avoid this wrap-around behavior for any __n >= 0.

Proposed solution

To avoid the wrap-around arithmetic, the return statement can be rewritten as:

return __n ? (__n - 1) / __bits_per_word + 1 : size_type(0);

or

return (__n + __bits_per_word - 1) / __bits_per_word;

This will automatically fix the SIGSEGV compilation error associated with flip().

@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants