aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp')
-rw-r--r--clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp8
1 files changed, 6 insertions, 2 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
index b0bd827..31ae2b9 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
@@ -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(),