<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/70494>70494</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libc++] `std::expected`: operations may overwrite bytes of unrelated objects
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jiixyj
</td>
</tr>
</table>
<pre>
Some operations, like `emplace()`, might overwrite bytes of unrelated objects (example from <https://github.com/llvm/llvm-project/pull/68733#issuecomment-1766984702>):
```c++
struct bool_with_padding {
alignas(8) bool b = false;
};
struct s : std::expected<bool_with_padding, bool> {
const bool please_dont_overwrite_me[6] = //
{true, true, true, true, true, true};
};
static_assert(sizeof(s) == sizeof(bool_with_padding));
int main() {
s s;
s.emplace();
assert(s.please_dont_overwrite_me[5]); // will abort
assert(s.please_dont_overwrite_me[4]);
assert(s.please_dont_overwrite_me[3]);
assert(s.please_dont_overwrite_me[2]);
assert(s.please_dont_overwrite_me[1]);
assert(s.please_dont_overwrite_me[0]);
}
```
This happens because currently, `std::__libcppdatasize<std::expected<bool_with_padding, bool>>::value == 2`: One byte because of `std::__libcppdatasize<bool_with_padding>::value == 1` and one additional byte for `expected`'s "has value flag.
However, the `emplace()` operation destructs/constructs another `bool_with_padding` in place -- and that will overwrite all `sizeof(bool_with_padding) == 8` bytes of the object, clobbering the six unrelated `bool`s that are stored in `expected`'s tail padding.
`std::expected` has to make sure that all of its tail padding (if it has some) cannot be touched by any destructor/constructor calls of the value/error.
There is a PR up that has a work in progress fix and some more discussion: <https://github.com/llvm/llvm-project/pull/69673>
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVl1v6zYM_TXMC9HAlhLbechD29xgbxu2vQeyTce6lS1Dkttmv36gnOajDe7arjCaRBbJwyPyUMp7ve-J1rB8gOVmpsbQWrf-qfXr4eestPVh_ZftCO1ATgVtew_iEY1-IoQsoW4wqiIQBYgVZAm_6_S-DWifyb04HQjLQyCPtsGxd2RUoBpt-ZOq4BFEQa-qGwxh42yHIB_bEAYP8h7EFsR2r0M7lvPKdiC2xjy_fdwNzrILENthNAbENityKUFI7f1Ile066sNdmmfZqljkiQD5gxHKe0g2kLz9z5LpqUA88BNXfXBjFbC01uxedGh3g6pr3e8R8uMORERl9L5XHkTBqcfdWCLIDTbKeAJ53Av55vz90r9HkPfoQ82g5D29DlQFqkE-fojMrPIiyB_XICrb-wkpDoaUp11t-7A7cb_rCJYPGSw3ERlOpJ7t-Q_yh-BG4hif-rzM50ZuKuhqp7wnF0AUXv9DtuEvTBLIDcM4Ld5IdBVP6cqn7gN2SvdTkV0T4NG_241-fl2U717z0Z3QzX_B2hKWm8n-SBu-aGNQldaFr_panHwdLT9nJr9nJr5nln7PLHlnxkVx3V2X_P_dao-tGgbqPZZUqdETVqNz1Adz4CKDLDk1xW5ndFkNQ62C4qoB-fjVhokP739WZqS3EhQMS97j7_2kTycotvkvAB-D3YyQQpag6mu0PSFvZO1UZorWWBfV8y0FFs6c5VC0yuPkpzFqP7-k7jf7Qs_kYiO2N9X3LNJY0yQzHsQ2qkT8gaq3oaUY_GMeWYK6x-gS7-4i-NCqMNX9Wc-VMZGjX3XxGwsFOz0NAIY9ST8nURlbluRYWfmF168XE-IIkONMIJQj9ME6qhnkDfKC0gaPCObvVP5j0WQJMtXBYqeeCP3o6BiHc21Qh2uPPKo0L0czbzviLCvV9zZgSRjsWLVUY3lA1R9O9Ft3yb91WCljTlzEgwaxJeesm1-3CTlC7VHhH3_iOEzYOLTCF-ue4kE5u3fkPTb6NR4Wo8LOOsJa-2r0Xtuei_z_TNVVlkuQP2b1WtYruVIzWqc8UqVMZTFr102Zi0W2qktJdU5imWZ52qQ5VUWxqhcrmum1SIRME5GnxbJYFnNVNmW5KIQklVaUVrBIqFPazBnB3Lr9LI7wdZ4sVouZUSUZHy8nQnAvHie1YJGbuXWEXY57D4vEaB_82U3QwcRrzYUZD8Lb5cBEne842KnDp64ws9GZ9ZfZjRlya8Yk_w0AAP__2cr93A">