Page MenuHomePhabricator

[clang-tidy] new check readability-no-alternative-tokens
Needs RevisionPublic

Authored by mgehre on Mar 23 2017, 2:15 PM.

Details

Summary

Flags (and replaces) the alternative tokens for binary and unary
operators, such as `not (for !), bitand (for &), or (for ||`)
or `not_eq (for !=`).

Event Timeline

mgehre created this revision.Mar 23 2017, 2:15 PM

I think will be good idea to make this check working in both ways (standard or alternative operator representations), depending on option.

Probably readability-operators-representation will be better name for check.

See also PR25195.

Eugene.Zelenko set the repository for this revision to rL LLVM.
Eugene.Zelenko added a subscriber: Prazek.

Thanks for your feedback, Eugene!

I'm not sure if it would be helpful to have this check in both ways. I did a code search for "not_eq", "bitand" and "and_eq"
on github, and their usage seems to be a clear minority.

So I would propose to keep the features as-is for now,
change the name to readability-operators-representation, and then later (someone else?) might also add an option
for making this work the other way around. Would that be ok for you?

Were you refering to https://reviews.llvm.org/D25195 ("[lit] Fix FormatError on individual test timeout")?

alexfh edited edge metadata.Mar 24 2017, 4:28 AM

Thanks for your feedback, Eugene!

I'm not sure if it would be helpful to have this check in both ways. I did a code search for "not_eq", "bitand" and "and_eq"
on github, and their usage seems to be a clear minority.

So I would propose to keep the features as-is for now,
change the name to readability-operators-representation, and then later (someone else?) might also add an option
for making this work the other way around. Would that be ok for you?

Were you refering to https://reviews.llvm.org/D25195 ("[lit] Fix FormatError on individual test timeout")?

Nope, "PR" notation is used to reference bugs ("Problem Reports", PRobably): http://llvm.org/PR25195

So I would propose to keep the features as-is for now,
change the name to readability-operators-representation, and then later (someone else?) might also add an option
for making this work the other way around. Would that be ok for you?

Fine by me.

FWIW, I'm pretty sure this can and should be done on the lexer level - it will be faster and more universal.

Thanks for working on this!

I'm not sure if it would be helpful to have this check in both ways. I did a code search for "not_eq", "bitand" and "and_eq" on github, and their usage seems to be a clear minority.

I actually was requesting the opposite version of this (but suggesting to implement both), because for me "if (!something)" is much harder to read than "if (not something)" (I am a bit blind).

So I would propose to keep the features as-is for now, change the name to readability-operators-representation, and then later (someone else?) might also add an option for making this work the other way around. Would that be ok for you?

Sounds good to me. This solves half of the problem, and I agree with you that more people will benefit from this check than from the opposite check. Thanks again for working on this!

mgehre updated this revision to Diff 93057.Mar 25 2017, 2:24 PM

Rename check to readability-operators-representation

aaron.ballman added inline comments.Mar 27 2017, 7:45 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

I think this would make more sense lifted into an AST matcher -- there are bound to be a *lot* of binary operators, so letting the matcher memoize things is likely to give better performance.

69

This diagnostic doesn't help the user to understand what's wrong with their code (especially in the presence of multiple operators). Perhaps "'%0' is an alternative token spelling; consider using '%1'"

It would be nice if we could say "consider using %1 for <reason>", but I'm really not certain why we would diagnose this code in the first place (it's purely a matter of stylistic choice, as I understand it).

docs/clang-tidy/checks/readability-operators-representation.rst
5

This underline is going to cause Sphinx diagnostics.

9

Why would someone want to do this? You should at least touch on that in the documentation.

Also, this doesn't read very clearly to me. Perhaps it would be better as a table with two columns, the first specifying the alternative token spelling and the second specifying the replacement (with suitable headings),

test/clang-tidy/readability-operators-representation.cpp
55

Please add a test where a class overloads the operators. For special fun:

struct S {
  friend S& operator and(const S &LHS, const S &RHS);
};

int main() {
  S s1, s2;
  S s3 = s1 and s2;
}

I'm not convinced the correct answer here is to tell the user to use a spelling that isn't used by the class definition...

alexfh added inline comments.Mar 27 2017, 9:51 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Any reasons not to do this on the lexer level?

aaron.ballman added inline comments.Mar 27 2017, 9:56 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Technical reasons? None.
User-experience reasons? We wouldn't want this to be on by default (I don't think) and we usually don't implement off-by-default diagnostics in Clang. I think a case could be made for doing it in the Lexer if the performance is really that bad with a clang-tidy check and we couldn't improve it here, though.

mgehre updated this revision to Diff 93309.Mar 28 2017, 3:07 PM

Improved diagnostic; updated documentation; added test for overloaded operator

clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Do I correctly understand that "doing this on lexer level" would mean to implement this as a warning directly into clang? If yes, would it be possible to generate fixits and have them possibly applied automatically (as it is the case for clang-tidy)?

69

The main rational for this check is to enforce consistency and thus make it easier to read and comprehend the code.
I agree with your proposed diagnostics.

aaron.ballman added inline comments.Mar 29 2017, 9:30 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
22

I think that this check should only be performed in C++. In C, the alternative token spellings are implemented as macros and would require additional work to support.

35

You are correct, that means implementing it as a warning in Clang. I believe you can still generate those fixits from lexer-level diagnostics, but have not verified it.

However, I don't think this diagnostic would be appropriate for Clang because it would have to be off by default.

69

I think that enforcing consistency is a good rationale for having the check, but would second the suggestion that this check have an option to enforce the consistency one way or the other.

Then the diagnostic can be:

"'%0' is %select{an alternative token|a primary token}2; consider using '%1' for consistency"

alexfh added inline comments.Mar 30 2017, 9:28 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Actually, I was thinking about changing this clang-tidy check to analyze token stream somehow (probably by handling PPCallbacks to detect ranges that need to be re-lexed) instead of matching the AST. I didn't intend to propose a new Clang warning (but it looks like the wording was misleading).

mgehre updated this revision to Diff 93519.Mar 30 2017, 12:10 PM

only check C++ code; only match operators that can have alternative representations

aaron.ballman added inline comments.Apr 3 2017, 4:56 PM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

There is some value in that -- it means we could support C, for instance. I'm not certain how easy or hard it would be, but suspect it's reasonable. However, in C, there's still the problem of the include file that introduces those macros. Do we have facilities to remove an include in clang-tidy?

69

The diagnostic is improved, but there's still no way to go the opposite direction (from primary to alternative).

Eugene.Zelenko added inline comments.Apr 3 2017, 5:04 PM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Yes, it may make sense in C, but parameter for map from macro name to operator is needed.

Product I'm working for, with long history, had alternative operator presentation implemented in C.

alexfh added inline comments.Apr 4 2017, 5:57 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Changing macro-based "alternative tokens" to the corresponding operators can also be formulated in the terms of expanding a set of macros, which should work with any LangOpts and arbitrary alternative operator names.

However, in C, there's still the problem of the include file that introduces those macros.

Sounds like a generic "remove unused includes" problem, since we need to analyze whether the header is needed for anything else. In particular, even if the use of the header is limited to the alternative representations of operators, we can't remove the include until we replace all these macros. Clang-tidy doesn't provide any support for transactional fixes and dependencies between fixes.

aaron.ballman added inline comments.Apr 4 2017, 6:06 AM
clang-tidy/readability/OperatorsRepresentationCheck.cpp
35

Sounds like a generic "remove unused includes" problem, since we need to analyze whether the header is needed for anything else. In particular, even if the use of the header is limited to the alternative representations of operators, we can't remove the include until we replace all these macros. Clang-tidy doesn't provide any support for transactional fixes and dependencies between fixes.

That's a good point. I also don't think an unused include is sufficiently awful to block this.

Yep, I am also a fan of "and","or" and "not". The other tokens doesn't make it more readable imho

alexfh requested changes to this revision.Mar 14 2018, 7:33 AM

As noted above, my concern with the current implementation is that the use of AST in this check seems to be superfluous. It should be enough to handle PPCallbacks and re-lex each file opened during compilation to find all alternative tokens.

This revision now requires changes to proceed.Mar 14 2018, 7:33 AM