This is an archive of the discontinued LLVM Phabricator instance.

[clang][dataflow] Fix a bug in handling of `operator->` for optional checker.
ClosedPublic

Authored by mboehme on May 17 2023, 6:27 AM.

Details

Summary

Prior to this patch, operator-> was being handled like operator*: It was
associating a Value of type T with the expression result (where T is the
template argument of the optional<T>). This is correct for operator*, which
returns a reference (of some flavor) to T, so that the result of the
CXXOperatorCallExpr is a glvalue of type T. However, operator* returns a
T*, so the result of the CXXOperatorCallExpr is a prvalue T*, which should
therefore be associated with PointerValue that in turn refers to a T.

I noticed this issue while working on the migration to strict handling of
value categories (see https://discourse.llvm.org/t/70086). The current behavior
also seems problematic more generally because it's plausible that the framework
may at some point introduce behavior that assumes an Expr of pointer type is
always associated with a PointerValue.

As it turns out, this patch fixes an existing FIXME in the test
OptionalValueInitialization.

Depends On D150657

Diff Detail

Event Timeline

mboehme created this revision.May 17 2023, 6:27 AM
Herald added a project: Restricted Project. · View Herald Transcript
mboehme requested review of this revision.May 17 2023, 6:27 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 17 2023, 6:27 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
ymandel accepted this revision.May 17 2023, 7:15 AM
ymandel added a subscriber: ymandel.

Nice catch!

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
789

this function will be left with only one caller. Maybe inline it? For that matter, should the other caller be changed in some parallel way?

This revision is now accepted and ready to land.May 17 2023, 7:15 AM
mboehme added inline comments.May 17 2023, 7:38 AM
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
789

this function will be left with only one caller. Maybe inline it?

The general style in this file seems to be to pull matcher expressions out into helper functions, even if they're only used in one place. FWIW, I'm personally not convinced this is helpful because you _want_ to be able to see exactly what a CaseOfCFGStmt is matching on, so inlining makes sense IMO. But I'm not sure I want to be inconsistent with the general style of this file -- it would make more sense to do a general cleanup. WDYT?

For that matter, should the other caller be changed in some parallel way?

No, that caller (buildDiagnoseMatchSwitch()) does not have the same problem because it looks only at the optional, not at the value that is contained in it (see also D150756, which makes this explicit), and the distinction between operator* and operator-> (for our purposes) is only in the way they return the contained value.

ymandel added inline comments.May 17 2023, 7:54 AM
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
789

regarding the matcher -- it's a judgment call; I agree that having to jump back and forth to read this case "statement" is problematic, but some of the matchers are kind of complicated, so a name can be a service to the reader. This one looked sufficiently simple to consider just inlining it, but I'm also fine leaving as is.

mboehme marked 2 inline comments as done.May 21 2023, 11:16 PM
mboehme added inline comments.
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
789

In that case, I think I'll leave this as-is for the time being and will revisit the question of inlining more generally.

This revision was landed with ongoing or failed builds.May 21 2023, 11:51 PM
This revision was automatically updated to reflect the committed changes.
mboehme marked an inline comment as done.