Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d34d19d

Browse files
authored
[NFC] [FlowSensitive] [StatusOr] Add tests for pointer receivers
Reviewers: jvoung Reviewed By: jvoung Pull Request: #180079
1 parent 9ab3e33 commit d34d19d

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,6 +3984,134 @@ TEST_P(UncheckedStatusOrAccessModelTest, AccessorCall) {
39843984
)cc");
39853985
}
39863986

3987+
TEST_P(UncheckedStatusOrAccessModelTest, PointerReceivers) {
3988+
// The following examples are not sound as there could be opaque calls between
3989+
// the ok() and the value() calls that change the StatusOr value. However,
3990+
// this is the behavior that users expect so it is here to stay.
3991+
ExpectDiagnosticsFor(R"cc(
3992+
#include "unchecked_statusor_access_test_defs.h"
3993+
3994+
void target(STATUSOR_INT* sor) {
3995+
sor->value(); // [[unsafe]]
3996+
}
3997+
)cc");
3998+
ExpectDiagnosticsFor(R"cc(
3999+
#include "unchecked_statusor_access_test_defs.h"
4000+
4001+
void target(STATUSOR_INT* sor) {
4002+
sor->emplace(1);
4003+
sor->value();
4004+
}
4005+
)cc");
4006+
ExpectDiagnosticsFor(R"cc(
4007+
#include "unchecked_statusor_access_test_defs.h"
4008+
4009+
void target(STATUSOR_INT* sor) {
4010+
if (sor->ok())
4011+
sor->value();
4012+
else
4013+
sor->value(); // [[unsafe]]
4014+
}
4015+
)cc");
4016+
ExpectDiagnosticsFor(R"cc(
4017+
#include "unchecked_statusor_access_test_defs.h"
4018+
4019+
void target(STATUS* s) {
4020+
STATUSOR_INT* sor = Make<STATUSOR_INT*>();
4021+
if (!s->ok()) return;
4022+
if (*s == sor->status())
4023+
sor->value();
4024+
else
4025+
sor->value(); // [[unsafe]]
4026+
}
4027+
)cc");
4028+
ExpectDiagnosticsFor(R"cc(
4029+
#include "unchecked_statusor_access_test_defs.h"
4030+
4031+
struct Foo {
4032+
STATUSOR_INT* sor;
4033+
};
4034+
4035+
void target(Foo foo) {
4036+
if (foo.sor->ok())
4037+
foo.sor->value();
4038+
else
4039+
foo.sor->value(); // [[unsafe]]
4040+
}
4041+
)cc");
4042+
ExpectDiagnosticsFor(R"cc(
4043+
#include "unchecked_statusor_access_test_defs.h"
4044+
4045+
struct Foo {
4046+
STATUSOR_INT* sor;
4047+
};
4048+
4049+
void target(Foo foo) {
4050+
if (foo.sor->status().ok())
4051+
foo.sor->value();
4052+
else
4053+
foo.sor->value(); // [[unsafe]]
4054+
}
4055+
)cc");
4056+
}
4057+
4058+
TEST_P(UncheckedStatusOrAccessModelTest, PointerReceiversWithSelfReferentials) {
4059+
// Same as PointerReceivers, but with a self-referential pointer.
4060+
ExpectDiagnosticsFor(R"cc(
4061+
#include "unchecked_statusor_access_test_defs.h"
4062+
4063+
struct Bar;
4064+
struct Foo {
4065+
STATUSOR_INT* sor;
4066+
Bar* bar;
4067+
};
4068+
struct Bar {
4069+
Foo* foo;
4070+
};
4071+
4072+
void target(Bar* bar) {
4073+
if (bar->foo->sor->status().ok())
4074+
bar->foo->sor->value();
4075+
else
4076+
bar->foo->sor->value(); // [[unsafe]]
4077+
}
4078+
)cc");
4079+
4080+
ExpectDiagnosticsFor(R"cc(
4081+
#include "unchecked_statusor_access_test_defs.h"
4082+
4083+
struct Foo {
4084+
Foo* next;
4085+
STATUSOR_INT* sor;
4086+
};
4087+
4088+
void target(Foo* foo) {
4089+
if (foo->next->sor->status().ok())
4090+
// False positive, should be safe.
4091+
foo->next->sor->value(); // [[unsafe]]
4092+
else
4093+
foo->next->sor->value(); // [[unsafe]]
4094+
}
4095+
)cc");
4096+
}
4097+
4098+
TEST_P(UncheckedStatusOrAccessModelTest, PointerReceiversWithUnion) {
4099+
ExpectDiagnosticsFor(R"cc(
4100+
#include "unchecked_statusor_access_test_defs.h"
4101+
4102+
union Foo {
4103+
STATUSOR_INT* sor;
4104+
};
4105+
4106+
void target(Foo foo) {
4107+
if (foo.sor->ok())
4108+
foo.sor->value();
4109+
else
4110+
foo.sor->value(); // [[unsafe]]
4111+
}
4112+
)cc");
4113+
}
4114+
39874115
TEST_P(UncheckedStatusOrAccessModelTest, PointerLike) {
39884116
ExpectDiagnosticsFor(R"cc(
39894117
#include "unchecked_statusor_access_test_defs.h"

0 commit comments

Comments
 (0)