https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106385
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- I was about to add the following to Bug 125236 (detect common misuses of the C++ lib) and realized we already have this one for std::optional. Here's what I was going to write in the other bug ... Accessing the value of a std::optional<T> or std::expected<T,E> without checking if it contains a value (an optional might be empty and an expected might contain an error instead of a value). void foo(int); std::optional<int> o; foo(*o); // UB foo(o.value()); // throws std::bad_optional_access if (o) foo(*o); // OK if (o.has_value()) foo(*o); // OK std::expected<int, std::error_code> e; foo(*e); // UB foo(e.value()); // throws std::bad_expected_access if (e) foo(*e); // OK if (e.has_value()) foo(*e); // OK The monadic operations (and_then, or_else, transform, transform_error) are all safe, they do the has_value() check internally. It might be worth flagging the .value() cases that throw. Technically, they have no UB because they check for a value, but it might still be a bug that the user didn't check (they might not be prepared to handle an exception there). The UB cases (*o and *e) would automatically by diagnosed by the analyzer if it used the __glibcxx_assert assertions inside those operator* functions, as suggested in Bug 106386.
