This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Add folly::Optional to unchecked-optional-access
ClosedPublic

Authored by adukeman on Jul 20 2023, 2:46 PM.

Details

Summary

The unchecked-optional-access check identifies attempted value
unwrapping without checking if the value exists. These changes extend
that support to checking folly::Optional.

Diff Detail

Event Timeline

adukeman created this revision.Jul 20 2023, 2:46 PM
Herald added a project: Restricted Project. · View Herald Transcript
adukeman requested review of this revision.Jul 20 2023, 2:47 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJul 20 2023, 2:47 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

To be honest, all those things just should be configurable instead of hardcoding them.
For example, a project that I work for got 4 different custom optional implementations, and this check is useless for all of them.
And still no boost::optional support.

gribozavr2 accepted this revision.Jul 20 2023, 4:15 PM
gribozavr2 added a subscriber: gribozavr2.

Thank you! Do you have commit access or do you need me to commit this patch for you?

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
845
This revision is now accepted and ready to land.Jul 20 2023, 4:15 PM
carlosgalvezp requested changes to this revision.Jul 20 2023, 9:40 PM

This should be a configuration option, we should not hardcore project-specific things in the source code.

This revision now requires changes to proceed.Jul 20 2023, 9:40 PM

This should be a configuration option, we should not hardcore project-specific things in the source code.

I agree, but we already are hardcoding specific types -- I think this is a separate (and valid) critique of the design. I'd propose filing an issue on the github tracker and we can follow up there. I, for one, would love to review such a change but don't have the time to write it.

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
846–848

A few concerns:

  1. This will allow hasValue on *any* of the optional types. While we know that the other types don't have this call, this is bad hygiene. At the least, we should note this potential problem in the comments.
  2. I don't think its worth duplicating the case above just to change the name, given that the action is identical. Instead, please generalize isOptionalMemberCallWithName to take a name matcher, and pass hasAnyName("has_value", "hasValue") for this case. The other calls to isOptionalMemberCallWithName will need to be changed to pass just hasName(...).

This should be a configuration option, we should not hardcore project-specific things in the source code.

I agree, but we already are hardcoding specific types -- I think this is a separate (and valid) critique of the design. I'd propose filing an issue on the github tracker and we can follow up there. I, for one, would love to review such a change but don't have the time to write it.

Is moving these values to config an appropriate task for somebody like me new to working on clang-tidy? I'd be happy to merge this and then try the transition to a config assuming there's some similar examples I can borrow from elsewhere in the codebase.

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
846–848

Sure. I can make that change.

This should be a configuration option, we should not hardcore project-specific things in the source code.

I agree, but we already are hardcoding specific types -- I think this is a separate (and valid) critique of the design. I'd propose filing an issue on the github tracker and we can follow up there. I, for one, would love to review such a change but don't have the time to write it.

Is moving these values to config an appropriate task for somebody like me new to working on clang-tidy? I'd be happy to merge this and then try the transition to a config assuming there's some similar examples I can borrow from elsewhere in the codebase.

This is one of the most complex clang-tidy checks. So, if you're looking for a CT starter task, I wouldn't recommend this particular challenge. That said, I think the clang-tidy side will be relatively easy -- CT has a mature config system/API. The harder part (and not CT relevant) is refactoring this code to consume that config. It's not terribly complicated but will require a bunch of changes and probably some design questions.

This should be a configuration option, we should not hardcore project-specific things in the source code.

I agree, but we already are hardcoding specific types -- I think this is a separate (and valid) critique of the design. I'd propose filing an issue on the github tracker and we can follow up there. I, for one, would love to review such a change but don't have the time to write it.

Is moving these values to config an appropriate task for somebody like me new to working on clang-tidy? I'd be happy to merge this and then try the transition to a config assuming there's some similar examples I can borrow from elsewhere in the codebase.

I think it can be a good starter task for a new engineer on the project. However, don't underestimate this problem, it will require the code to be refactored a little bit. For example, the function hasOptionalClassName needs restructuring so that it can accept class names from a list. Not a lot of work, but it isn't mechanically replacing string literals with a variable either.

This should be a configuration option, we should not hardcore project-specific things in the source code.

I agree, but we already are hardcoding specific types -- I think this is a separate (and valid) critique of the design. I'd propose filing an issue on the github tracker and we can follow up there. I, for one, would love to review such a change but don't have the time to write it.

Is moving these values to config an appropriate task for somebody like me new to working on clang-tidy? I'd be happy to merge this and then try the transition to a config assuming there's some similar examples I can borrow from elsewhere in the codebase.

I think it can be a good starter task for a new engineer on the project. However, don't underestimate this problem, it will require the code to be refactored a little bit. For example, the function hasOptionalClassName needs restructuring so that it can accept class names from a list. Not a lot of work, but it isn't mechanically replacing string literals with a variable either.

Indeed this is not "the standard" CT check, the core is part of Clang so I think it'd be good to add reviewers there as well in case this affects other parts of the codebase. In that sense it does not seen as trivial as I thought to make this user configurable, so perhaps opening a ticket and solve it there is a faster way forward.

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

If there's no need for absl here, why do we need to add folly?

carlosgalvezp resigned from this revision.Jul 21 2023, 10:40 AM
carlosgalvezp added a reviewer: aaron.ballman.

I think it'd be good to add reviewers there

I realize the CodeOwners for Analysis are already in the list of reviewers, I won't interfere then :)

This revision is now accepted and ready to land.Jul 21 2023, 10:41 AM
gribozavr2 added inline comments.Jul 21 2023, 10:53 AM
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
62

This is the branch for RD.getName() == "Optional" with a capital "O" because base::Optional, folly;:Optional are spelled with a capital "O".

Abseil provides absl::optional and it is handled under RD.getName() == "optional" together with std::optional above.

carlosgalvezp added inline comments.Jul 21 2023, 11:22 AM
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
62

Got it, thanks!

I have opened a refactoring ticket here: https://github.com/llvm/llvm-project/issues/64037

Thank you!

The review is marked as accepted, should we land it? Let me know if you need help with that :)

The review is marked as accepted, should we land it? Let me know if you need help with that :)

We're still waiting on some small changes: https://reviews.llvm.org/D155890#inline-1508661

adukeman updated this revision to Diff 543619.Jul 24 2023, 10:20 AM

Update calls to OptionalMemberCall to take a name matcher

Supports treating calls to optional::has_value and optional::hasValue identically

adukeman marked 3 inline comments as done.Jul 24 2023, 10:28 AM

Thanks for all the comments! I think I've got them all addressed and tests are passing locally.

The review is marked as accepted, should we land it? Let me know if you need help with that :)

Yes, will need help with that since I don't have commit access. Anybody with commit access, feel free to land this for me.

Some entry in release notes or/and check documentation would be welcome.

adukeman updated this revision to Diff 543659.Jul 24 2023, 11:37 AM

Update docs and run clang-format

PiotrZSL added inline comments.Jul 24 2023, 11:51 AM
clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-optional-access.rst
10–11

80 characters limit, wrap it

PiotrZSL accepted this revision.Jul 24 2023, 12:20 PM

+- LGTM, I will correct those nits and push it.

ymandel accepted this revision.Jul 24 2023, 12:24 PM
This revision was landed with ongoing or failed builds.Jul 24 2023, 12:43 PM
This revision was automatically updated to reflect the committed changes.