diff --git a/infer/src/pulse/PulseModels.ml b/infer/src/pulse/PulseModels.ml index ebceb47e5..8da884e47 100644 --- a/infer/src/pulse/PulseModels.ml +++ b/infer/src/pulse/PulseModels.ml @@ -1075,14 +1075,14 @@ module ProcNameDispatcher = struct ~desc:"std::optional::optional(std::optional arg)" ; -"std" &:: "optional" &:: "optional" $ capt_arg_payload $+ capt_arg_payload $+...$--> Optional.assign_value ~desc:"std::optional::optional(Value arg)" - ; -"std" &:: "optional" &:: "operator=" <>$ capt_arg_payload + ; -"std" &:: "optional" &:: "operator=" $ capt_arg_payload $+ any_arg_of_typ (-"std" &:: "nullopt_t") $--> Optional.assign_none ~desc:"std::optional::operator=(None)" - ; -"std" &:: "optional" &:: "operator=" <>$ capt_arg_payload + ; -"std" &:: "optional" &:: "operator=" $ capt_arg_payload $+ capt_arg_payload_of_typ (-"std" &:: "optional") $--> Optional.assign_optional_value ~desc:"std::optional::operator=(std::optional arg)" - ; -"std" &:: "optional" &:: "operator=" <>$ capt_arg_payload $+ capt_arg_payload + ; -"std" &:: "optional" &:: "operator=" $ capt_arg_payload $+ capt_arg_payload $+...$--> Optional.assign_value ~desc:"std::optional::operator=(Value arg)" ; -"std" &:: "optional" &:: "emplace<>" $ capt_arg_payload $+...$--> Optional.emplace ~desc:"std::optional::emplace()" @@ -1090,6 +1090,8 @@ module ProcNameDispatcher = struct $+...$--> Optional.emplace ~desc:"std::optional::emplace()" ; -"std" &:: "optional" &:: "has_value" <>$ capt_arg_payload $+...$--> Optional.has_value ~desc:"std::optional::has_value()" + ; -"std" &:: "__optional_storage_base" &:: "has_value" $ capt_arg_payload + $+...$--> Optional.has_value ~desc:"std::optional::has_value()" ; -"std" &:: "optional" &:: "operator_bool" <>$ capt_arg_payload $+...$--> Optional.has_value ~desc:"std::optional::operator_bool()" ; -"std" &:: "optional" &:: "reset" <>$ capt_arg_payload diff --git a/infer/tests/codetoanalyze/cpp/pulse/optional.cpp b/infer/tests/codetoanalyze/cpp/pulse/optional.cpp index d9b90e73d..fac78061a 100644 --- a/infer/tests/codetoanalyze/cpp/pulse/optional.cpp +++ b/infer/tests/codetoanalyze/cpp/pulse/optional.cpp @@ -238,6 +238,14 @@ int std_none_check_ok() { return -1; } +int std_none_check_has_value_ok() { + std::optional foo{std::nullopt}; + if (foo.has_value()) { + return foo.value(); + } + return -1; +} + int std_none_no_check_bad() { std::optional foo{std::nullopt}; return foo.value(); @@ -305,6 +313,7 @@ int std_value_or_check_value_ok_FP() { } return -1; } + struct Container final { std::vector _vec; @@ -324,3 +333,19 @@ struct Container final { return -1; } }; + +std::optional might_return_none(bool b, std::string x) { + if (b) { + return std::nullopt; + } + return x; +} + +std::string reassing_non_empty_ok(const std::string& x) { + std::optional foo = might_return_none(true, x); + if (!foo.has_value()) { + foo = x; + } + + return foo.value(); +}