Created attachment 1267634 [details] Test program Description of problem: calling set_value() on moved std::promise object results in SIGSEGV. Instead, exception should be thrown Version-Release number of selected component (if applicable): gcc version 6.2.1 20160916 (Red Hat 6.2.1-3) (GCC) How reproducible: Always Steps to Reproduce: <test program> [fmhirtz@surface2 transient] $ cat badMove.C #include <future> using namespace std; main() { promise<int> p1; promise<int> p2(move(p1)); p1.set_value(99); // SIGSEGV! } </program> 1. g++ -g -o badMovegcc6 badMove.C -lpthread 2. ./badMovegcc6 <boom> Actual results: [root@rhel6 ~]# gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-6/root/usr/libexec/gcc/x86_64-redhat-linux/6.2.1/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-6/root/usr --mandir=/opt/rh/devtoolset-6/root/usr/share/man --infodir=/opt/rh/devtoolset-6/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-6.2.1-20160916/obj-x86_64-redhat-linux/isl-install --enable-libmpx --with-mpc=/builddir/build/BUILD/gcc-6.2.1-20160916/obj-x86_64-redhat-linux/mpc-install --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 6.2.1 20160916 (Red Hat 6.2.1-3) (GCC) [root@rhel6 ~]# g++ -g -o badMovegcc6 badMove.C -lpthread [root@rhel6 ~]# ./badMovegcc6 Segmentation fault (core dumped) [root@rhel6 ~]# gdb --batch ./badMovegcc6 core.10711 -ex bt [New LWP 10711] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Core was generated by `./badMovegcc6'. Program terminated with signal SIGSEGV, Segmentation fault. #0 pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:45 45 testl $2, (%rdi) #0 pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:45 #1 0x0000000000402a54 in __gthread_once (__once=0x18, __func=0x402790 <__once_proxy@plt>) at /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/x86_64-redhat-linux/bits/gthr-default.h:699 #2 0x00000000004037f3 in std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (__once=..., __f=@0x7ffc2f035270: (void (std::__future_base::_State_baseV2::*)(std::__future_base::_State_baseV2 * const, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()> *, bool *)) 0x403308 <std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>, __args#0=@0x7ffc2f035268: 0x0, __args#1=@0x7ffc2f035260: 0x7ffc2f0352d0, __args#2=@0x7ffc2f035258: 0x7ffc2f035257) at /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/mutex:619 #3 0x00000000004030d2 in std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) (this=0x0, __res=..., __ignore_failure=false) at /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/future:393 #4 0x0000000000403cbd in std::promise<int>::set_value(int&&) (this=0x7ffc2f035330, __r=@0x7ffc2f03534c: 99) at /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/future:1081 #5 0x0000000000402b31 in main () at badMove.C:12 [root@rhel6 ~]# Expected results: Exception should be thrown rather than a segfault Additional info:
I don't think the standard is clear here. The Throws paragraph for promise::set_value doesn't say it throws if there's no shared state, and GCC's implementation treats it as undefined behaviour. By comparison, promise::get_future() explicitly says that you get an exception if there's no shared state (and we segfault there too, so that's definitely a bug). I'll seek clarification from the standard committee, and address this in upstream GCC first, before we change anything in DTS.
Related tests passed on all arches/distros with devtoolset-7-gcc-7.1.1-7.el{6,7}. VERIFIED.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHEA-2017:3016