Skip to content

Commit

Permalink
[clang][dataflow] Don't clear cached field state if field is const (l…
Browse files Browse the repository at this point in the history
…lvm#113698)

... in the unchecked optional access model.
  • Loading branch information
jvoung authored Oct 28, 2024
1 parent bd6ab32 commit 1f6741c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -601,10 +601,14 @@ void handleNonConstMemberCall(const CallExpr *CE,
dataflow::RecordStorageLocation *RecordLoc,
const MatchFinder::MatchResult &Result,
LatticeTransferState &State) {
// When a non-const member function is called, reset some state.
if (RecordLoc != nullptr) {
// When a non-const member function is called, clear all (non-const)
// optional fields of the receiver. Const-qualified fields can't be
// changed (at least, not without UB).
for (const auto &[Field, FieldLoc] : RecordLoc->children()) {
if (isSupportedOptionalType(Field->getType())) {
QualType FieldType = Field->getType();
if (!FieldType.isConstQualified() &&
isSupportedOptionalType(Field->getType())) {
auto *FieldRecordLoc = cast_or_null<RecordStorageLocation>(FieldLoc);
if (FieldRecordLoc) {
setHasValue(*FieldRecordLoc, State.Env.makeAtomicBoolValue(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2167,7 +2167,7 @@ TEST_P(UncheckedOptionalAccessTest, OptionalReturnedFromFuntionCall) {
)");
}

TEST_P(UncheckedOptionalAccessTest, OptionalFieldModified) {
TEST_P(UncheckedOptionalAccessTest, NonConstMethodMayClearOptionalField) {
ExpectDiagnosticsFor(
R"(
#include "unchecked_optional_access_test.h"
Expand All @@ -2187,6 +2187,27 @@ TEST_P(UncheckedOptionalAccessTest, OptionalFieldModified) {
)");
}

TEST_P(UncheckedOptionalAccessTest,
NonConstMethodMayNotClearConstOptionalField) {
ExpectDiagnosticsFor(
R"(
#include "unchecked_optional_access_test.h"
struct Foo {
const $ns::$optional<std::string> opt;
void clear();
};
void target(Foo& foo) {
if (foo.opt) {
foo.opt.value();
foo.clear();
foo.opt.value();
}
}
)");
}

TEST_P(UncheckedOptionalAccessTest, StdSwap) {
ExpectDiagnosticsFor(
R"(
Expand Down

0 comments on commit 1f6741c

Please sign in to comment.