This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Add a checker for swapped literal arguments.
ClosedPublic

Authored by bkramer on Jul 10 2014, 2:56 AM.

Details

Reviewers
djasper
alexfh
Summary

This looks for swapped arguments by looking at implicit conversions of
literal arguments

void Foo(int, double);
Foo(1.0, 3); // Most likely a bug

We do this by checking that the same argument types exist in literals and
the declaration of the function.

Diff Detail

Event Timeline

bkramer updated this revision to Diff 11256.Jul 10 2014, 2:56 AM
bkramer retitled this revision from to [clang-tidy] Add a checker for swapped literal arguments..
bkramer updated this object.
bkramer added reviewers: alexfh, djasper.
bkramer added a subscriber: Unknown Object (MLST).
djasper added inline comments.Jul 10 2014, 3:20 AM
clang-tidy/misc/CMakeLists.txt
6

ImplicitArgumentConversion is not exactly what this does, I think. Maybe SwappedArgumentsCheck?

clang-tidy/misc/ImplicitArgumentConversion.cpp
33 ↗(On Diff #11256)

Why do we only care about literals?

34 ↗(On Diff #11256)

Maybe IgnoreParenImpCasts()?

52 ↗(On Diff #11256)

Mhmm. This seems like a very crude way of doing this. Might be ok for a first iteration, but it seems like we could actually be much smarter and check if there is a re-ordering that would fit better (and even extend the analysis to more than two parameters, no)?

clang-tidy/misc/ImplicitArgumentConversion.h
18 ↗(On Diff #11256)

This is VERY brief ;-)

alexfh added inline comments.Jul 10 2014, 4:52 AM
clang-tidy/misc/CMakeLists.txt
6

+1 for SwappedArgumentsCheck.

clang-tidy/misc/ImplicitArgumentConversion.cpp
52 ↗(On Diff #11256)

Instead, I'd check if swapping each consecutive pair of arguments decreases the number of conversions by 2. It would also be nice to specify which pair of arguments is likely to be swapped.

Worth a compiler warning?

If we're talking literals, could we just warn whenever someone wrote a
literal with a mismatched parameter? (3.0 for an int parameter -
skipping 3e6 as being safe because people like to write big ints with
exponent notation even though it's actually a double)

Things like passing literal true/false for int parameters is also
often a bad sign... (I tried to implement bool literal conversion at
some point, but never got around to finishing it - it caught some
cases like this)

thakis added a subscriber: thakis.Jul 10 2014, 8:38 AM

Wouldn't this make sense as a regular warning?

djasper edited edge metadata.Jul 10 2014, 9:40 AM

I think for this (and probably many future clang-tidy checks), the answer
"Does this make sense as a compiler warning?" is always: YES. However,
clang-tidy enables us to quickly develop and tune an implementation using
AST matchers, not worrying about slowing down the compiler and testing it
on a larger codebase in order establish whether a check/warning provides
sufficient benefit and even let users play around with it to get more
feedback. So, I see clang-tidy as a prototyping platform and good checks
will be turned into compiler warnings. At some stage we might want to think
about how we can simplify that process, i.e. how we can make porting a
clang-tidy check into a compiler warning easier, but IMO that stage isn't
necessarily now.

Makes sense, thanks.

bkramer updated this revision to Diff 11367.Jul 14 2014, 4:20 AM
bkramer edited edge metadata.

This is essentially a complete rewrite of the checker.

  • Only compares pairs of arguments, and emits a swap fixit.
  • Also looks at non-literal arguments. This increases false positives slightly but also catches a lot more cases.
  • Renamed the checker.
alexfh added inline comments.Jul 14 2014, 5:40 AM
clang-tidy/misc/SwappedArgumentsCheck.cpp
55

IIUC, isWrittenInSameFile(l1, l2) will return true if l1 and l2 are macro locations. Am I missing something?

78

I'd prefer "const auto *" (or just "auto", if you want to save a few keystrokes).

91

Name-based approach may be used independently of argument types. I'd expect x/y, raw/column and other argument pairs using the same type to be swapped occasionally.

99

"Two matching implicit casts" isn't enough to understand what's wrong here. Maybe something like this

warning: potentially swapped arguments for parameter "x" of type double and parameter "y" of type int
note: argument "0" has type int, argument "10e6" has type double

?

test/clang-tidy/misc-swapped-arguments.cpp
2

Please add a test where the invocations are inside a template with a couple of instantiations.

bkramer updated this revision to Diff 11375.Jul 14 2014, 6:52 AM
  • Fix for crashes when the warning is within a macro (+ test)
  • Use const auto *
  • Wording tweak for warning message. Added types and SourceRanges to make the af

fected arguments stand out. Sadly we don't print them on the command line :(

bkramer updated this revision to Diff 11381.Jul 14 2014, 7:22 AM

Updated for r212941.

alexfh accepted this revision.Jul 14 2014, 7:30 AM
alexfh edited edge metadata.

Looks good. Nice check!

This revision is now accepted and ready to land.Jul 14 2014, 7:30 AM
bkramer closed this revision.Jul 14 2014, 7:49 AM

Committed in rL212942