<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/125426>125426</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Unsafe Implementation: std::future undefined behavior when the object is not valid
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          slotosch
      </td>
    </tr>
</table>

<pre>
    During the qualification for Safety +f the C++ STL at Validas we found this safety relevant issue
The C++ 14 Standard states in requirement 30.6.6-3:
The effect of calling any member function other than the destructor, the move-assignment operator, or valid on a future object for which valid() == false is undefined. [ Note: Implementations are encouraged to detect this case and throw an object of type future_error with an error condition of future_errc::no_- state. â€”end note ]
While this requirement is optional, or recommended (see "encouraged" wording), **not fulfilling it may affects the stability and _safety_ badly.**

So strictly speaking the "undefined behaviour" might not be a clear bug, but it is a clear safety issue as stated in the C++ standard.
We think it should be easy to fix and gcc implementation does not suffer this bug.

**Steps to reproduce:**

Create the future object which state is not valid. For example: default-constructed std::future object, or move the shared state from valid `future` object, or call `get` on the valid object, etc

Call function such as get, wait, wait_for etc

**Expected behavior:**

The function throws future_error exception.

**Actual behavior:**

LLVM based library : QNX, MacOS: Segmentation fault, core dump.

GNU/Linux stdlib:  works as expected

**Issue analysis:**

Implementation does not check if the current status is valid.

**Workaround:**

Check future::valid() before the call, or ensure the safe state by design.

**Note:** The following

if (fut.valid()) fut.wait()

may not guarantee the state of fut object in multitasking code if the future object is shared (for example, because of leaking the pointer or reference to another thread). Note that sharing std::future object is not recommended anyway (use shared_future instead). 

**Minimal reproducer**

#include <future>
#include <iostream>
int main() {
  std::future<void> f;
  try {
    f.get();
  } catch (std::future_error& e) {
    std::cout << "Exception handled: " << e.what() << std::endl;
    return 0;
  }
  return 1;
}

**or, a bit more advanced workflow:**

#include <future>
#include <iostream>
int main() {
  auto f = std::async(std::launch::async, [](){ return 42; });
  f.get(); // first time is OK
  try {
    f.get(); // second time fails
  } catch (std::future_error& e) {
    std::cout << "Exception handled: " << e.what() << std::endl;
    return 0;
  }
  return 1;
}
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzcV0tvI7kR_jX0pWChxbZs66CDH-NgkJlZBJ7dzc2oJqvVjNmklg_L-vdBkS255c0il5wCGBCaj3p89X1VNMZoto5oI1b3YvV4gTkNPmyi9clHNVx0Xh82jzkYt4U0EPyR0ZreKEzGO-h9gGfsKR1AyPu-nHgQ8l7Ie3j--Q0wwW9ojcYIe4LeZ6chDSZCrJcCWXpDl8DEmEk0dz9nBpZX8JzQaQwaYsJEEYyDQH9kE2gkl6BtFteL68tWtHfTXep7Ugl8Dwqt5aDRHWCksaMAfXaqhO3TQAHSgK5ErCmmkFXyQciHsjL6N7qs0BRHfkcBp30f4I1zAu8Aoc8pBwLf_Yv9Mh77waihHhHyVsg1iPZRtI_Qo40EJkJ2mnrjSC9ArO7hh08k2jv4Ou5syatgGwEDATnlc8AtaUgeNCX2UhBUGAmw4Bn8HtAdY_A9pMOOpsheKAQOyqSBz9Qv5Z02FYl-dk4xju2d8y-XFfAFiC9S3DZifUVOg_OJQKweRXP3-2As1UDmBTER_I4No52gCqT8OJLTpEHI20gEQsqPtISUsPdBG7cVcs2XhLwT8s75BH22valVNAlGPACW8sZSo5iwM9akQ0HhpTLqBTrU9rCoRkTDf88eYgpGJXuAuCN8PXJZSHkqBXQ04JvxOXBEo9kOifOFjgBBWcIAXd5yfF1OHI6Jp42JzIXDgLFip5mscz3EicsLhq9g517ZUBx8tuwfCOOBy9yb95LTVikwZ6QA7SmWuGLu-8JhEzmwRU21pv2caBfZUKBd8DorptcckYdAmKhEd87fyt0SPyfIjgqRF_DkA9A7cjTMVU09ZpsulXdVO8Qa1ZVAZzYnHrCiatkGDDQJGvrgx0lN4rqp98R1c36VlczbW0plr8I6afB0kJKakuPjJ6nHrAauCV-WD7BHc_p9YbWerlV8vrzvqCQz0SF8Qu5ngWyyXZQXz4VG74qKAs4qcqdSRvtXRr99--07dBhJgzVdwHAAxvgfP_7JoX5H9cszfz_T9oMIBX7eVj4Q6DzuJod_-_GrkE_fjMvvXBFrOr7LGnuNDARNGc7D-1qZ69Aeoomfovv6FwxUA6lXMLXpqxwCNwAua47MncqbuZfffXjFwDPgMx2Lpan6hUHz7tlRzykWL2iPfYVczNMqy2_iU3fgZm625-hPDbZ-QCmht9bvueeUY6bn3tTntJg5Zt-8VClTVsph7kOc_zZjQJeIjt0o0dROj2oyDsZsk0kYS89RXtMRsHPd8USsuuA4ZlLjfkMKcyy27ax57bxxiULtsT0FcopY8-iO0y0QaiHXizJgeNql4oQN_GepHiU_79noDnvk6X7LMdQgX6ZbxsV09DHH-7txZkT70X7CvNpCtsYpmzWBaB-OVf_ypx3jYwqEY90zjieAcceRenMvmjv4nIhoH9680aL9Ar1o65HEcpqOA_SL0glKOacD4uYRFCY1lAF1brCqWshroLnbmWPlc-JwRcujS3456h8GdNoSn-L14xFa7AdMp4dBWTvZIqftMSqAQCkHB80szvI7rS_rel09YV_fKAgdT0zWDeo3dIp06QC99ftP4vuflgMzjy9-8HwkhfHg1BxZi9mp4WzzAerzcyrMzf0xySsp2vuS-Ue9zksIQj4J-QS9CTFBMmOZXL_8_b_W_ngxEj-H6s0ejY3_H6S40JtWr9s1XtBmedPerpa3101zMWyaZXu9RnlFtLpp26u206t1v1yu16v1CvuVvjAb2chVIxu5vFk1TbO4am863a2XqJXUtCRx1dCIxi6sfRsXPmwvytNns5SrK3l9YbEjG8s_FFI62k-Peyn5_4uw4UuXXd5GcdVYE1P8MJNMsrT51ZWOfj53GLHPXetPjzd-fFN9Hpx3tNLWL3KwmyGlXZ1wXPytSUPuFsqPQj5xGNPP5S74-rB4KsFHIZ-m7N428t8BAAD__4kMOp0">