https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106385

            Bug ID: 106385
           Summary: Support for std::optional in -fanalyzer
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
            Blocks: 97110
  Target Milestone: ---

Check that std::optional::has_value() (or equivalent) is checked before
accessing the contained value of a std::optional.

See
https://devblogs.microsoft.com/cppblog/new-stdoptional-checks-in-visual-studio-2022-version-17-3-preview-3/

std::optional either contains a value, or is empty. Some accessors for the
value are safe and will throw if no value is present, some have a precondition
that a value is present and do not check. The analyzer could flag when the
unchecked accessor is used without a preceeding check for a value.

void f(std::optional<int> o)
{
  int i = 0;

  if (o.has_value())
    i = *o; // safe
  if (o) // conversion to bool, equivalent to has_value()
    i = *o; // safe

  i = o.value_or(1);  // safe

  if (rand() % 2)
    i = o.value(); // safe, throws if no value
  else
    i = *o; // unsafe!

  i = *o; // "safe" because we already accessed it once.
}


Similarly for std::expected, which is a union of two types with accessors for
the result value or error value, only one of which is present. Some accessors
are safe and will throw an exception, others are unchecked and have
preconditions.

We don't need to do this for std::variant, as there are no unchecked accessors
for it (std::get will throw if the alternative you ask for isn't active, and
std::visit handles any alternative being active).


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97110
[Bug 97110] [meta-bug] tracker bug for supporting C++ in -fanalyzer

Reply via email to