diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2021-05-04 16:28:57 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2021-05-04 22:46:24 +0100 |
commit | 058d6acefe8bac4a66c8e7fb4951276db188e2d8 (patch) | |
tree | cefa327bd9c3bc7b792203a9e22289f97e980d3d /gcc | |
parent | 789c57bc5fe023fc6dc72ade4afcb0916ff788d3 (diff) | |
download | gcc-058d6acefe8bac4a66c8e7fb4951276db188e2d8.zip gcc-058d6acefe8bac4a66c8e7fb4951276db188e2d8.tar.gz gcc-058d6acefe8bac4a66c8e7fb4951276db188e2d8.tar.bz2 |
libstdc++: Fix null dereferences in std::promise
This fixes some ubsan errors in std::promise:
future:1153:34: runtime error: member call on null pointer of type 'struct element_type'
future:1153:34: runtime error: member access within null pointer of type 'struct element_type'
The problem is that the check for a null pointer is done inside the
_State::__Setter function, which is only evaluated after evaluating the
_M_future->_M_set_result postfix-expression.
This change adds a new promise::_M_state() helper for accessing
_M_future, and moves the check for no shared state into there, instead
of inside the __setter functions. The __setter functions are made
always_inline, to avoid the situation where the linker selects the old
version of set_value (without the _S_check call) and the new version of
__setter (without the _S_check call) and so there is no check. With the
always_inline attribute the old version of set_value will either inline
the old __setter or call an extern definition of it, and the new
set_value will do the check itself, so both versions do the check.
libstdc++-v3/ChangeLog:
* include/std/future (promise::set_value): Check for existence
of shared state before dereferncing it.
(promise::set_exception, promise::set_value_at_thread_exit)
(promise::set_exception_at_thread_exit): Likewise.
(promise<R&>::set_value, promise<R&>::set_exception)
(promise<R&>::set_value_at_thread_exit)
(promise<R&>::set_exception_at_thread_exit): Likewise.
(promise<void>::set_value, promise<void>::set_exception)
(promise<void>::set_value_at_thread_exit)
(promise<void>::set_exception_at_thread_exit): Likewise.
* testsuite/30_threads/promise/members/at_thread_exit2.cc:
Remove unused variable.
Diffstat (limited to 'gcc')
0 files changed, 0 insertions, 0 deletions