This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Fix false-positive in readability-container-size-empty
ClosedPublic

Authored by PiotrZSL on Feb 16 2023, 1:48 PM.

Details

Summary

Ignoring std::array type when matching 'std:array == std::array()'.
In such case we shouldn't propose to use empty().

Fixes: https://github.com/llvm/llvm-project/issues/48286

Diff Detail

Event Timeline

PiotrZSL created this revision.Feb 16 2023, 1:48 PM
Herald added a project: Restricted Project. · View Herald Transcript

I may consider tomorrow moving std::array into into some dedicated option, like IgnoredContainersInComparisonRegexp

PiotrZSL updated this revision to Diff 498450.EditedFeb 17 2023, 11:04 AM

Add configuration option. Release Notes + documentation for new option powered by ChatGPT.

PiotrZSL published this revision for review.Feb 17 2023, 11:56 AM

Ready for review

Herald added a project: Restricted Project. · View Herald TranscriptFeb 17 2023, 11:56 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Looks good in general, thanks for the fix! I have minor comments.

Also, I found the comment on the Github issue interesting:

Perhaps, this can even be generalized to all types whose size() and empty() are constexpr.

Would that be a more scalable approach than maintaining a list of classes to ignore?

clang-tools-extra/docs/clang-tidy/checks/readability/container-size-empty.rst
30

For better readability, please spell out this acronym.

clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp
723

Missing a test case to test that the option works as expected, e.g. set it to a non-default value.

760

Empty

Perhaps, this can even be generalized to all types whose size() and empty() are constexpr.

Problem is that you can mark function constexpr, but it doesnt need to be constexpr evaluated:

struct C
{
    constexpr C(int v) : v(v) {}
    constexpr int size() const { return v; };
    constexpr bool empty() const { return v == 0; };
    constexpr void setSize(int vv) { v = vv; };
    int v;
};

constexpr C value(6);
C non_const(6);

I would need to check if it's constexpr evaluated, but here we don't evaluate it. Alternative would be to check if method use only template arguments, but then it could use other const static or something...
This is why I decided to go with config. And still you may have other user provided classes that does not have empty/size constexpr.

Perhaps, this can even be generalized to all types whose size() and empty() are constexpr.

Problem is that you can mark function constexpr, but it doesnt need to be constexpr evaluated:

struct C
{
    constexpr C(int v) : v(v) {}
    constexpr int size() const { return v; };
    constexpr bool empty() const { return v == 0; };
    constexpr void setSize(int vv) { v = vv; };
    int v;
};

constexpr C value(6);
C non_const(6);

I would need to check if it's constexpr evaluated, but here we don't evaluate it. Alternative would be to check if method use only template arguments, but then it could use other const static or something...
This is why I decided to go with config. And still you may have other user provided classes that does not have empty/size constexpr.

Ok, good point!

clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
106

I also realize that in other checks, this is typically implemented as a list (comma or semicolon-separated) instead of a regex. Would it make sense to do that here as well, for consistency? As a user I would also find it easier and more intuitive to type a list than to have to google how to create a list using regex :)

PiotrZSL added inline comments.Feb 22 2023, 12:59 AM
clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
106

I usually prefer regexp, as it allow more flexibility (like matching templates), but I can change this to use semicolon separated list, in this case it would also do a job.

PiotrZSL marked 4 inline comments as done.Feb 22 2023, 1:51 PM
PiotrZSL updated this revision to Diff 499642.Feb 22 2023, 1:51 PM

Review fixes + Rebase

PiotrZSL updated this revision to Diff 499643.Feb 22 2023, 1:52 PM

Removed include

PiotrZSL updated this revision to Diff 500232.Feb 24 2023, 9:03 AM

Rebase + Used existing matcher instead of creating new one

Thanks for the fix! Looks good, have a couple minor comments.

clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
88–89

While this improves readability, we typically prefer these changes to be done in a separate NFC patch to reduce review noise (and thereby improving review speed).

180

This is no longer just StdArray, it can be any excluded type - please rename accordingly.

clang-tools-extra/docs/clang-tidy/checks/readability/container-size-empty.rst
34

Only std::array is currently part of the default.

clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp
658

What was the motivation for this change? Similarly to my previous comment this seems unrelated to the main scope of the patch.

PiotrZSL updated this revision to Diff 500437.Feb 25 2023, 8:50 AM
PiotrZSL marked 2 inline comments as done.

Fix review comments

carlosgalvezp accepted this revision.Feb 25 2023, 9:36 AM
This revision is now accepted and ready to land.Feb 25 2023, 9:36 AM