Author: Florian Mayer Date: 2025-10-23T12:27:29-07:00 New Revision: c745f745b11766949cfc7326e69e3cdccf9cc893
URL: https://github.com/llvm/llvm-project/commit/c745f745b11766949cfc7326e69e3cdccf9cc893 DIFF: https://github.com/llvm/llvm-project/commit/c745f745b11766949cfc7326e69e3cdccf9cc893.diff LOG: [FlowSensitive] [StatusOr] [7/N] Support StatusOr::emplace This always makes the StatusOr OK. Reviewers: jvoung, Xazax-hun Reviewed By: jvoung Pull Request: https://github.com/llvm/llvm-project/pull/163876 Added: Modified: clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp index 22465e664cdd3..90551c22e0734 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp @@ -516,6 +516,18 @@ static void transferNotOkStatusCall(const CallExpr *Expr, State.Env.assume(A.makeNot(OkVal.formula())); } +static void transferEmplaceCall(const CXXMemberCallExpr *Expr, + const MatchFinder::MatchResult &, + LatticeTransferState &State) { + RecordStorageLocation *StatusOrLoc = + getImplicitObjectLocation(*Expr, State.Env); + if (StatusOrLoc == nullptr) + return; + + auto &OkVal = valForOk(locForStatus(*StatusOrLoc), State.Env); + State.Env.assume(OkVal.formula()); +} + CFGMatchSwitch<LatticeTransferState> buildTransferMatchSwitch(ASTContext &Ctx, CFGMatchSwitchBuilder<LatticeTransferState> Builder) { @@ -559,6 +571,8 @@ buildTransferMatchSwitch(ASTContext &Ctx, }) .CaseOfCFGStmt<CallExpr>(isOkStatusCall(), transferOkStatusCall) .CaseOfCFGStmt<CallExpr>(isNotOkStatusCall(), transferNotOkStatusCall) + .CaseOfCFGStmt<CXXMemberCallExpr>(isStatusOrMemberCallWithName("emplace"), + transferEmplaceCall) .Build(); } diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp index fff79e52e0aaa..425beb939a42a 100644 --- a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp +++ b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp @@ -2928,6 +2928,53 @@ TEST_P(UncheckedStatusOrAccessModelTest, PointerEqualityCheck) { )cc"); } +TEST_P(UncheckedStatusOrAccessModelTest, Emplace) { + ExpectDiagnosticsFor(R"cc( +#include "unchecked_statusor_access_test_defs.h" + + struct Foo { + Foo(int); + }; + + void target(absl::StatusOr<Foo> sor, int value) { + sor.emplace(value); + sor.value(); + } + )cc"); + ExpectDiagnosticsFor(R"cc( +#include "unchecked_statusor_access_test_defs.h" + + struct Foo { + Foo(std::initializer_list<int>, int); + }; + + void target(absl::StatusOr<Foo> sor, int value) { + sor.emplace({1, 2, 3}, value); + sor.value(); + } + )cc"); + ExpectDiagnosticsFor(R"cc( +#include "unchecked_statusor_access_test_defs.h" + + void target() { + STATUSOR_INT sor; + bool sor_ok = sor.ok(); + if (!sor_ok) + sor.emplace(42); + sor.value(); + } + )cc"); + ExpectDiagnosticsFor(R"cc( +#include "unchecked_statusor_access_test_defs.h" + + void target(bool b) { + STATUSOR_INT sor; + if (b) sor.emplace(42); + if (b) sor.value(); + } + )cc"); +} + } // namespace std::string _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
