llvm / llvm/llvm-project

`__end` Not Correctly Written in `vector::emplace_back` (Suspected Compiler Codegen Bug)

Open
#186,583 1 comment 0 reactions 0 assignees View on GitHub
libc++
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

# Issue: `__end` Not Correctly Written in `vector::emplace_back` (Suspected Compiler Codegen Bug)

## Summary

In the slow path of `std::vector>::emplace_back`, the return value of `__emplace_back_slow_path` is not correctly written back to the local variable `__end`. As a result, `__end` remains `nullptr`, and `this->__end_` is assigned nullptr, corrupting the vector's internal state.

## Relevant Code (libc++ vector.h)

```cpp
// vector.h:1155-1167
vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
pointer __end = this->__end_;
std::__if_likely_else(
__end < this->__cap_,
[&] {
__emplace_back_assume_capacity(std::forward<_Args>(__args)...);
++__end;
},
[&] { __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); });

this->__end_ = __end; // ← __end is nullptr, corrupting the vector
return *(__end - 1);
}
```

## Debug Info

### 1. `__emplace_back_slow_path` Return Value Is Correct

- `$rax = 0x00007c1ff6e1aea0` (valid pointer)

### 2. `__end` Is Not Updated Correctly

- `(lldb) p __end` → `nullptr`
- Stack address of `__end`: `0x00007bffebd35b58`

### 3. Suspicious Assembly (After `__emplace_back_slow_path` Returns)

```asm
movq %rax, 0x30ac4e6(%rip) ; intended to write to __end
```

- Target address: `$rip + 0x30ac4e6` ≈ `0x55555af5bcb9`
- This address is clearly not on the stack, whereas `__end` should reside on the stack (`0x7bffebd35b58`)

### 4. Call Stack Snippet

```
frame #0: vector.h:1163 - after __emplace_back_slow_path returns
frame #2: vector.h:1157 - emplace_back entry, this->size=1
```

## Conclusion

The generated instruction `movq %rax, 0x30ac4e6(%rip)` uses an incorrect RIP-relative offset. The value that should be written to the stack location of `__end` is instead written to a wrong address. `__end` remains uninitialized/incorrect (manifesting as nullptr) and is then assigned to `this->__end_`, corrupting the vector.

## Environment
LLVM/Clang 22.1.1 with std module and many other module or third-party library.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.