-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[FlowSensitive] [StatusOr] [7/N] Support StatusOr::emplace #163876
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FlowSensitive] [StatusOr] [7/N] Support StatusOr::emplace #163876
Conversation
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7
|
@llvm/pr-subscribers-clang-analysis @llvm/pr-subscribers-clang Author: Florian Mayer (fmayer) ChangesThis always makes the StatusOr OK. Full diff: https://github.com/llvm/llvm-project/pull/163876.diff 2 Files Affected:
diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp
index dc0a8f7e4cfd6..fa72cc24d8701 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 62e456ad07bdb..f354441299156 100644
--- a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
@@ -2915,6 +2915,54 @@ 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(bool b) {
+ STATUSOR_INT sor;
+ bool sor_ok = sor.ok();
+ if (b)
+ sor.emplace(42);
+ else if (sor_ok)
+ 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
|
Created using spr 1.3.7 [skip ci]
|
@BaLiKfromUA CC |
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7 [skip ci]
| if (b) | ||
| sor.emplace(42); | ||
| else if (sor_ok) | ||
| sor.value(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, the emplace happens in a disjoint branch from the value() access, so seems like it wouldn't directly test the emplace.
Did you mean to test if there is a control flow join (if not ok, do the emplace, if ok, no need to emplace, then after the branches access the value)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7 [skip ci]
This always makes the StatusOr OK. Reviewers: jvoung, Xazax-hun Reviewed By: jvoung Pull Request: llvm/llvm-project#163876
This always makes the StatusOr OK. Reviewers: jvoung, Xazax-hun Reviewed By: jvoung Pull Request: llvm#163876
This always makes the StatusOr OK. Reviewers: jvoung, Xazax-hun Reviewed By: jvoung Pull Request: llvm#163876
This always makes the StatusOr OK. Reviewers: jvoung, Xazax-hun Reviewed By: jvoung Pull Request: llvm#163876
This always makes the StatusOr OK.