[clang] c745f74 - [FlowSensitive] [StatusOr] [7/N] Support StatusOr::emplace
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 23 12:27:33 PDT 2025
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
More information about the cfe-commits
mailing list