aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp')
-rw-r--r--clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
index 4827cc1..cae9265 100644
--- a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
@@ -2453,6 +2453,167 @@ TEST_P(UncheckedStatusOrAccessModelTest, SubclassOperator) {
)cc");
}
+TEST_P(UncheckedStatusOrAccessModelTest, UnwrapValueWithStatusCheck) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor) {
+ if (sor.status().ok())
+ sor.value();
+ else
+ sor.value(); // [[unsafe]]
+ }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, UnwrapValueWithStatusRefCheck) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor) {
+ const STATUS& s = sor.status();
+ if (s.ok())
+ sor.value();
+ else
+ sor.value(); // [[unsafe]]
+ }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, UnwrapValueWithStatusPtrCheck) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor) {
+ const STATUS* s = &sor.status();
+ if (s->ok())
+ sor.value();
+ else
+ sor.value(); // [[unsafe]]
+ }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, UnwrapValueWithMovedStatus) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor) {
+ if (std::move(sor.status()).ok())
+ sor.value();
+ else
+ sor.value(); // [[unsafe]]
+ }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, MembersUsedInsideStatus) {
+ ExpectDiagnosticsFor(R"cc(
+ namespace absl {
+
+ class Status {
+ public:
+ bool ok() const;
+
+ void target() const { ok(); }
+ };
+
+ } // namespace absl
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, StatusUpdate) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor) {
+ STATUS s;
+ s.Update(sor.status());
+ if (s.ok())
+ sor.value();
+ else
+ sor.value(); // [[unsafe]]
+ }
+ )cc");
+
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor1, STATUSOR_INT sor2) {
+ STATUS s;
+ s.Update(sor1.status());
+ s.Update(sor2.status());
+ if (s.ok()) {
+ sor1.value();
+ sor2.value();
+ }
+ }
+ )cc");
+
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor1, STATUSOR_INT sor2) {
+ STATUS s;
+ s.Update(sor1.status());
+ CHECK(s.ok());
+ s.Update(sor2.status());
+ sor1.value();
+ sor2.value(); // [[unsafe]]
+ }
+ )cc");
+
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor1, STATUSOR_INT sor2) {
+ STATUS s;
+ s.Update(sor1.status());
+ CHECK(s.ok());
+ sor1.value();
+ sor2.value(); // [[unsafe]]
+ }
+ )cc");
+
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor1, STATUSOR_INT sor2) {
+ STATUS s;
+ STATUS sor1_status = sor1.status();
+ s.Update(std::move(sor1_status));
+ CHECK(s.ok());
+ sor1.value();
+ sor2.value(); // [[unsafe]]
+ }
+ )cc");
+
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT sor1, STATUSOR_INT sor2) {
+ STATUS s;
+ STATUS sor1_status = sor1.status();
+ sor1_status.Update(sor2.status());
+ s.Update(std::move(sor1_status));
+ CHECK(s.ok());
+ sor1.value();
+ sor2.value();
+ }
+ )cc");
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ const STATUS& OptStatus();
+
+ void target(STATUSOR_INT sor) {
+ auto s = sor.status();
+ s.Update(OptStatus());
+ if (s.ok()) sor.value();
+ }
+ )cc");
+}
+
} // namespace
std::string