Skip to content

Invalid std::optional<> value reads sneak past static _and_ dynamic analysis #156762

@sh1boot

Description

@sh1boot
#include <optional>
int f(bool c) {
    std::optional<int> x;
    if (c) x = 3;
    return *x;
}

When I compile this with -fsanitize=undefined, memory I don't get any code generated to confirm that x did get initialised; but unlike an unadorned int x; version, I also don't get a compile time warning about the possible oversight. So undefined behaviour slips right through.

In this case we get something consistent with erroneous behaviour, where the result is at least predictable even if it's not right. However the intent of using the sanitiser has been undermined by premature optimisation.

The following version appears to behave as expected:

#include <optional>
int f(std::optional<int> x) {
    return *x;
}

Where the generated code does indeed check that there's a valid result available before returning it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzercompiler-rt:ubsanUndefined behavior sanitizerlibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.undefined behaviour

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions