[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 6 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:255
+  std::string NodeTypeName =
+  Node->getType().getAsString(Node->getASTContext().getPrintingPolicy());
+  StringRef CaptureName{NodeTypeName};

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > Hmm, one downside to using the printing policy to get the node name is 
> > > that there can be alternative spellings for the same type that the user 
> > > might reasonably expect to be applied. e.g., if the user expects to 
> > > ignore `bool` datatypes and the printing policy wants to spell the type 
> > > as `_Bool`, this won't behave as expected.
> > But then the diagnostic is inconsistent with what the compiler is 
> > configured to output as diagnostics, isn't it? Can I stringify through 
> > Clang with some "default" printing policy?
> The situation I'm worried about is something like this in C code:
> ```
> #include 
> 
> void func(bool b, bool c) {}
> ```
> because the `bool` in the function signature will expand to `_Bool` after the 
> preprocessor gets to it (because of the contents of ``). If the 
> user writes `bool` in their configuration file because that's what they've 
> written in their function signatures, will this fail because the printing 
> policy says it should be `_Bool`?
> 
> Along similar lines, I wonder about things like `struct S` vs `S` (in C), 
> `signed char` vs `char`, types within anonymous namespaces (where we print 
> ``), etc. Basically, any time when the printing policy 
> may differ from what the user lexically writes in code.
Meanwhile, I realised we are talking of two entirely distinct things. I will 
look into how this `PrintingPolicy` stuff works... I agree that the ignore 
rules (where the comment was originally posted) should respect the text written 
into the code as-is. The diagnostics printing type names could continue using 
the proper printing policy (to be in line with how Sema diagnoses, AFAIK).



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:402-403
+
+// Unfortunately, undersquiggly highlights are for some reason chewed up
+// and not respected by diagnostics from Clang-Tidy. :(
+diag(First->getLocation(), "the first parameter in the range is '%0'",

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > Can you post a screenshot of what you mean?
> > Given
> > 
> > ```
> > Diag << SourceRange{First->getSourceRange().getBegin(), 
> > Last->getSourceRange().getEnd()};
> > ```
> > 
> > The diagnostic is still produced with only a `^` at the original 
> > `diag(Location)`, ignoring the fed `SourceRange`:
> > 
> > ```
> > /home/whisperity/LLVM/Build/../llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:21:18:
> >  warning: 3 adjacent parameters of 'redeclChain' of similar type ('int') 
> > are easily swapped by mistake [bugprone-easily-swappable-parameters]
> > void redeclChain(int I, int J, int K) {}
> >  ^
> > ```
> > 
> > Instead of putting all the squigglies in as the range-location highlight, 
> > like how `Sema` can diagnose:
> > 
> > ```
> > /home/whisperity/LLVM/Build/../llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:21:18:
> >  warning: 3 adjacent parameters of 'redeclChain' of similar type ('int') 
> > are easily swapped by mistake [bugprone-easily-swappable-parameters]
> > void redeclChain(int I, int J, int K) {}
> >  ^~~
> > ```
> > 
> > I would not want to put additional note tags in an otherwise already 
> > verbose output.
> > 
> > Back in 2019 I was investigating this issue specifically for another 
> > checker I was working on, but hit the wall... Somewhere deep inside where 
> > Tidy diagnostic stuff is translated and consumed to Clang stuff, it goes 
> > away. It shouldn't, because there are statements that seemingly copy the 
> > `Diag.Ranges` array over, but it still does not come out.
> > 
> > ... EDIT: I found [[ 
> > http://lists.llvm.org/pipermail/cfe-dev/2019-October/063676.html | the 
> > relevant mailing list post ]].
> > ... EDIT: I found the relevant mailing list post.
> 
> Oh wow, I had no idea! That's a rather unfortunate bug. :-(
Speaking of bugs, shall I put it up on Bugzilla, or see if anyone reported 
already? Would require me digging into that "where are the data structures 
copied" kind of thing to figure it out again.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h:30
+  void storeOptions(ClangTidyOptions::OptionMap ) override;
+
+  /// The minimum length of an adjacent swappable parameter range required for

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 3 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:402-403
+
+// Unfortunately, undersquiggly highlights are for some reason chewed up
+// and not respected by diagnostics from Clang-Tidy. :(
+diag(First->getLocation(), "the first parameter in the range is '%0'",

whisperity wrote:
> aaron.ballman wrote:
> > whisperity wrote:
> > > aaron.ballman wrote:
> > > > Can you post a screenshot of what you mean?
> > > Given
> > > 
> > > ```
> > > Diag << SourceRange{First->getSourceRange().getBegin(), 
> > > Last->getSourceRange().getEnd()};
> > > ```
> > > 
> > > The diagnostic is still produced with only a `^` at the original 
> > > `diag(Location)`, ignoring the fed `SourceRange`:
> > > 
> > > ```
> > > /home/whisperity/LLVM/Build/../llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:21:18:
> > >  warning: 3 adjacent parameters of 'redeclChain' of similar type ('int') 
> > > are easily swapped by mistake [bugprone-easily-swappable-parameters]
> > > void redeclChain(int I, int J, int K) {}
> > >  ^
> > > ```
> > > 
> > > Instead of putting all the squigglies in as the range-location highlight, 
> > > like how `Sema` can diagnose:
> > > 
> > > ```
> > > /home/whisperity/LLVM/Build/../llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:21:18:
> > >  warning: 3 adjacent parameters of 'redeclChain' of similar type ('int') 
> > > are easily swapped by mistake [bugprone-easily-swappable-parameters]
> > > void redeclChain(int I, int J, int K) {}
> > >  ^~~
> > > ```
> > > 
> > > I would not want to put additional note tags in an otherwise already 
> > > verbose output.
> > > 
> > > Back in 2019 I was investigating this issue specifically for another 
> > > checker I was working on, but hit the wall... Somewhere deep inside where 
> > > Tidy diagnostic stuff is translated and consumed to Clang stuff, it goes 
> > > away. It shouldn't, because there are statements that seemingly copy the 
> > > `Diag.Ranges` array over, but it still does not come out.
> > > 
> > > ... EDIT: I found [[ 
> > > http://lists.llvm.org/pipermail/cfe-dev/2019-October/063676.html | the 
> > > relevant mailing list post ]].
> > > ... EDIT: I found the relevant mailing list post.
> > 
> > Oh wow, I had no idea! That's a rather unfortunate bug. :-(
> Speaking of bugs, shall I put it up on Bugzilla, or see if anyone reported 
> already? Would require me digging into that "where are the data structures 
> copied" kind of thing to figure it out again.
Nevermind, this is worth [[ http://bugzilla.llvm.org/show_bug.cgi?id=49000 | a 
bug report ]] just so we can track it in the proper location.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D69560#2536570 , @steveire wrote:

> I haven't read through all the comments, but the word 'easily' implies 
> 'desirable'. This check seems to be for finding params which are undesirably 
> swappable, right?

The `easily` was to mean that the swap can be done with little effort (i.e. "in 
an easy fashion"?) and by accident. We want to find function signatures where 
that is the case, yes. TL;DR: //"This function will be misused by a careless 
client, please try designing a better interface!"//


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:10
+
+void declaration(int Param, int Other); // NO-WARN: No chance to change this 
function.
+

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > whisperity wrote:
> > > > aaron.ballman wrote:
> > > > > whisperity wrote:
> > > > > > aaron.ballman wrote:
> > > > > > > I think this is a case where we could warn when the declaration 
> > > > > > > is outside of a system header (perhaps as an option).
> > > > > > > 
> > > > > > > Thinking about it a bit more, declarations and definitions 
> > > > > > > provide a novel way to get another kind of swap:
> > > > > > > ```
> > > > > > > void func(int x, int y);
> > > > > > > void func(int y, int x) {} // Oops, the swap was probably not 
> > > > > > > intentional
> > > > > > > ```
> > > > > > > which may or may not be interesting for a check (or its 
> > > > > > > heuristics).
> > > > > > I gave this some thought. It is a very good idea, but I believe not 
> > > > > > for //this// check, but D20689. What do you think of that? Maybe 
> > > > > > simply saying "call site v. function node that was called" could be 
> > > > > > extended with a completely analogous, string distance function 
> > > > > > based "function definition node v. redecl chain" case.
> > > > > Hmmm, my impression is that this check is fundamentally about 
> > > > > *parameter* ordering whereas D20689 is about *argument* ordering. 
> > > > > Given that the example is about the ordering of parameters and 
> > > > > doesn't have anything to do with call sites, I kind of think the 
> > > > > functionality would be better in a parameter-oriented check.
> > > > > 
> > > > > That said, it doesn't feel entirely natural to add it to this check 
> > > > > because this check is about parameters that are easily swappable *at 
> > > > > call sites*, and this situation is not exactly that. However, it 
> > > > > could probably be argued that it is appropriate to add it to this 
> > > > > check given that swapped parameters between the declaration and the 
> > > > > definition are likely to result in swapped arguments at call sites.
> > > > > 
> > > > > Don't feel obligated to add this functionality to this check (or 
> > > > > invent a new check), though.
> > > > It just seems incredibly easier to put it into the other check, as that 
> > > > deals with names. But yes, then it would be a bit weird for the 
> > > > "suspicious call argument" check to say something about the 
> > > > definition... This check (and the relevant Core Guideline) was 
> > > > originally meant to consider **only** types (this is something I'll 
> > > > have to emphasise more in the research paper too!). Everything that 
> > > > considers //names// is only for making the check less noisy and make 
> > > > the actually emitted results more useful. However, I feel we should 
> > > > //specifically// not rely on the names and the logic too much.
> > > > 
> > > > But(!) your suggestion is otherwise a good idea. I am not sure if the 
> > > > previous research (with regards to names) consider the whole "forward 
> > > > declaration" situation, even where they did analysis for C projects, 
> > > > not just Java.
> > > > However, I feel we should specifically not rely on the names and the 
> > > > logic too much.
> > > 
> > > I agree, to a point. I don't think the basic check logic should be 
> > > name-sensitive, but I do think we need to rely on names to tweak the 
> > > true/false positive/negative ratios. I think most of the time when we're 
> > > relying on names should wind up being configuration options so that users 
> > > can tune the algorithm to their needs.
> > > 
> > > We could put the logic into the suspicious call argument check with 
> > > roughly the same logic -- the call site looks like it has potentially 
> > > swapped arguments because the function redeclaration chain (which 
> > > includes the function definition, as that's also a declaration) has 
> > > inconsistent parameter names. So long as the diagnostic appears on the 
> > > call site, and then refers back to the inconsistent declarations, it 
> > > could probably work. However, I think it'd be a bit strange to diagnose 
> > > the call site because the user of the API didn't really do anything wrong 
> > > (and they may not even be able to change the declaration or the 
> > > definition where the problem really lives).
> > But wait... suppose there is a project A, which sees the header for `f(int 
> > x, int y)` and has a call `f(y, x)`. That will be diagnosed. But if project 
> > A is only a client of `f`, it should be highly unlikely that project A has 
> > the //definition// of `f` in their tree, right? So people of A will not get 
> > the warning for that. Only what is part of the compilation process will be 
> > part of the analysis process.
> > 
> > Similarly to how 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity marked an inline comment as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:10
+
+void declaration(int Param, int Other); // NO-WARN: No chance to change this 
function.
+

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > whisperity wrote:
> > > > aaron.ballman wrote:
> > > > > I think this is a case where we could warn when the declaration is 
> > > > > outside of a system header (perhaps as an option).
> > > > > 
> > > > > Thinking about it a bit more, declarations and definitions provide a 
> > > > > novel way to get another kind of swap:
> > > > > ```
> > > > > void func(int x, int y);
> > > > > void func(int y, int x) {} // Oops, the swap was probably not 
> > > > > intentional
> > > > > ```
> > > > > which may or may not be interesting for a check (or its heuristics).
> > > > I gave this some thought. It is a very good idea, but I believe not for 
> > > > //this// check, but D20689. What do you think of that? Maybe simply 
> > > > saying "call site v. function node that was called" could be extended 
> > > > with a completely analogous, string distance function based "function 
> > > > definition node v. redecl chain" case.
> > > Hmmm, my impression is that this check is fundamentally about *parameter* 
> > > ordering whereas D20689 is about *argument* ordering. Given that the 
> > > example is about the ordering of parameters and doesn't have anything to 
> > > do with call sites, I kind of think the functionality would be better in 
> > > a parameter-oriented check.
> > > 
> > > That said, it doesn't feel entirely natural to add it to this check 
> > > because this check is about parameters that are easily swappable *at call 
> > > sites*, and this situation is not exactly that. However, it could 
> > > probably be argued that it is appropriate to add it to this check given 
> > > that swapped parameters between the declaration and the definition are 
> > > likely to result in swapped arguments at call sites.
> > > 
> > > Don't feel obligated to add this functionality to this check (or invent a 
> > > new check), though.
> > It just seems incredibly easier to put it into the other check, as that 
> > deals with names. But yes, then it would be a bit weird for the "suspicious 
> > call argument" check to say something about the definition... This check 
> > (and the relevant Core Guideline) was originally meant to consider **only** 
> > types (this is something I'll have to emphasise more in the research paper 
> > too!). Everything that considers //names// is only for making the check 
> > less noisy and make the actually emitted results more useful. However, I 
> > feel we should //specifically// not rely on the names and the logic too 
> > much.
> > 
> > But(!) your suggestion is otherwise a good idea. I am not sure if the 
> > previous research (with regards to names) consider the whole "forward 
> > declaration" situation, even where they did analysis for C projects, not 
> > just Java.
> > However, I feel we should specifically not rely on the names and the logic 
> > too much.
> 
> I agree, to a point. I don't think the basic check logic should be 
> name-sensitive, but I do think we need to rely on names to tweak the 
> true/false positive/negative ratios. I think most of the time when we're 
> relying on names should wind up being configuration options so that users can 
> tune the algorithm to their needs.
> 
> We could put the logic into the suspicious call argument check with roughly 
> the same logic -- the call site looks like it has potentially swapped 
> arguments because the function redeclaration chain (which includes the 
> function definition, as that's also a declaration) has inconsistent parameter 
> names. So long as the diagnostic appears on the call site, and then refers 
> back to the inconsistent declarations, it could probably work. However, I 
> think it'd be a bit strange to diagnose the call site because the user of the 
> API didn't really do anything wrong (and they may not even be able to change 
> the declaration or the definition where the problem really lives).
But wait... suppose there is a project A, which sees the header for `f(int x, 
int y)` and has a call `f(y, x)`. That will be diagnosed. But if project A is 
only a client of `f`, it should be highly unlikely that project A has the 
//definition// of `f` in their tree, right? So people of A will not get the 
warning for that. Only what is part of the compilation process will be part of 
the analysis process.

Similarly to how this check matches **only** function definitions, and never a 
prototype. The latter one would have bazillion of warnings from every header 
ever, with the user not having a chance to fix it anyways.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:10
+
+void declaration(int Param, int Other); // NO-WARN: No chance to change this 
function.
+

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > whisperity wrote:
> > > > aaron.ballman wrote:
> > > > > whisperity wrote:
> > > > > > aaron.ballman wrote:
> > > > > > > whisperity wrote:
> > > > > > > > aaron.ballman wrote:
> > > > > > > > > I think this is a case where we could warn when the 
> > > > > > > > > declaration is outside of a system header (perhaps as an 
> > > > > > > > > option).
> > > > > > > > > 
> > > > > > > > > Thinking about it a bit more, declarations and definitions 
> > > > > > > > > provide a novel way to get another kind of swap:
> > > > > > > > > ```
> > > > > > > > > void func(int x, int y);
> > > > > > > > > void func(int y, int x) {} // Oops, the swap was probably not 
> > > > > > > > > intentional
> > > > > > > > > ```
> > > > > > > > > which may or may not be interesting for a check (or its 
> > > > > > > > > heuristics).
> > > > > > > > I gave this some thought. It is a very good idea, but I believe 
> > > > > > > > not for //this// check, but D20689. What do you think of that? 
> > > > > > > > Maybe simply saying "call site v. function node that was 
> > > > > > > > called" could be extended with a completely analogous, string 
> > > > > > > > distance function based "function definition node v. redecl 
> > > > > > > > chain" case.
> > > > > > > Hmmm, my impression is that this check is fundamentally about 
> > > > > > > *parameter* ordering whereas D20689 is about *argument* ordering. 
> > > > > > > Given that the example is about the ordering of parameters and 
> > > > > > > doesn't have anything to do with call sites, I kind of think the 
> > > > > > > functionality would be better in a parameter-oriented check.
> > > > > > > 
> > > > > > > That said, it doesn't feel entirely natural to add it to this 
> > > > > > > check because this check is about parameters that are easily 
> > > > > > > swappable *at call sites*, and this situation is not exactly 
> > > > > > > that. However, it could probably be argued that it is appropriate 
> > > > > > > to add it to this check given that swapped parameters between the 
> > > > > > > declaration and the definition are likely to result in swapped 
> > > > > > > arguments at call sites.
> > > > > > > 
> > > > > > > Don't feel obligated to add this functionality to this check (or 
> > > > > > > invent a new check), though.
> > > > > > It just seems incredibly easier to put it into the other check, as 
> > > > > > that deals with names. But yes, then it would be a bit weird for 
> > > > > > the "suspicious call argument" check to say something about the 
> > > > > > definition... This check (and the relevant Core Guideline) was 
> > > > > > originally meant to consider **only** types (this is something I'll 
> > > > > > have to emphasise more in the research paper too!). Everything that 
> > > > > > considers //names// is only for making the check less noisy and 
> > > > > > make the actually emitted results more useful. However, I feel we 
> > > > > > should //specifically// not rely on the names and the logic too 
> > > > > > much.
> > > > > > 
> > > > > > But(!) your suggestion is otherwise a good idea. I am not sure if 
> > > > > > the previous research (with regards to names) consider the whole 
> > > > > > "forward declaration" situation, even where they did analysis for C 
> > > > > > projects, not just Java.
> > > > > > However, I feel we should specifically not rely on the names and 
> > > > > > the logic too much.
> > > > > 
> > > > > I agree, to a point. I don't think the basic check logic should be 
> > > > > name-sensitive, but I do think we need to rely on names to tweak the 
> > > > > true/false positive/negative ratios. I think most of the time when 
> > > > > we're relying on names should wind up being configuration options so 
> > > > > that users can tune the algorithm to their needs.
> > > > > 
> > > > > We could put the logic into the suspicious call argument check with 
> > > > > roughly the same logic -- the call site looks like it has potentially 
> > > > > swapped arguments because the function redeclaration chain (which 
> > > > > includes the function definition, as that's also a declaration) has 
> > > > > inconsistent parameter names. So long as the diagnostic appears on 
> > > > > the call site, and then refers back to the inconsistent declarations, 
> > > > > it could probably work. However, I think it'd be a bit strange to 
> > > > > diagnose the call site because the user of the API didn't really do 
> > > > > anything wrong (and they may not even be able to change the 
> > > > > declaration or the definition where the problem really lives).
> > > > But wait... suppose there is a project A, which sees the header 

[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:135
   void sanitize() {
-assert(Flags != MIX_Invalid && "sanitize() called on invalid bitvec");
-// TODO: There will be statements here in further extensions of the check.
+assert(Flags != MIX_Invalid && "sanitise() called on sentinel bitvec");
+

aaron.ballman wrote:
> 
How in the... Okay, I think I need to up my rebase game because I know for a 
fact that I fixed BrE to AmE in the parent patch and that patch was merged into 
the branch this patch was created from and this patch is created against the 
parent, obviously.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:240
+  // user to understand.
+  if (isa(LType.getTypePtr())) {
+LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. LHS is ParenType.\n");

aaron.ballman wrote:
> 
Is `const` respected properly in this case, will it not try to cast it away? 
Wow... I did not know this!



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:289-290
 
+/// Calculates if the reference binds an expression of the given type. This is
+/// true iff 'LRef' is some 'const T &' type, and the 'Ty' is 'T' or 'const T'.
+static MixData isLRefEquallyBindingToType(const TheCheck ,

aaron.ballman wrote:
> I think this is reasonable but it does raise a question about implicit 
> conversions, which I suppose is more of a generic question about the check. 
> Should the check consider these to be easily swappable parameter types?
> ```
> struct S {
>   S(int);
>   operator int() const;
> };
> 
> void func(S s, int i);
> ```
> given that you can call `func()` like:
> ```
> S s;
> int i;
> 
> func(i, s);
> func(s, i);
> ```
> (Also, does the answer change if `S` has more types it can convert to/from? 
> Or does the answer change if `S` can only convert from a type (or convert to 
> a type) rather than convert both ways?)
Yes, yes, yes and yes! That is the whole idea, that is one of the things in 
which we are "better" than the existing works... and one of the reasons behind 
this whole "argument swapping" deal is much worse in C++, than let's say Java. 
(A lot of existing literature deals with Java, or deals with C++ but only in 
terms of type equivalence, or not considering types -- only arg and param names 
-- at all.) That one shall be diagnosed, but the whole implicit conversion 
"mess" is coming in a later patch!
In fact, the patch for implicit conversions is already up, but in a //will be 
reworked// state.

Unfortunately, I can't seem to find a way to link a particular line of a 
particular diff, so let's do it manually. The `...-implicits.cpp` test file in 
D75041 [[ http://reviews.llvm.org/D75041?id=315384 | diff 315384 ]] starting 
from line 95 shows this being dealt with.

Originally, implicit conversions were warned about when they were only 
unidirectional (i.e. `int -> S` possible, `S -> int` not possible, `fn(int{}, 
S{})` warned). However, this created **a lot of** false positives even in the 
two or three projects I went over manually, so... for the time being, I 
reworked the patch (only changing like 2 lines at most!) to only deal with 
//bidirectional// implicit conversions. Because in case you say `fn(5, 5)` it 
still accepts, but if you have a //valid `s`//, `fn(s, 5)` is a compile error.
(You can check the [[ http://reviews.llvm.org/D75041?id=259324 | earlier diff 
]] at the same location for this case.)

This becomes a deep rabbit hole way too fast, because one layer of the analysis 
is //"warn about `f(T1, T2)` if `f(T2, T1)` is also possible"//. That's the 
idea I'm trying to sell right now. Saying //"warn about `f(T1, T2)` if there 
exists some type `Tx` with which `f(Tx, Tx)` is possible"// is a whooole lotta 
harder to handle. Maybe not impossible, but definitely harder, and with most 
likely introducing a plethora of weird false positives.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:289-290
 
+/// Calculates if the reference binds an expression of the given type. This is
+/// true iff 'LRef' is some 'const T &' type, and the 'Ty' is 'T' or 'const T'.
+static MixData isLRefEquallyBindingToType(const TheCheck ,

whisperity wrote:
> aaron.ballman wrote:
> > I think this is reasonable but it does raise a question about implicit 
> > conversions, which I suppose is more of a generic question about the check. 
> > Should the check consider these to be easily swappable parameter types?
> > ```
> > struct S {
> >   S(int);
> >   operator int() const;
> > };
> > 
> > void func(S s, int i);
> > ```
> > given that you can call `func()` like:
> > ```
> > S s;
> > int i;
> > 
> > func(i, s);
> > func(s, i);
> > ```
> > (Also, does the answer change if `S` has more types it can 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:402-403
+
+// Unfortunately, undersquiggly highlights are for some reason chewed up
+// and not respected by diagnostics from Clang-Tidy. :(
+diag(First->getLocation(), "the first parameter in the range is '%0'",

aaron.ballman wrote:
> whisperity wrote:
> > whisperity wrote:
> > > aaron.ballman wrote:
> > > > whisperity wrote:
> > > > > aaron.ballman wrote:
> > > > > > Can you post a screenshot of what you mean?
> > > > > Given
> > > > > 
> > > > > ```
> > > > > Diag << SourceRange{First->getSourceRange().getBegin(), 
> > > > > Last->getSourceRange().getEnd()};
> > > > > ```
> > > > > 
> > > > > The diagnostic is still produced with only a `^` at the original 
> > > > > `diag(Location)`, ignoring the fed `SourceRange`:
> > > > > 
> > > > > ```
> > > > > /home/whisperity/LLVM/Build/../llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:21:18:
> > > > >  warning: 3 adjacent parameters of 'redeclChain' of similar type 
> > > > > ('int') are easily swapped by mistake 
> > > > > [bugprone-easily-swappable-parameters]
> > > > > void redeclChain(int I, int J, int K) {}
> > > > >  ^
> > > > > ```
> > > > > 
> > > > > Instead of putting all the squigglies in as the range-location 
> > > > > highlight, like how `Sema` can diagnose:
> > > > > 
> > > > > ```
> > > > > /home/whisperity/LLVM/Build/../llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:21:18:
> > > > >  warning: 3 adjacent parameters of 'redeclChain' of similar type 
> > > > > ('int') are easily swapped by mistake 
> > > > > [bugprone-easily-swappable-parameters]
> > > > > void redeclChain(int I, int J, int K) {}
> > > > >  ^~~
> > > > > ```
> > > > > 
> > > > > I would not want to put additional note tags in an otherwise already 
> > > > > verbose output.
> > > > > 
> > > > > Back in 2019 I was investigating this issue specifically for another 
> > > > > checker I was working on, but hit the wall... Somewhere deep inside 
> > > > > where Tidy diagnostic stuff is translated and consumed to Clang 
> > > > > stuff, it goes away. It shouldn't, because there are statements that 
> > > > > seemingly copy the `Diag.Ranges` array over, but it still does not 
> > > > > come out.
> > > > > 
> > > > > ... EDIT: I found [[ 
> > > > > http://lists.llvm.org/pipermail/cfe-dev/2019-October/063676.html | 
> > > > > the relevant mailing list post ]].
> > > > > ... EDIT: I found the relevant mailing list post.
> > > > 
> > > > Oh wow, I had no idea! That's a rather unfortunate bug. :-(
> > > Speaking of bugs, shall I put it up on Bugzilla, or see if anyone 
> > > reported already? Would require me digging into that "where are the data 
> > > structures copied" kind of thing to figure it out again.
> > Nevermind, this is worth [[ http://bugzilla.llvm.org/show_bug.cgi?id=49000 
> > | a bug report ]] just so we can track it in the proper location.
> If you don't mind doing that effort, it'd be appreciated! Even if you don't 
> root cause the issue, having the report (or pinging an existing one) is still 
> useful.
And I managed to post a broken link originally... Here's the right one: 
https://bugs.llvm.org/show_bug.cgi?id=49000


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-02-02 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

(Typing this in here so it is not forgotten.) @aaron.ballman suggested in 
http://reviews.llvm.org/D69560#inline-893813 that a case of argument and 
parameter swaps could be discovered between forward declarations and the 
definitions, i.e.

  void fn(int x, int y);
  
  void fn(int y, int x) { ... } // Proparly mistakenly swapped names!

The conclusion was that this check (given this one does string distance, 
metrics, etc.) should be extended with such functionality. However, we need a 
better name for the check in that case!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353969.
whisperity marked 8 inline comments as done.
whisperity added a comment.

All changes are **NFC** and styling only.

- Remove the `FB` macro in favour of explicitly specifying the bit flag value
- Change debug printout from bit pattern to individual significant letters


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void 

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353978.
whisperity added a comment.

**NFC**: Rebase & update.

While this patch conceptually only depends on D69560 
, the diff itself has become linear during the 
code review and subsequent updates, and as such, must be applied on top of 
D75041 .


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -4,7 +4,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -0,0 +1,231 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN:  ]}' --
+
+namespace std {
+template 
+T max(const T , const T );
+} // namespace std
+
+bool coin();
+void f(int);
+void g(int);
+void h(int, int);
+void i(int, bool);
+void i(int, char);
+
+struct Tmp {
+  int f(int);
+  int g(int, int);
+};
+
+struct Int {
+  int I;
+};
+
+void compare(int Left, int Right) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'compare' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Left'
+// CHECK-MESSAGES: :[[@LINE-3]]:28: note: the last parameter in the range is 'Right'
+
+int decideSequence(int A, int B) {
+  if (A)
+return 1;
+  if (B)
+return 2;
+  return 3;
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:20: warning: 2 adjacent parameters of 'decideSequence' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-8]]:24: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-9]]:31: note: the last parameter in the range is 'B'
+
+int myMax(int A, int B) { // NO-WARN: Appears in same expression.
+  return A < B ? A : B;
+}
+
+int myMax2(int A, int B) { // NO-WARN: Appears in same expression.
+  if (A < B)
+return A;
+  return B;
+}
+
+int myMax3(int A, int B) { // NO-WARN: Appears in same expression.
+  return std::max(A, B);
+}
+
+int binaryToUnary(int A, int) {
+  

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D69560#2747092 , @alexfh wrote:

> BTW, any ideas why "patch application failed"? (See the Build status in the 
> Diff Detail section)

I think I figured out why the pre-build CI isn't working... it seems that the 
fact that this patch depends on an abandoned revision D76545 
 misleads the CI logic as it sees the 
dependency, and even though it is abandoned, tries to download and apply the 
contents of D76545 , which makes it fail...

  INFOD76545#251840 commit 1e9b6b89a7b5c49612018b120c2c142106056f82 has a 
later commit date then7cdbf1ed4b94259a3aad2a7575e928fa61b0e57e
  [...]
  ERROR   error: patch failed: clang-tools-extra/docs/clang-tidy/index.rst:62
  error: clang-tools-extra/docs/clang-tidy/index.rst: patch does not apply
  error: patch failed: clang-tools-extra/clang-tidy/ClangTidyForceLinker.h:15
  error: clang-tools-extra/clang-tidy/ClangTidyForceLinker.h: patch does not 
apply


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353972.
whisperity added a comment.

**NFC**: Rebase & update.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95736/new/

https://reviews.llvm.org/D95736

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -111,20 +111,38 @@
 // CHECK-MESSAGES: :[[@LINE-2]]:32: note: the first parameter in the range is 'I1'
 // CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'I2'
 
-void throughTypedef(int I, MyInt1 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'throughTypedef' of similar type ('int')
-// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:35: note: the last parameter in the range is 'J'
+void typedefMultiple(MyInt1 I1, MyInt2 I2x, MyInt2 I2y) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 adjacent parameters of 'typedefMultiple' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I1'
+// CHECK-MESSAGES: :[[@LINE-3]]:52: note: the last parameter in the range is 'I2y'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+void throughTypedef1(int I, MyInt1 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'throughTypedef1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:26: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+
+void betweenTypedef2(MyInt1 I, MyInt2 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'betweenTypedef2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:39: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+typedef MyInt2 MyInt2b;
 
-void betweenTypedef(MyInt1 I, MyInt2 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'betweenTypedef' of similar type ('MyInt1')
-// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:38: note: the last parameter in the range is 'J'
+void typedefChain(int I, MyInt1 MI1, MyInt2 MI2, MyInt2b MI2b) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 4 adjacent parameters of 'typedefChain' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:23: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:58: note: the last parameter in the range is 'MI2b'
+// CHECK-MESSAGES: :[[@LINE-4]]:19: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+// CHECK-MESSAGES: :[[@LINE-5]]:19: note: after resolving type aliases, 'int' and 'MyInt2' are the same
+// CHECK-MESSAGES: :[[@LINE-6]]:19: note: after resolving type aliases, 'int' and 'MyInt2b' are the same
 
 typedef long MyLong1;
 using MyLong2 = long;
 
-void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: Not the same type.
+void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: int and long.
 
 void qualified1(int I, const int CI) {} // NO-WARN: Not the same type.
 
@@ -138,18 +156,73 @@
 
 void qualifiedThroughTypedef1(int I, CInt CI) {} // NO-WARN: Not the same type.
 
-void qualifiedThroughTypedef2(CInt CI1, const int CI2) {} // NO-WARN: Not the same type.
-// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type ('CInt')
+void qualifiedThroughTypedef2(CInt CI1, const int CI2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type are
 // CHECK-MESSAGES: :[[@LINE-2]]:36: note: the first parameter in the range is 'CI1'
 // CHECK-MESSAGES: :[[@LINE-3]]:51: note: the last parameter in the range is 'CI2'
-
-void reference1(int I, int ) {} // NO-WARN: Not the same type.
-
-void reference2(int I, const int ) {} // NO-WARN: Not the same type.
-
-void reference3(int I, int &) {} // NO-WARN: Not the same type.
-
-void reference4(int I, const int &) {} // NO-WARN: Not the same type.
+// CHECK-MESSAGES: :[[@LINE-4]]:31: note: after resolving 

[PATCH] D97297: [clang-tidy] Suppress reports to patternedly named parameters in 'bugprone-easily-swappable-parameters'

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353979.
whisperity added a comment.

**NFC**: Rebase & update.

While this patch conceptually only depends on D69560 
, the diff itself has become linear during the 
code review and subsequent updates, and as such, must be applied on top of 
D78652 .


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97297/new/

https://reviews.llvm.org/D97297

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-prefixsuffixname.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' --
 
 namespace std {
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 int myprint();
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353975.
whisperity marked 5 inline comments as done.
whisperity added a comment.

**NFC**.

- Rebase and update for changes of base patch D69560 
.
- Remove the `<<=` and `%=` operators in favour of named functions.
- Elaborated the documentation for `ConversionSequence`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:34: note: the last parameter in the range is 'CI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const int' parameters accept and bind the same kind of values
+
+void qualified2(int I, volatile int VI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'VI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'volatile int' parameters accept and bind the same kind of values
+
+void qualified3(int I, const volatile int CVI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified3' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'CVI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const volatile int' parameters accept and bind the same kind of values
+
+void qualified4(int *IP, const int *CIP) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified4' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'CIP'
+// CHECK-MESSAGES: :[[@LINE-4]]:26: note: 'int *' and 'const int *' parameters accept and bind the same kind of values
+
+void qualified5(const int CI, const long CL) {} // NO-WARN: Not the same type
+

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353983.
whisperity added a comment.

(Try nudging the CI to only apply this commit after removal of parent links.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
+// Even though it is "_Bool" that is written in the code, the diagnostic message
+// respects the printing policy as defined by 

[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 353974.
whisperity added a comment.

**NFC**: Rebase & update.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96355/new/

https://reviews.llvm.org/D96355

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:34: note: the last parameter in the range is 'CI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const int' parameters accept and bind the same kind of values
+
+void qualified2(int I, volatile int VI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'VI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'volatile int' parameters accept and bind the same kind of values
+
+void qualified3(int I, const volatile int CVI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified3' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'CVI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const volatile int' parameters accept and bind the same kind of values
+
+void qualified4(int *IP, const int *CIP) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified4' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'CIP'
+// CHECK-MESSAGES: :[[@LINE-4]]:26: note: 'int *' and 'const int *' parameters accept and bind the same kind of values
+
+void qualified5(const int CI, const long CL) {} // NO-WARN: Not the same type
+
+void qualifiedPtr1(int *IP, int *const IPC) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 2 adjacent parameters of 'qualifiedPtr1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'IP'
+// 

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-23 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 2 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:657-667
+  // Certain kinds unfortunately need to be side-stepped for canonical type
+  // matching.
+  if (LType->getAs() || RType->getAs()) {
+// Unfortunately, the canonical type of a function pointer becomes the
+// same even if exactly one is "noexcept" and the other isn't, making us
+// give a false positive report irrespective of implicit conversions.
+LLVM_DEBUG(llvm::dbgs()

whisperity wrote:
> whisperity wrote:
> > martong wrote:
> > > aaron.ballman wrote:
> > > > whisperity wrote:
> > > > > @aaron.ballman Getting ahead of the curve here. I understand this is 
> > > > > ugly. Unfortunately, no matter how much I read the standard, I don't 
> > > > > get anything of "canonical type" mentioned, it seems to me this 
> > > > > concept is something inherent to the model of Clang.
> > > > > 
> > > > > Basically why this is here: imagine a `void (*)() noexcept` and a 
> > > > > `void (*)()`. One's `noexcept`, the other isn't. Inside the AST, this 
> > > > > is a `ParenType` of a `PointerType` to a `FunctionProtoType`. There 
> > > > > exists a //one-way// implicit conversion from the `noexcept` to the 
> > > > > non-noexcept ("noexceptness can be discarded", similarly to how 
> > > > > "constness can be gained")
> > > > > Unfortunately, because this is a one-way implicit conversion, it 
> > > > > won't return on the code path earlier for implicit conversions.
> > > > > 
> > > > > Now because of this, the recursive descent in our code will reach the 
> > > > > point when the two innermost `FunctionProtoType`s are in our hands. 
> > > > > As a fallback case, we simply ask Clang "Hey, do //you// think these 
> > > > > two are the same?". And for some weird reason, Clang will say 
> > > > > "Yes."... While one of them is a `noexcept` function and the other 
> > > > > one isn't.
> > > > > 
> > > > > I do not know the innards of the AST well enough to even have a 
> > > > > glimpse of whether or not this is a bug. So that's the reason why I 
> > > > > went ahead and implemented this side-stepping logic. Basically, as 
> > > > > the comment says, it'lll **force** the information of "No matter what 
> > > > > you do, do NOT consider these mixable!" back up the recursion chain, 
> > > > > and handle it appropriately later.
> > > > > Unfortunately, no matter how much I read the standard, I don't get 
> > > > > anything of "canonical type" mentioned, it seems to me this concept 
> > > > > is something inherent to the model of Clang.
> > > > 
> > > > It is more of a Clang-centric concept. Basically, a canonical type is 
> > > > one that's had all of the typedefs stripped off it.
> > > > 
> > > > > Now because of this, the recursive descent in our code will reach the 
> > > > > point when the two innermost FunctionProtoTypes are in our hands. As 
> > > > > a fallback case, we simply ask Clang "Hey, do you think these two are 
> > > > > the same?". And for some weird reason, Clang will say "Yes."... While 
> > > > > one of them is a noexcept function and the other one isn't.
> > > > 
> > > > I think a confounding factor in this area is that `noexcept` did not 
> > > > used to be part of the function type until one day it started being a 
> > > > part of the function type. So my guess is that this is fallout from 
> > > > this sort of thing: https://godbolt.org/z/EYfj8z (which may be worth 
> > > > keeping in mind when working on the check).
> > > About `noexcept`: we've faced a similar problem in the `ASTImporter` 
> > > library. We could not import a noexcept function's definition if we 
> > > already had one without the noexcept specifier. 
> > > 
> > > Thus, in `ASTStructuralEquivalence.cpp` we do differentiate the function 
> > > types based on their noexcept specifier (and we even check the noexcept 
> > > expression).:
> > > ```
> > > TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
> > >   auto t = makeNamedDecls("void foo();",
> > >   "void foo() noexcept;", Lang_CXX11);
> > >   EXPECT_FALSE(testStructuralMatch(t));
> > > }
> > > TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
> > >   auto t = makeNamedDecls("void foo() noexcept(false);",
> > >   "void foo() noexcept(true);", Lang_CXX11);
> > >   EXPECT_FALSE(testStructuralMatch(t));
> > > }
> > > ```
> > > 
> > > May be in these special cases it would worth to reuse the 
> > > ASTStructuralEquivalenceContext class?
> > Definitely, good catch, @martong, thank you very much! @aaron.ballman, what 
> > do you think? If I see this right, `StructuralEquivalenceContext` is part 
> > of `libClangAST` so should be readily available.
> > 
> > The only issue I'm seeing is that this class takes non-**`const`** 
> > `ASTContext` and `Decl` nodes...
> Well, I started looking into putting up 

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354218.
whisperity added a comment.

**NC** Rebase & more buildbot shenanigans so we can get a pass!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -4,7 +4,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -0,0 +1,231 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN:  ]}' --
+
+namespace std {
+template 
+T max(const T , const T );
+} // namespace std
+
+bool coin();
+void f(int);
+void g(int);
+void h(int, int);
+void i(int, bool);
+void i(int, char);
+
+struct Tmp {
+  int f(int);
+  int g(int, int);
+};
+
+struct Int {
+  int I;
+};
+
+void compare(int Left, int Right) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'compare' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Left'
+// CHECK-MESSAGES: :[[@LINE-3]]:28: note: the last parameter in the range is 'Right'
+
+int decideSequence(int A, int B) {
+  if (A)
+return 1;
+  if (B)
+return 2;
+  return 3;
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:20: warning: 2 adjacent parameters of 'decideSequence' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-8]]:24: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-9]]:31: note: the last parameter in the range is 'B'
+
+int myMax(int A, int B) { // NO-WARN: Appears in same expression.
+  return A < B ? A : B;
+}
+
+int myMax2(int A, int B) { // NO-WARN: Appears in same expression.
+  if (A < B)
+return A;
+  return B;
+}
+
+int myMax3(int A, int B) { // NO-WARN: Appears in same expression.
+  return std::max(A, B);
+}
+
+int binaryToUnary(int A, int) {
+  return A;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: 2 adjacent parameters of 'binaryToUnary' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:23: note: the first parameter in the range is 'A'
+// 

[PATCH] D90399: [clang-tidy] non-portable-integer-constant check

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.
Herald added a subscriber: cfe-commits.



Comment at: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp:38
 #include "NoEscapeCheck.h"
+#include "NonportableintegerconstantCheck.h"
 #include "NotNullTerminatedResultCheck.h"

aaron.ballman wrote:
> Please use PascalCase for this -- `NonPortableIntegerConstantCheck.h`  (be 
> sure to change the actual case of the files being added in addition to the 
> include directives)
> Please use PascalCase for this -- `NonPortableIntegerConstantCheck.h`  (be 
> sure to change the actual case of the files being added in addition to the 
> include directives)





Comment at: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp:124
 "bugprone-multiple-statement-macro");
+CheckFactories.registerCheck(
+"bugprone-non-portable-integer-constant");

> Please use PascalCase for this -- `NonPortableIntegerConstantCheck.h`  (be 
> sure to change the actual case of the files being added in addition to the 
> include directives)

Not just for the filename, but for the class's name as well, everywhere.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/NonportableintegerconstantCheck.cpp:21-23
+/// The mask is problematic if:
+/// - The highest bit is set and everything else are zeroes, for example: 
`0x8000`.
+/// - All the bits are set to one, for example: `0x`.





Comment at: 
clang-tools-extra/clang-tidy/bugprone/NonportableintegerconstantCheck.cpp:24-38
+bool isProblematicMask(StringRef HexNumber) {
+
+ // Check whether only the highest bit is set.
+  if (HexNumber[0] == '8' && HexNumber[1] == '0') {
+// Consume the first non-zero.
+HexNumber = HexNumber.drop_front();
+// Consume all the left zeroes.

C++17 introduced binary literals, i.e. `0b1100`, which could also be used 
for masking operations. I suggest creating two functions `isUnsafeHexMask()` 
and `isUnsafeBinMask()` and a wrapper function that calls both(?), and 
supporting finding literals like `0b1000` and `0b`.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/NonportableintegerconstantCheck.cpp:30
+HexNumber = HexNumber.drop_front();
+// Consume all the left zeroes.
+HexNumber = HexNumber.drop_while([](char C) { return C == '0'; });





Comment at: 
clang-tools-extra/clang-tidy/bugprone/NonportableintegerconstantCheck.cpp:41
+void NonportableintegerconstantCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(integerLiteral().bind("integer"), this);
+}

aaron.ballman wrote:
> I'm a bit worried about the performance of this check given that it's going 
> to make a function call on every single integer literal anywhere in the 
> program. I'd be curious to know how this check performs compared to other 
> checks in the bugprone module.
I did a quick skim and it seems there is plenty of `integerLiteral(` matches 
used here and there, but most of them seem to either do an `equal(0)` or 
`equal(1)` sub-matching first. If performance is a concern, I think we could do 
an `unless(equal(0))`-like construct, given that no pattern that we try to 
check may match a literal 0.

(Although if we dig deeper into the maths, maybe we can come up with a better 
lower bound?)



Comment at: 
clang-tools-extra/clang-tidy/bugprone/NonportableintegerconstantCheck.cpp:63-64
+
+diag(MatchedInt->getBeginLoc(),
+ "integer is being used in a non-portable manner ");
+  }

This message is misleading. It should emphasise that it looks like a bit mask, 
and given that the CERT rule suggests portable ways (`-1` instead of `0x` 
and `~(MAX >> 1)` instead of `0x8000`), this check should be able to produce 
//FixIt//s based off of that.



Comment at: clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp:106-108
+// INT
+CheckFactories.registerCheck(
+"cert-int17-c");

This is a C-specific check, or does it apply to C++ too? If only applies to C, 
it should be disabled in C++ mode, if it applies to C++, is there a 
C++-specific CERT rule/tag/number/ID for that version?



Comment at: clang-tools-extra/docs/ReleaseNotes.rst:115-117
+  ` check.   
+  
+  Finds masks that are being used in a non-portable manner.

The name of the check versus the one-liner summary doesn't really match up.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90399/new/

https://reviews.llvm.org/D90399

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354210.
whisperity added a comment.

**NC** Rebase, buildbots, etc.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 typedef int MyInt1;
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 3}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 int add(int Left, int Right) { return Left + Right; } // NO-WARN: Only 2 parameters.
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: 

[PATCH] D97297: [clang-tidy] Suppress reports to patternedly named parameters in 'bugprone-easily-swappable-parameters'

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354229.
whisperity added a comment.

**NC** Rebase and buildbot trigger.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97297/new/

https://reviews.llvm.org/D97297

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-prefixsuffixname.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' --
 
 namespace std {
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 int myprint();
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
+++ 

[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354203.
whisperity added a comment.

**NC** Fix lint mishap that occurred during previous rebase.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96355/new/

https://reviews.llvm.org/D96355

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:34: note: the last parameter in the range is 'CI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const int' parameters accept and bind the same kind of values
+
+void qualified2(int I, volatile int VI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'VI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'volatile int' parameters accept and bind the same kind of values
+
+void qualified3(int I, const volatile int CVI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified3' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'CVI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const volatile int' parameters accept and bind the same kind of values
+
+void qualified4(int *IP, const int *CIP) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified4' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'CIP'
+// CHECK-MESSAGES: :[[@LINE-4]]:26: note: 'int *' and 'const int *' parameters accept and bind the same kind of values
+
+void qualified5(const int CI, const long CL) {} // NO-WARN: Not the same type
+
+void qualifiedPtr1(int *IP, int *const IPC) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 2 adjacent parameters of 'qualifiedPtr1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first 

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-06-25 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354467.
whisperity added a comment.

**NFC** Rebase and fix things broken by D104819 
.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,477 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+void foo_8(int frobble1, int frobble2) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test cases for multilevel pointers.
+void multilevel_pointer_parameters(int *const **pp,
+   const int *const *volatile const *qq);
+void multilevel_pointer_parameters2(
+char *nn, char *volatile *const *const *const *const );
+
+typedef float T;
+typedef T *S;
+typedef S *const volatile R;
+typedef R *Q;
+typedef Q *P;
+typedef P *O;
+void multilevel_pointer_parameters3(float **const volatile ***rr, O );
+
+void multilevel_pointer_swap() {
+  int *const **qq;
+  int *const **pp;
+  multilevel_pointer_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+
+  char *mm;
+  char *nn;
+  multilevel_pointer_parameters2(mm, 

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-25 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354478.
whisperity marked 5 inline comments as done.
whisperity added a comment.

**NFC** Fix nits.

Let's have one final run with the buildbots, just in case.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 typedef int MyInt1;
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 3}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 int add(int Left, int Right) { return Left + Right; } // NO-WARN: Only 2 parameters.
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: 

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-25 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:249
+  /// the conversion sequence. This method does **NOT** return Begin and End.
+  SmallVector getInvolvedTypesInSequence() const {
+SmallVector Ret;

aaron.ballman wrote:
> Return a `SmallVectorImpl` so that the size of the vector doesn't 
> matter to callers?
Meh... that seems to only work if the context is polymorphic, like reference 
parameters or pointers... This tries to return by value and construct, which is 
not possible for `Impl`.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-25 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D69560#2840554 , @aaron.ballman 
wrote:

> This is a very involved check that I think is going to produce some 
> interesting results for users, thank you for working so diligently on it! I 
> think all of the patches in the series have now been accepted and this is 
> ready to land. @whisperity, are you aware of any changes that are left to be 
> made?

I'll ping @martong privately if they have additional comments about D75041 
, but otherwise, no, I think no more things 
left to do. Landing checklist complete.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-05-10 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D69560#2747092 , @alexfh wrote:

> BTW, any ideas why "patch application failed"? (See the Build status in the 
> Diff Detail section)
>
> It would be really nice to get pre-merge checks to work for the patch.

Put simply, I think I haven't rebased the patch since a few changes ago. The 
past few changes were NFC/lint stuff only.




Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:113-120
+#define FB(Name, K) MIX_##Name = (1ull << (K##ull - 1ull))
+
+  FB(None, 1),  //< Mix between the two parameters is not possible.
+  FB(Trivial, 2),   //< The two mix trivially, and are the exact same type.
+  FB(Canonical, 3), //< The two mix because the types refer to the same
+// CanonicalType, but we do not elaborate as to how.
+

alexfh wrote:
> I'd switch to scoped enums (`enum class`), remove the macro, and use simpler 
> code like `None = 0x1, Trivial = 0x2, Canonical = 0x4`, etc.
`enum class` is a good idea!

Unfortunately, I'm not really sold on the hexa literals... It makes the code 
confusing the read, because you have to keep in mind which range the hexa 
literals mean, and when there is a shift in position, e.g. if you read `0x20` 
you have to count out that okay, that's 2nd position, so at least 16, so at 
least the 4th bit, but it is two, so you shift it again to the right, so in the 
bit pattern it turns on the 5th bit actually.
It makes it very easy to misread or misinterpret things, especially when trying 
to work on the source code.
(In the last extension patch, the number of elements in the bit mask go up to 
the 8th or the 9th bit, I don't remember exactly at the top of my head.)

Compared to this, the current text when read immediately tells you which 
"decimal" position you should expect the appropriate bit to be toggled on, if 
the flag is there.

Binary literals, on the other hand, would be amazing to use here, sadly we're 
only in C++14.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:133
+
+  void sanitize() {
+assert(Flags != MIX_Invalid && "sanitize() called on invalid bitvec");

alexfh wrote:
> What should this method do and how it should be used? Same for Mix::sanitize()
Once there are more flags in the bitmask (not just "None" and "Trivial"), this 
method deals with sanitising the flags that are toggled on and off by the 
recursive descent on the type tree.

For example, if there is a typedef involved (see D95736), it will toggle on the 
typedef flag, and start investigating the aliased type. This subsequent 
investigation might figure out that the aliased type is trivial, or it is 
distinct. In case it is distinct, that level of the recursion will turn on the 
"Not mixable" flag. In this case, when the investigation returns completely, we 
will have "Typedef" and "None" both turned on. This method will throw away 
everything but the "None" bit, so when the data is returned to the 
diagnostic-generating part of the check, it will know what to do.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:313-320
+if (B.isMacroID()) {
+  LLVM_DEBUG(llvm::dbgs() << "\t\tBeginning is macro.\n");
+  B = SM.getTopMacroCallerLoc(B);
+}
+if (E.isMacroID()) {
+  LLVM_DEBUG(llvm::dbgs() << "\t\tEnding is macro.\n");
+  E = Lexer::getLocForEndOfToken(SM.getTopMacroCallerLoc(E), 0, SM, LO);

alexfh wrote:
> Is there a chance that you're trying to reimplement a part of 
> Lexer::makeFileCharRange functionality here?
Does that expand the token length properly? I took this idiom of 
`getLocForEndOfToken` from various other Tidy checks... basically, anything 
that deals with replacing some sort of textual range in the code calls to this 
function. I need to have the exact ending location so I can obtain the full 
text, as appears in the source file. In this case, to compare against the 
user's input.

E.g. here is one example from `utils/UsingInserter.cpp`:

```
  32   │ Optional UsingInserter::createUsingDeclaration(
  33   │ ASTContext , const Stmt , StringRef 
QualifiedName) {
/* ... */
  42   │   SourceLocation InsertLoc = Lexer::getLocForEndOfToken(
  43   │   Function->getBody()->getBeginLoc(), 0, SourceMgr, 
Context.getLangOpts());
```

A quick grep for `makeCharRange` in the repository didn't turn up any 
significant result, apart from one unit test.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:129
+
+void qualified1(int I, const int CI) {} // NO-WARN: Not the same type.
+

alexfh wrote:
> Does the top-level const change anything with regard to the "mixability"? 
> It's a purely implementation-side difference, callers could still swap 
> parameters.
Unfortunately, 

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-03 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:657-667
+  // Certain kinds unfortunately need to be side-stepped for canonical type
+  // matching.
+  if (LType->getAs() || RType->getAs()) {
+// Unfortunately, the canonical type of a function pointer becomes the
+// same even if exactly one is "noexcept" and the other isn't, making us
+// give a false positive report irrespective of implicit conversions.
+LLVM_DEBUG(llvm::dbgs()

martong wrote:
> aaron.ballman wrote:
> > whisperity wrote:
> > > @aaron.ballman Getting ahead of the curve here. I understand this is 
> > > ugly. Unfortunately, no matter how much I read the standard, I don't get 
> > > anything of "canonical type" mentioned, it seems to me this concept is 
> > > something inherent to the model of Clang.
> > > 
> > > Basically why this is here: imagine a `void (*)() noexcept` and a `void 
> > > (*)()`. One's `noexcept`, the other isn't. Inside the AST, this is a 
> > > `ParenType` of a `PointerType` to a `FunctionProtoType`. There exists a 
> > > //one-way// implicit conversion from the `noexcept` to the non-noexcept 
> > > ("noexceptness can be discarded", similarly to how "constness can be 
> > > gained")
> > > Unfortunately, because this is a one-way implicit conversion, it won't 
> > > return on the code path earlier for implicit conversions.
> > > 
> > > Now because of this, the recursive descent in our code will reach the 
> > > point when the two innermost `FunctionProtoType`s are in our hands. As a 
> > > fallback case, we simply ask Clang "Hey, do //you// think these two are 
> > > the same?". And for some weird reason, Clang will say "Yes."... While one 
> > > of them is a `noexcept` function and the other one isn't.
> > > 
> > > I do not know the innards of the AST well enough to even have a glimpse 
> > > of whether or not this is a bug. So that's the reason why I went ahead 
> > > and implemented this side-stepping logic. Basically, as the comment says, 
> > > it'lll **force** the information of "No matter what you do, do NOT 
> > > consider these mixable!" back up the recursion chain, and handle it 
> > > appropriately later.
> > > Unfortunately, no matter how much I read the standard, I don't get 
> > > anything of "canonical type" mentioned, it seems to me this concept is 
> > > something inherent to the model of Clang.
> > 
> > It is more of a Clang-centric concept. Basically, a canonical type is one 
> > that's had all of the typedefs stripped off it.
> > 
> > > Now because of this, the recursive descent in our code will reach the 
> > > point when the two innermost FunctionProtoTypes are in our hands. As a 
> > > fallback case, we simply ask Clang "Hey, do you think these two are the 
> > > same?". And for some weird reason, Clang will say "Yes."... While one of 
> > > them is a noexcept function and the other one isn't.
> > 
> > I think a confounding factor in this area is that `noexcept` did not used 
> > to be part of the function type until one day it started being a part of 
> > the function type. So my guess is that this is fallout from this sort of 
> > thing: https://godbolt.org/z/EYfj8z (which may be worth keeping in mind 
> > when working on the check).
> About `noexcept`: we've faced a similar problem in the `ASTImporter` library. 
> We could not import a noexcept function's definition if we already had one 
> without the noexcept specifier. 
> 
> Thus, in `ASTStructuralEquivalence.cpp` we do differentiate the function 
> types based on their noexcept specifier (and we even check the noexcept 
> expression).:
> ```
> TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
>   auto t = makeNamedDecls("void foo();",
>   "void foo() noexcept;", Lang_CXX11);
>   EXPECT_FALSE(testStructuralMatch(t));
> }
> TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
>   auto t = makeNamedDecls("void foo() noexcept(false);",
>   "void foo() noexcept(true);", Lang_CXX11);
>   EXPECT_FALSE(testStructuralMatch(t));
> }
> ```
> 
> May be in these special cases it would worth to reuse the 
> ASTStructuralEquivalenceContext class?
Definitely, good catch, @martong, thank you very much! @aaron.ballman, what do 
you think? If I see this right, `StructuralEquivalenceContext` is part of 
`libClangAST` so should be readily available.

The only issue I'm seeing is that this class takes non-**`const`** `ASTContext` 
and `Decl` nodes...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-03 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:657-667
+  // Certain kinds unfortunately need to be side-stepped for canonical type
+  // matching.
+  if (LType->getAs() || RType->getAs()) {
+// Unfortunately, the canonical type of a function pointer becomes the
+// same even if exactly one is "noexcept" and the other isn't, making us
+// give a false positive report irrespective of implicit conversions.
+LLVM_DEBUG(llvm::dbgs()

whisperity wrote:
> martong wrote:
> > aaron.ballman wrote:
> > > whisperity wrote:
> > > > @aaron.ballman Getting ahead of the curve here. I understand this is 
> > > > ugly. Unfortunately, no matter how much I read the standard, I don't 
> > > > get anything of "canonical type" mentioned, it seems to me this concept 
> > > > is something inherent to the model of Clang.
> > > > 
> > > > Basically why this is here: imagine a `void (*)() noexcept` and a `void 
> > > > (*)()`. One's `noexcept`, the other isn't. Inside the AST, this is a 
> > > > `ParenType` of a `PointerType` to a `FunctionProtoType`. There exists a 
> > > > //one-way// implicit conversion from the `noexcept` to the non-noexcept 
> > > > ("noexceptness can be discarded", similarly to how "constness can be 
> > > > gained")
> > > > Unfortunately, because this is a one-way implicit conversion, it won't 
> > > > return on the code path earlier for implicit conversions.
> > > > 
> > > > Now because of this, the recursive descent in our code will reach the 
> > > > point when the two innermost `FunctionProtoType`s are in our hands. As 
> > > > a fallback case, we simply ask Clang "Hey, do //you// think these two 
> > > > are the same?". And for some weird reason, Clang will say "Yes."... 
> > > > While one of them is a `noexcept` function and the other one isn't.
> > > > 
> > > > I do not know the innards of the AST well enough to even have a glimpse 
> > > > of whether or not this is a bug. So that's the reason why I went ahead 
> > > > and implemented this side-stepping logic. Basically, as the comment 
> > > > says, it'lll **force** the information of "No matter what you do, do 
> > > > NOT consider these mixable!" back up the recursion chain, and handle it 
> > > > appropriately later.
> > > > Unfortunately, no matter how much I read the standard, I don't get 
> > > > anything of "canonical type" mentioned, it seems to me this concept is 
> > > > something inherent to the model of Clang.
> > > 
> > > It is more of a Clang-centric concept. Basically, a canonical type is one 
> > > that's had all of the typedefs stripped off it.
> > > 
> > > > Now because of this, the recursive descent in our code will reach the 
> > > > point when the two innermost FunctionProtoTypes are in our hands. As a 
> > > > fallback case, we simply ask Clang "Hey, do you think these two are the 
> > > > same?". And for some weird reason, Clang will say "Yes."... While one 
> > > > of them is a noexcept function and the other one isn't.
> > > 
> > > I think a confounding factor in this area is that `noexcept` did not used 
> > > to be part of the function type until one day it started being a part of 
> > > the function type. So my guess is that this is fallout from this sort of 
> > > thing: https://godbolt.org/z/EYfj8z (which may be worth keeping in mind 
> > > when working on the check).
> > About `noexcept`: we've faced a similar problem in the `ASTImporter` 
> > library. We could not import a noexcept function's definition if we already 
> > had one without the noexcept specifier. 
> > 
> > Thus, in `ASTStructuralEquivalence.cpp` we do differentiate the function 
> > types based on their noexcept specifier (and we even check the noexcept 
> > expression).:
> > ```
> > TEST_F(StructuralEquivalenceFunctionTest, Noexcept) {
> >   auto t = makeNamedDecls("void foo();",
> >   "void foo() noexcept;", Lang_CXX11);
> >   EXPECT_FALSE(testStructuralMatch(t));
> > }
> > TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
> >   auto t = makeNamedDecls("void foo() noexcept(false);",
> >   "void foo() noexcept(true);", Lang_CXX11);
> >   EXPECT_FALSE(testStructuralMatch(t));
> > }
> > ```
> > 
> > May be in these special cases it would worth to reuse the 
> > ASTStructuralEquivalenceContext class?
> Definitely, good catch, @martong, thank you very much! @aaron.ballman, what 
> do you think? If I see this right, `StructuralEquivalenceContext` is part of 
> `libClangAST` so should be readily available.
> 
> The only issue I'm seeing is that this class takes non-**`const`** 
> `ASTContext` and `Decl` nodes...
Well, I started looking into putting up `const` whereever possible into the 
aforementioned type, but I hit a hurdle. When checking equivalence of records, 
the algorithm tries to ASTImport-complete the definition of a record if it's 
not fully defined yet... which is 

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-03 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:122
 
 #define FB(Name, K) MIX_##Name = (1ull << (K##ull - 1ull))
 

martong wrote:
> FB stands for FunnyBitmask? Could you please either describe that in a 
> comment or just spell it out?
FlagBit. @alexfh suggested in the base check to use hexa literals. I'm not too 
sold about that, but maybe we can cut the macro out and keep the bit shift 
instructions in. Given that the check has more or less earned its final form 
(for now), we know how many bits we need!



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:182
+  /// The intermediate type after the first Standard Conversion Sequence.
+  QualType AfterPreStd;
+

martong wrote:
> Maybe it's just me, but AfterPre sounds ambiguous and AfterPost seems 
> redundant.
Should I use "AfterFirstStandard" or "AfterFirstStd"?

AfterPost isn't redundant. An implicit conversion sequence might be of **3 
steps**. Consider in a hypothetical `void f(Complex x, const double d)`.

`Complex` ---(PRE: std qual adjustment)--> `const Complex` ---(UD: user defined 
conv)--> `double` ---(POST: std qual adjustment)--> `const double`

And because in case of many conversions a lot of combinations need to be 
checked, we can't have `AfterPost` be the same as `End`. First, because of the 
combinations, second, because of the //other// things the check is doing.

`void g(ComplexTypedef CT, ConstDoubleTypedef CDT);`

In this case, `Start` and `End` are the typedefs, and the inner sequence is the 
same as before. And in order to generate the diagnostic, we also need to have 
**both** pieces of information.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:210
+  /// the conversion sequence. This method does **NOT** return Begin and End.
+  SmallVector getInvolvedTypesInSequence() const {
+SmallVector Ret;

martong wrote:
> So, we can never return with a vector with size > 4?
`N` in `SmallVector` only specifies the pre-allocated smallness size. 
AFAIK, if you have >N elements, it will just put the vector out onto the heap.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h:42
 
-  /// Whether to consider an unqualified and a qualified type mixable.
+  /// Whether to consider differently qualified versions of the same type
+  /// mixable.

martong wrote:
> "qualified"
> Do you consider `volatile` here as well, or just `const`?
Const, volatile, and in C mode, restrict, too.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76287: [analysis][analyzer] Introduce the skeleton of a reaching definitions calculator

2021-06-03 Thread Whisperity via Phabricator via cfe-commits
whisperity resigned from this revision.
whisperity added a comment.
Herald added a subscriber: manas.

What about this patch? I'm removing my reviewer bit just so it doesn't appear 
in my list anymore, but if there are any updates, I'll keep myself as a 
subscriber. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76287/new/

https://reviews.llvm.org/D76287

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-03 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

There was a bit of talk on Twitter recently about strong typing which reminded 
me of this checker!  I'll fix all issues in one go once we're through with all 
the comments, I'd like to see the full picture of what needs to be done.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-04 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 5 inline comments as done.
whisperity added a comment.

In D75041#2799023 , @martong wrote:

> Perhaps all conversion related logic should go into their own implementation 
> file? Seems like it adds up to roughly 1000 lines.

That's against the usual conventions of the project (1 TU for 1 check 
implementation). The methods are grouped by namespace, you can fold it up in 
your editor.




Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:550-551
+  if (isUselessSugar(LType.getTypePtr())) {
+LLVM_DEBUG(llvm::dbgs()
+   << "--- calculateMixability. LHS is useless sugar.\n");
 return calculateMixability(Check, LType.getSingleStepDesugaredType(Ctx),

martong wrote:
> Is this still WIP or do you use the DEBUG printouts in the tests? If not then 
> could you please create a Diff without the DEBUG printouts, that could 
> increase readability and ease the review.
As discussed earlier (and perhaps in the previous patches), these debug 
printouts are needed and shall stay here. The output is not used //in 
automation//, but it's intended for people who might pick up on further 
developing the check later. The recursive descent is too complex to be 
handleable in your mind without the debug information.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-05-31 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

Bump.  This is the last part that's still unreviewed and also the most complex.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354180.
whisperity added a comment.

(Uploaded the prerequisite, wrong patch here by accident.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 typedef int MyInt1;
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 3}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 int add(int Left, int Right) { return Left + Right; } // NO-WARN: Only 2 parameters.
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354166.
whisperity added a comment.

Attempt to fix build failure on Windows buildbot (`operator new` was taking 
`unsigned long` instead of `size_t` in a test which resulted in hard error).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
+// Even though it is "_Bool" that is written in the 

[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354183.
whisperity added a comment.

**NFC** Fix lint.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95736/new/

https://reviews.llvm.org/D95736

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -115,20 +115,38 @@
 // CHECK-MESSAGES: :[[@LINE-2]]:32: note: the first parameter in the range is 'I1'
 // CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'I2'
 
-void throughTypedef(int I, MyInt1 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'throughTypedef' of similar type ('int')
-// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:35: note: the last parameter in the range is 'J'
+void typedefMultiple(MyInt1 I1, MyInt2 I2x, MyInt2 I2y) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 adjacent parameters of 'typedefMultiple' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I1'
+// CHECK-MESSAGES: :[[@LINE-3]]:52: note: the last parameter in the range is 'I2y'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+void throughTypedef1(int I, MyInt1 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'throughTypedef1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:26: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+
+void betweenTypedef2(MyInt1 I, MyInt2 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'betweenTypedef2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:39: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+typedef MyInt2 MyInt2b;
 
-void betweenTypedef(MyInt1 I, MyInt2 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'betweenTypedef' of similar type ('MyInt1')
-// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:38: note: the last parameter in the range is 'J'
+void typedefChain(int I, MyInt1 MI1, MyInt2 MI2, MyInt2b MI2b) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 4 adjacent parameters of 'typedefChain' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:23: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:58: note: the last parameter in the range is 'MI2b'
+// CHECK-MESSAGES: :[[@LINE-4]]:19: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+// CHECK-MESSAGES: :[[@LINE-5]]:19: note: after resolving type aliases, 'int' and 'MyInt2' are the same
+// CHECK-MESSAGES: :[[@LINE-6]]:19: note: after resolving type aliases, 'int' and 'MyInt2b' are the same
 
 typedef long MyLong1;
 using MyLong2 = long;
 
-void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: Not the same type.
+void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: int and long.
 
 void qualified1(int I, const int CI) {} // NO-WARN: Not the same type.
 
@@ -142,18 +160,73 @@
 
 void qualifiedThroughTypedef1(int I, CInt CI) {} // NO-WARN: Not the same type.
 
-void qualifiedThroughTypedef2(CInt CI1, const int CI2) {} // NO-WARN: Not the same type.
-// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type ('CInt')
+void qualifiedThroughTypedef2(CInt CI1, const int CI2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type are
 // CHECK-MESSAGES: :[[@LINE-2]]:36: note: the first parameter in the range is 'CI1'
 // CHECK-MESSAGES: :[[@LINE-3]]:51: note: the last parameter in the range is 'CI2'
-
-void reference1(int I, int ) {} // NO-WARN: Not the same type.
-
-void reference2(int I, const int ) {} // NO-WARN: Not the same type.
-
-void reference3(int I, int &) {} // NO-WARN: Not the same type.
-
-void reference4(int I, const int &) {} // NO-WARN: Not the same type.
+// CHECK-MESSAGES: :[[@LINE-4]]:31: note: after resolving type 

[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354192.
whisperity added a comment.

**NC!** Recreate diff to try and get the buildbots running...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96355/new/

https://reviews.llvm.org/D96355

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:34: note: the last parameter in the range is 'CI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const int' parameters accept and bind the same kind of values
+
+void qualified2(int I, volatile int VI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'VI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'volatile int' parameters accept and bind the same kind of values
+
+void qualified3(int I, const volatile int CVI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified3' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'CVI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const volatile int' parameters accept and bind the same kind of values
+
+void qualified4(int *IP, const int *CIP) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified4' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'CIP'
+// CHECK-MESSAGES: :[[@LINE-4]]:26: note: 'int *' and 'const int *' parameters accept and bind the same kind of values
+
+void qualified5(const int CI, const long CL) {} // NO-WARN: Not the same type
+
+void qualifiedPtr1(int *IP, int *const IPC) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 2 adjacent parameters of 'qualifiedPtr1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first 

[PATCH] D89649: Fix __has_unique_object_representations with no_unique_address

2021-06-24 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

//Gentle boop.// Bugzilla is offline for me right now (and rumour has it that 
it will be completely shut down in the near future), so it would be good to 
know what is the status of this patch and how it related to the mentioned (and 
//right now// unavailable) bug report, as it is also blocking a Clang-Tidy 
check.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89649/new/

https://reviews.llvm.org/D89649

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
whisperity marked an inline comment as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:694-695
+
+  for (std::size_t I = 0, E = CalleeFuncDecl->getNumParams(); I != E; ++I) {
+if (const auto *Param = CalleeFuncDecl->getParamDecl(I)) {
+  ParamTypes.push_back(Param->getType());

aaron.ballman wrote:
> Range-based for loop over `CalledFuncDecl->params()`?
(Note: it's `parameters()` now, not `params()`!)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354867.
whisperity added a comment.

**NFC** Fix `ReleaseNotes` entry getting out of place during rebases earlier.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
  llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn

Index: llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
===
--- llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
+++ llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
@@ -48,6 +48,7 @@
 "StaticAccessedThroughInstanceCheck.cpp",
 "StaticDefinitionInAnonymousNamespaceCheck.cpp",
 "StringCompareCheck.cpp",
+"SuspiciousCallArgumentCheck.cpp",
 "UniqueptrDeleteReleaseCheck.cpp",
 "UppercaseLiteralSuffixCheck.cpp",
 "UseAnyOfAllOfCheck.cpp",
Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,487 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+void foo_8(int frobble1, int frobble2) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test cases for multilevel pointers.
+void multilevel_pointer_parameters(int *const **pp,
+   const int *const *volatile const *qq);

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 354856.
whisperity marked 2 inline comments as done.
whisperity added a comment.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

- Fix comments and code according to comments
- Turned `Substring` into a case-insensitive heuristic.
- Added some missing tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
  llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn

Index: llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
===
--- llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
+++ llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
@@ -48,6 +48,7 @@
 "StaticAccessedThroughInstanceCheck.cpp",
 "StaticDefinitionInAnonymousNamespaceCheck.cpp",
 "StringCompareCheck.cpp",
+"SuspiciousCallArgumentCheck.cpp",
 "UniqueptrDeleteReleaseCheck.cpp",
 "UppercaseLiteralSuffixCheck.cpp",
 "UseAnyOfAllOfCheck.cpp",
Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,487 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+void foo_8(int frobble1, int frobble2) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test 

[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe33d0478831e: [clang-tidy] Extend 
bugprone-easily-swappable-parameters with mixability… (authored by 
whisperity).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 typedef int MyInt1;
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 3}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
 // RUN:  ]}' --
 
 int add(int Left, int Right) { return Left + Right; } // NO-WARN: Only 2 parameters.
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -3,7 +3,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
-// RUN: {key: 

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb9ece0346112: [clang-tidy] Suppress reports to similarly 
used parameters in bugprone-easily… (authored by whisperity).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -4,7 +4,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -0,0 +1,231 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN:  ]}' --
+
+namespace std {
+template 
+T max(const T , const T );
+} // namespace std
+
+bool coin();
+void f(int);
+void g(int);
+void h(int, int);
+void i(int, bool);
+void i(int, char);
+
+struct Tmp {
+  int f(int);
+  int g(int, int);
+};
+
+struct Int {
+  int I;
+};
+
+void compare(int Left, int Right) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'compare' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Left'
+// CHECK-MESSAGES: :[[@LINE-3]]:28: note: the last parameter in the range is 'Right'
+
+int decideSequence(int A, int B) {
+  if (A)
+return 1;
+  if (B)
+return 2;
+  return 3;
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:20: warning: 2 adjacent parameters of 'decideSequence' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-8]]:24: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-9]]:31: note: the last parameter in the range is 'B'
+
+int myMax(int A, int B) { // NO-WARN: Appears in same expression.
+  return A < B ? A : B;
+}
+
+int myMax2(int A, int B) { // NO-WARN: Appears in same expression.
+  if (A < B)
+return A;
+  return B;
+}
+
+int myMax3(int A, int B) { // NO-WARN: Appears in same expression.
+  return std::max(A, B);
+}
+
+int binaryToUnary(int A, int) {
+  return A;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: 2 adjacent parameters of 'binaryToUnary' of similar type ('int')
+// CHECK-MESSAGES: 

[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG26d864b44b9d: [clang-tidy] Extend 
bugprone-easily-swappable-parameters with `typedef` and… (authored 
by whisperity).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95736/new/

https://reviews.llvm.org/D95736

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -115,20 +115,38 @@
 // CHECK-MESSAGES: :[[@LINE-2]]:32: note: the first parameter in the range is 'I1'
 // CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'I2'
 
-void throughTypedef(int I, MyInt1 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'throughTypedef' of similar type ('int')
-// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:35: note: the last parameter in the range is 'J'
+void typedefMultiple(MyInt1 I1, MyInt2 I2x, MyInt2 I2y) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 adjacent parameters of 'typedefMultiple' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I1'
+// CHECK-MESSAGES: :[[@LINE-3]]:52: note: the last parameter in the range is 'I2y'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+void throughTypedef1(int I, MyInt1 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'throughTypedef1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:26: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+
+void betweenTypedef2(MyInt1 I, MyInt2 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'betweenTypedef2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:39: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+typedef MyInt2 MyInt2b;
 
-void betweenTypedef(MyInt1 I, MyInt2 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'betweenTypedef' of similar type ('MyInt1')
-// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:38: note: the last parameter in the range is 'J'
+void typedefChain(int I, MyInt1 MI1, MyInt2 MI2, MyInt2b MI2b) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 4 adjacent parameters of 'typedefChain' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:23: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:58: note: the last parameter in the range is 'MI2b'
+// CHECK-MESSAGES: :[[@LINE-4]]:19: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+// CHECK-MESSAGES: :[[@LINE-5]]:19: note: after resolving type aliases, 'int' and 'MyInt2' are the same
+// CHECK-MESSAGES: :[[@LINE-6]]:19: note: after resolving type aliases, 'int' and 'MyInt2b' are the same
 
 typedef long MyLong1;
 using MyLong2 = long;
 
-void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: Not the same type.
+void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: int and long.
 
 void qualified1(int I, const int CI) {} // NO-WARN: Not the same type.
 
@@ -142,18 +160,73 @@
 
 void qualifiedThroughTypedef1(int I, CInt CI) {} // NO-WARN: Not the same type.
 
-void qualifiedThroughTypedef2(CInt CI1, const int CI2) {} // NO-WARN: Not the same type.
-// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type ('CInt')
+void qualifiedThroughTypedef2(CInt CI1, const int CI2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type are
 // CHECK-MESSAGES: :[[@LINE-2]]:36: note: the first parameter in the range is 'CI1'
 // CHECK-MESSAGES: :[[@LINE-3]]:51: note: the last parameter in the range is 'CI2'
-
-void reference1(int I, int ) {} // NO-WARN: Not the same type.
-
-void reference2(int I, const int ) {} // NO-WARN: Not the same type.
-
-void reference3(int I, int &) {} // NO-WARN: Not the same type.
-
-void reference4(int I, 

[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG961e9e6af65e: [clang-tidy] Extend 
bugprone-easily-swappable-parameters with optionally… (authored by 
whisperity).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96355/new/

https://reviews.llvm.org/D96355

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:34: note: the last parameter in the range is 'CI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const int' parameters accept and bind the same kind of values
+
+void qualified2(int I, volatile int VI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'VI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'volatile int' parameters accept and bind the same kind of values
+
+void qualified3(int I, const volatile int CVI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified3' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'CVI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const volatile int' parameters accept and bind the same kind of values
+
+void qualified4(int *IP, const int *CIP) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified4' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'CIP'
+// CHECK-MESSAGES: :[[@LINE-4]]:26: note: 'int *' and 'const int *' parameters accept and bind the same kind of values
+
+void qualified5(const int CI, const long CL) {} // NO-WARN: Not the same type
+
+void qualifiedPtr1(int *IP, int *const IPC) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 2 adjacent parameters of 'qualifiedPtr1' of 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG499e39c5983d: [clang-tidy] Add 
bugprone-easily-swappable-parameters check (authored by whisperity).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
+// Even though it is "_Bool" that is written in the code, the diagnostic message
+// 

[PATCH] D97297: [clang-tidy] Suppress reports to patternedly named parameters in 'bugprone-easily-swappable-parameters'

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0fba450b9756: [clang-tidy] Suppress reports to patternedly 
named parameters in bugprone… (authored by whisperity).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97297/new/

https://reviews.llvm.org/D97297

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicit-qualifiers.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-prefixsuffixname.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' --
 
 namespace std {
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
@@ -5,7 +5,8 @@
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
-// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 int myprint();
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
+++ 

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-06-28 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 12 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:408-409
+
+  bool IsParamContinuouslyConst =
+  !IsParamReference || ParamType.getNonReferenceType().isConstQualified();
+

aaron.ballman wrote:
> Should this move down closer to where it's used?
Sure!



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:801
+  }
+  llvm_unreachable("Unhandled heuristic kind");
+}

aaron.ballman wrote:
> This looks pretty reachable to me in the case where there's no bound.
I'm not sure if that is the case. I added the `llvm_unreachable` so we don't 
get a warning about the function not having a return value on every code path. 
The `switch` covers **all** potential heuristics that are in the check //right 
now//, but if we add a new heuristic (to the enum) and forget to write it in, 
we will get a `-Wswitch` warning here. A `default` case doesn't apply here, 
further developers should be encouraged to wire new heuristics in properly.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-06-29 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 2 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:113-120
+#define FB(Name, K) MIX_##Name = (1ull << (K##ull - 1ull))
+
+  FB(None, 1),  //< Mix between the two parameters is not possible.
+  FB(Trivial, 2),   //< The two mix trivially, and are the exact same type.
+  FB(Canonical, 3), //< The two mix because the types refer to the same
+// CanonicalType, but we do not elaborate as to how.
+

alexfh wrote:
> whisperity wrote:
> > alexfh wrote:
> > > I'd switch to scoped enums (`enum class`), remove the macro, and use 
> > > simpler code like `None = 0x1, Trivial = 0x2, Canonical = 0x4`, etc.
> > `enum class` is a good idea!
> > 
> > Unfortunately, I'm not really sold on the hexa literals... It makes the 
> > code confusing the read, because you have to keep in mind which range the 
> > hexa literals mean, and when there is a shift in position, e.g. if you read 
> > `0x20` you have to count out that okay, that's 2nd position, so at least 
> > 16, so at least the 4th bit, but it is two, so you shift it again to the 
> > right, so in the bit pattern it turns on the 5th bit actually.
> > It makes it very easy to misread or misinterpret things, especially when 
> > trying to work on the source code.
> > (In the last extension patch, the number of elements in the bit mask go up 
> > to the 8th or the 9th bit, I don't remember exactly at the top of my head.)
> > 
> > Compared to this, the current text when read immediately tells you which 
> > "decimal" position you should expect the appropriate bit to be toggled on, 
> > if the flag is there.
> > 
> > Binary literals, on the other hand, would be amazing to use here, sadly 
> > we're only in C++14.
> First of all, do we ever need to know the position of the set bit in these 
> flag enumerators? Isn't it enough that each enumerator has a distinct bit 
> set? If so, there's not much complexity in reading and expanding sequences 
> like `0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 
> 0x0200, ...`.
> However, if that's not to your taste, there's another frequently used style 
> of defining flag enumerations in LLVM: `1 << 0, 1 << 1, 1 << 2, 1 << 3, ...`.
> 
> Either of these is fine, but using macros for this purpose is not necessary 
> and doesn't make the code any easier to read or to modify.
> 
> > Compared to this, the current text when read immediately tells you which 
> > "decimal" position you should expect the appropriate bit to be toggled on, 
> > if the flag is there.
> Do I understand correctly that you need this exclusively for the purpose of 
> reading debug logs? If so, it seems to be better to decode the bits before 
> logging them. See the comment on line 87 above.
Yes, there individual positions themselves don't matter! The only thing that 
matters is that some flags are < than `None` and the rest are `>=`, but that's 
only needed because of the ugly workaround.

I turned the debug printouts to use a manual formatting with "reasonable" 
characters being set (e.g. `T` for `Trivial` or `&` for `reference`). It's much 
more readable and straight-forward, because you actually do not need to know 
the position of the bits themselves, those don't matter.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:133
+
+  void sanitize() {
+assert(Flags != MIX_Invalid && "sanitize() called on invalid bitvec");

alexfh wrote:
> whisperity wrote:
> > alexfh wrote:
> > > What should this method do and how it should be used? Same for 
> > > Mix::sanitize()
> > Once there are more flags in the bitmask (not just "None" and "Trivial"), 
> > this method deals with sanitising the flags that are toggled on and off by 
> > the recursive descent on the type tree.
> > 
> > For example, if there is a typedef involved (see D95736), it will toggle on 
> > the typedef flag, and start investigating the aliased type. This subsequent 
> > investigation might figure out that the aliased type is trivial, or it is 
> > distinct. In case it is distinct, that level of the recursion will turn on 
> > the "Not mixable" flag. In this case, when the investigation returns 
> > completely, we will have "Typedef" and "None" both turned on. This method 
> > will throw away everything but the "None" bit, so when the data is returned 
> > to the diagnostic-generating part of the check, it will know what to do.
> Thanks for the explanation! But it would be very helpful to have this 
> information in the code, not only in a code review comment.
The full patch stack landed, and this function has a much more elaborated 
implementation (with more comments), I believe. In this patch, there was indeed 
nothing to add here.



Comment at: 

[PATCH] D92777: [clang-tidy] Add bugprone-strlen-in-array-index checker

2021-07-09 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

The tests are a bit slim. We definitely need more cases... what if the array 
isn't allocated locally, but received as a parameter? I take that we need both 
an `fgets` and a `strlen` call in the same function(?) to emit diagnostics. Are 
we sure it will work if the array is originally from somewhere else?




Comment at: clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:21
+  Finder->addMatcher(
+  arraySubscriptExpr(
+  allOf(hasBase(implicitCastExpr(hasSourceExpression(

While certainly not natural, if we're already here, it wouldn't take more than 
a few additional lines to match the equivalent but "expanded" version of array 
indexing:

```
*(buf + strlen(buf) - 1) = 0;
```



Comment at: clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:22
+  arraySubscriptExpr(
+  allOf(hasBase(implicitCastExpr(hasSourceExpression(
+declRefExpr(to(varDecl().bind("buf")),

What's a hard `implicitCastExpr` doing here? Does a cast always happen? I feel 
this might be a bit too restrictive... there are matcher adaptors like 
`ignoringParenImpCasts`, that route should be investigated.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:26-28
+allOf(callee(functionDecl(
+  hasAnyName("::strlen", "::std::strlen",
+ "::wcslen", "::std::wcslen"))),

`strlen_s`, `wcslen_s`? If I am reading [[ 
http://en.cppreference.com/w/c/string/byte/strlen | this correctly ]] then in 
case the input buffer starts with a `NUL` (and the //safe size// is large 
enough) then it behaves the same way `strlen` and will still return 0.

If we are already here, it might be worth to also check for [[ 
http://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html | strnlen 
]]. It is POSIX and BSD specific, but behaves the same way as `strlen_s`.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:31-32
+ equalsBoundNode("buf",
+anyOf(hasDescendant(binaryOperator(hasOperatorName("-"))),
+  binaryOperator(hasOperatorName("-")))
+  .bind("arrayExpr"),

Why is the inner matcher duplicated here? What cases do we have a direct (?) 
`-` and a non-direct (descendant) one?



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-strlen-in-array-index.cpp:16-17
+
+// Examples were copied from the cert-fio37-c issue (with some added calls):
+// 
https://wiki.sei.cmu.edu/confluence/display/c/FIO37-C.+Do+not+assume+that+fgets%28%29+or+fgetws%28%29+returns+a+nonempty+string+when+successful
+

Such code examples might be covered by non-permissive copyright, which might be 
incompatible with LLVM's licence. I was unable to find anything wrt. copyright 
on SEI CERT's Confluence, which in this case makes the work to be //(strictly) 
copyrighted// by default. I am not sure what the actual situation is, but such 
a **direct mention** of copying //could// lead to problems.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92777/new/

https://reviews.llvm.org/D92777

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-04-22 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 339533.
whisperity edited the summary of this revision.
whisperity added a comment.

- **NFC** Fix lint of header guard nomenclature
- **NFC** Tear out obsolete `LLVM_DEBUG` calls from the implementation


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,477 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+void foo_8(int frobble1, int frobble2) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test cases for multilevel pointers.
+void multilevel_pointer_parameters(int *const **pp,
+   const int *const *volatile const *qq);
+void multilevel_pointer_parameters2(
+char *nn, char *volatile *const *const *const *const );
+
+typedef float T;
+typedef T *S;
+typedef S *const volatile R;
+typedef R *Q;
+typedef Q *P;
+typedef P *O;
+void multilevel_pointer_parameters3(float **const volatile ***rr, O );
+
+void multilevel_pointer_swap() {
+  int *const **qq;
+  int *const **pp;
+  multilevel_pointer_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+
+  

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-04-22 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 339625.
whisperity added a comment.

**NFC** Fix the header guard name lint again, hopefully to the proper value 
this time. I forgot the `CHECK` out of it...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,477 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+void foo_8(int frobble1, int frobble2) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test cases for multilevel pointers.
+void multilevel_pointer_parameters(int *const **pp,
+   const int *const *volatile const *qq);
+void multilevel_pointer_parameters2(
+char *nn, char *volatile *const *const *const *const );
+
+typedef float T;
+typedef T *S;
+typedef S *const volatile R;
+typedef R *Q;
+typedef Q *P;
+typedef P *O;
+void multilevel_pointer_parameters3(float **const volatile ***rr, O );
+
+void multilevel_pointer_swap() {
+  int *const **qq;
+  int *const **pp;
+  multilevel_pointer_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+
+  char *mm;
+  char *nn;
+  

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-08 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:177
+   const std::size_t StartIndex) {
+  const std::size_t NumParams = FD->getNumParams();
+  assert(StartIndex < NumParams && "out of bounds for start");

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > Some interesting test cases to consider: varargs functions and K C 
> > > functions
> > > K C functions
> > 
> > Call me too young, but I had to look up what a "K C function" is, and I 
> > am absolutely baffled how this unholy construct is still supported! 
> > **But:** thanks to Clang supporting it properly in the AST, the checker 
> > works out of the box!
> > 
> > Given
> > 
> > ```
> > int foo(a, b)
> >   int a;
> >   int b;
> > {
> >   return a + b;
> > }
> > ```
> > 
> > We get the following output:
> > 
> > ```
> > /tmp/knr.c:2:3: warning: 2 adjacent parameters of 'foo' of similar type 
> > ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
> >   int a;
> >   ^
> > /tmp/knr.c:2:7: note: the first parameter in the range is 'a'
> >   int a;
> >   ^
> > /tmp/knr.c:3:7: note: the last parameter in the range is 'b'
> >   int b;
> >   ^
> > ```
> > 
> > (even the locations are consistent!)
> > 
> > Should I add a test case for this? We could use a specifically C test case 
> > either way eventually...
> > 
> > -
> > 
> > > varargs functions
> > 
> > This is a bit of terminology, but something tells me you meant the 
> > //variadic function// here, right? As opposed to type parameter packs.
> > 
> > Given
> > 
> > ```
> > int sum(int ints...) {
> >   return 0;
> > }
> > ```
> > 
> > the AST looks something like this:
> > 
> > ```
> > `-FunctionDecl 0x56372e29e258  line:1:5 sum 
> > 'int (int, ...)'
> >   |-ParmVarDecl 0x56372e29e188  col:13 ints 'int'
> > ```
> > 
> > Should we diagnose this? And if so, how? The variadic part is not 
> > represented (at least not at first glance?) in the AST. Understanding the 
> > insides of such a function would require either overapproximatic stuff and 
> > doing a looot of extra handling, or becoming flow sensitive... and we'd 
> > still need to understand all the `va_` standard functions' semantics either 
> > way.
> > Call me too young, but I had to look up what a "K C function" is, and I 
> > am absolutely baffled how this unholy construct is still supported!
> 
> Ah, to be innocent again, how I miss those days. :-D
> 
> > Should I add a test case for this? We could use a specifically C test case 
> > either way eventually...
> 
> I think it'd be a useful case, but the one I was specifically more concerned 
> with is:
> ```
> // N.B.: this is C-specific and does not apply to C++.
> void f();
> 
> int main(void) {
>   f(1, 2, 3.4, "this is why we can't have nice things");
> }
> ```
> where the function has no prototype and so is treated as a varargs call.
> 
> > This is a bit of terminology, but something tells me you meant the variadic 
> > function here, right? As opposed to type parameter packs.
> 
> Yes, sorry for being unclear, I am talking about variadic functions.
> 
> > Should we diagnose this? And if so, how? The variadic part is not 
> > represented (at least not at first glance?) in the AST. Understanding the 
> > insides of such a function would require either overapproximatic stuff and 
> > doing a looot of extra handling, or becoming flow sensitive... and we'd 
> > still need to understand all the va_ standard functions' semantics either 
> > way.
> 
> Well, that's what I'm wondering, really. The arguments are certainly easy to 
> swap because the type system can't help the user to identify swaps without 
> further information (like format specifier strings). However, the checking 
> code would be... highly unpleasant, I suspect. My intuition is to say that we 
> don't support functions without prototypes at all (we just silently ignore 
> them) and that we only check the typed parameters in a variadic function 
> declaration (e.g., we'll diagnose `void foo(int i, int j, ...);` because of 
> the sequential `int` parameters, but we won't diagnose `void foo(int i, 
> ...);` even if call sites look like `foo(1, 2);`). WDYT?
It is definitely highly unpleasant, at one point I remember just glancing into 
the logic behind `printf()` related warnings in Sema and it was... odd, to say 
the least.

That is how the checker works right now. It will not diagnose `int f() {}` 
because from the looks of the function definition, it is a 0-parameter 
function. Same with the variadic `...`, it is a single parameter function 
(which has a rather //weird// parameter type).

But yes, I think I'll make this explicit in the documentation (and FWIW, the 
research paper, too). 

> However, the checking code would be... highly unpleasant, I suspect.

Incredibly, because this check purposefully targets the function definition 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D69560#2549959 , @steveire wrote:

> Why "easily" instead of "suspicious", "spuriously" or any of the other words 
> that are already used?

The name was @aaron.ballman's idea after we postponed the 
`experimental-cppcoreguidelines-yaddayaddayadda...`.
The best I could come up with is `potentially`. The `suspicious` is a problem 
because this check is an interface check, not a call-site check. (The sister 
check is currently called `suspiciously-swapped-argument` or something like 
that.)

The original check idea from C++ Core Guidelines 

 also uses the phrase:

> Reason: Adjacent arguments of the same type are easily swapped by mistake.

However, `potentially-swappable-parameters` just sounds... wonky. It does not 
carry the weight the rule otherwise meant to.
`weakly-typed-parameters`?

I am not good with names, sadly.



I am conflicted about saying that "easily" **always** refers to some "positive 
aspect", however. Use a [[unnamed trademarked safety device]] because you can 
end up easily cutting off your finger during work. Do not touch a stove/hot 
water fountain, because you can easily get burnt. Leaving Christmas candles 
unattended could easily lead to a house fire. Does anyone want to get hurt, 
burnt, their house destroyed, etc.? There is nothing "positive" in these 
suggestions or regulations either. And we are doing a tool that is practically 
the same thing, trying to prevent a (different kind of) fire.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 322431.
whisperity marked 6 inline comments as done.
whisperity added a comment.
Herald added a subscriber: nullptr.cpp.

- **NFC** Code style, formatting, wording, etc. changes as per review comments.
- **NFC** Removed a stale FIXME


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95736/new/

https://reviews.llvm.org/D95736

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -86,20 +86,38 @@
 // CHECK-MESSAGES: :[[@LINE-2]]:32: note: the first parameter in the range is 'I1'
 // CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'I2'
 
-void throughTypedef(int I, MyInt1 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'throughTypedef' of similar type ('int')
-// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:35: note: the last parameter in the range is 'J'
+void typedefMultiple(MyInt1 I1, MyInt2 I2x, MyInt2 I2y) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 adjacent parameters of 'typedefMultiple' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I1'
+// CHECK-MESSAGES: :[[@LINE-3]]:52: note: the last parameter in the range is 'I2y'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+void throughTypedef1(int I, MyInt1 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'throughTypedef1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:26: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+
+void betweenTypedef2(MyInt1 I, MyInt2 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'betweenTypedef2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:39: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+typedef MyInt2 MyInt2b;
 
-void betweenTypedef(MyInt1 I, MyInt2 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'betweenTypedef' of similar type ('MyInt1')
-// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:38: note: the last parameter in the range is 'J'
+void typedefChain(int I, MyInt1 MI1, MyInt2 MI2, MyInt2b MI2b) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 4 adjacent parameters of 'typedefChain' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:23: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:58: note: the last parameter in the range is 'MI2b'
+// CHECK-MESSAGES: :[[@LINE-4]]:19: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+// CHECK-MESSAGES: :[[@LINE-5]]:19: note: after resolving type aliases, 'int' and 'MyInt2' are the same
+// CHECK-MESSAGES: :[[@LINE-6]]:19: note: after resolving type aliases, 'int' and 'MyInt2b' are the same
 
 typedef long MyLong1;
 using MyLong2 = long;
 
-void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: Not the same type.
+void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: int and long.
 
 void qualified1(int I, const int CI) {} // NO-WARN: Not the same type.
 
@@ -113,18 +131,73 @@
 
 void qualifiedThroughTypedef1(int I, CInt CI) {} // NO-WARN: Not the same type.
 
-void qualifiedThroughTypedef2(CInt CI1, const int CI2) {} // NO-WARN: Not the same type.
-// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type ('CInt')
+void qualifiedThroughTypedef2(CInt CI1, const int CI2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type are
 // CHECK-MESSAGES: :[[@LINE-2]]:36: note: the first parameter in the range is 'CI1'
 // CHECK-MESSAGES: :[[@LINE-3]]:51: note: the last parameter in the range is 'CI2'
-
-void reference1(int I, int ) {} // NO-WARN: Not the same type.
-
-void reference2(int I, const int ) {} // NO-WARN: Not the same type.
-
-void reference3(int I, int 

[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity created this revision.
whisperity added reviewers: aaron.ballman, alexfh, hokein, njames93.
whisperity added projects: clang, clang-tools-extra.
Herald added subscribers: nullptr.cpp, rnkovacs, xazax.hun.
whisperity requested review of this revision.
Herald added a subscriber: cfe-commits.

Adds a relaxation option **`QualifiersMix`** which will make the check report 
for cases where parameters refer to the same type if they only differ in 
qualifiers.

This makes cases, such as the following, not warned about by default, produce a 
warning.

  void* memcpy(void* dst, const void* src, unsigned size) {}

The reasoning behind this is that several projects, code styles, and 
preferences might consider `T` and `const T` fundamentally different types. The 
related C++ Core Guidelines 

 rule itself shows an example where `void T*, const void T*` is considered a 
"good solution".

However, unless people meticulously `const` their local variables, 
unfortunately, even such a function carry a potential swap:

  T* obj = new T; // Not const!!!
  void* buf = malloc(sizeof(T));
  
  memcpy(obj, buf, sizeof(T));
  // ^~~  ^~~ accidental swap here, even though the interface "specified" a 
const.

Of course, keeping your things `const` where appropriate results in an error:

  const T* obj = new T;
  void* buf = malloc(sizeof(T));
  
  memcpy(obj, buf, sizeof(T));
  // error: 1st argument ('const T*') loses qualifiers

Due to the rationale behind this depending on project-specific guidelines and 
preferences, the modelling is introduced as a check option. The default value 
is **`false`**, i.e. `T*` and `const T*` are considered **unmixable, distinct 
types**.

> Originally, the implementation of this feature was part of the very first 
> patch related to this check, D69560  (diff 
> 259320 ). It has been factored out 
> for clarity and to allow more on-point discussion.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96355

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 4 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:255
+  std::string NodeTypeName =
+  Node->getType().getAsString(Node->getASTContext().getPrintingPolicy());
+  StringRef CaptureName{NodeTypeName};

whisperity wrote:
> aaron.ballman wrote:
> > whisperity wrote:
> > > aaron.ballman wrote:
> > > > Hmm, one downside to using the printing policy to get the node name is 
> > > > that there can be alternative spellings for the same type that the user 
> > > > might reasonably expect to be applied. e.g., if the user expects to 
> > > > ignore `bool` datatypes and the printing policy wants to spell the type 
> > > > as `_Bool`, this won't behave as expected.
> > > But then the diagnostic is inconsistent with what the compiler is 
> > > configured to output as diagnostics, isn't it? Can I stringify through 
> > > Clang with some "default" printing policy?
> > The situation I'm worried about is something like this in C code:
> > ```
> > #include 
> > 
> > void func(bool b, bool c) {}
> > ```
> > because the `bool` in the function signature will expand to `_Bool` after 
> > the preprocessor gets to it (because of the contents of ``). If 
> > the user writes `bool` in their configuration file because that's what 
> > they've written in their function signatures, will this fail because the 
> > printing policy says it should be `_Bool`?
> > 
> > Along similar lines, I wonder about things like `struct S` vs `S` (in C), 
> > `signed char` vs `char`, types within anonymous namespaces (where we print 
> > ``), etc. Basically, any time when the printing policy 
> > may differ from what the user lexically writes in code.
> Meanwhile, I realised we are talking of two entirely distinct things. I will 
> look into how this `PrintingPolicy` stuff works... I agree that the ignore 
> rules (where the comment was originally posted) should respect the text 
> written into the code as-is. The diagnostics printing type names could 
> continue using the proper printing policy (to be in line with how Sema 
> diagnoses, AFAIK).
Right, @aaron.ballman I think I got this tested. Please check the C test file. 
`bool` becomes `_Bool` in C code by the preprocessor, but the printing policy 
still says both should be printed as `bool`. I added some test cases about 
this. It is weird, because without doing some extra magic specifically against 
macros (which might break detecting type names in other locations), I can't 
really test ignoring `_Bool` but not ignoring `bool`. Now, the diagnostics 
respect the printing policy, but the type names are taken with an empty 
printing policy, which //should// give us the result as-is in the code. 
Unfortunately, "as-is" still means `_Bool` for `bool`'s case, so even if you 
ignore `bool`, you will still get results where `bool` is written, because 
`bool` is a macro (Tidy automatically puts a note about this!) and the real 
type is `_Bool`, as per the macro expansion.

Wow... okay, that explanation got convoluted.
Anyways, it's //really weird//. But: we no longer take the actual printing 
policy anymore, but the default, which should eliminate all these cases.
The `bool`/`_Bool` case doesn't fail because of the printing policy, it fails 
because `bool` is a macro in ``.

Also, the type name ignore list not a full match, but a //substring match// 
ignore list. So if you have a type named `struct Foo`, if you ignore `Foo`, 
both `struct Foo`, `Foo`, `MyFoo`, etc. will be also ignored. And it's case 
sensitive.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 322339.
whisperity added a comment.

- Added a C test file with some C-specific language constructs that we may or 
may not match.
- Explained limitations with regards to variadics, templates, etc. better in 
the docs, and added test cases for these too.
- When comparing the type names against the ignored type name list, do **not** 
consider `PrintingPolicy`, but take //exactly// what's in the source code. This 
mostly concerns `bool` and `_Bool` at face value, so this is tested in the C 
file too.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,93 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void unholy(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'unholy' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {}
+// Even though it is "bool" what is written there, the preprocessor has changed
+// it to "_Bool" due to 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 322357.
whisperity added a comment.

Made detection of macros as "parameter type names" more robust.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
+// Even though it is "_Bool" that is written in the code, the diagnostic message
+// respects the printing policy as defined by the 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity marked an inline comment as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:255
+  std::string NodeTypeName =
+  Node->getType().getAsString(Node->getASTContext().getPrintingPolicy());
+  StringRef CaptureName{NodeTypeName};

whisperity wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > whisperity wrote:
> > > > aaron.ballman wrote:
> > > > > Hmm, one downside to using the printing policy to get the node name 
> > > > > is that there can be alternative spellings for the same type that the 
> > > > > user might reasonably expect to be applied. e.g., if the user expects 
> > > > > to ignore `bool` datatypes and the printing policy wants to spell the 
> > > > > type as `_Bool`, this won't behave as expected.
> > > > But then the diagnostic is inconsistent with what the compiler is 
> > > > configured to output as diagnostics, isn't it? Can I stringify through 
> > > > Clang with some "default" printing policy?
> > > The situation I'm worried about is something like this in C code:
> > > ```
> > > #include 
> > > 
> > > void func(bool b, bool c) {}
> > > ```
> > > because the `bool` in the function signature will expand to `_Bool` after 
> > > the preprocessor gets to it (because of the contents of ``). 
> > > If the user writes `bool` in their configuration file because that's what 
> > > they've written in their function signatures, will this fail because the 
> > > printing policy says it should be `_Bool`?
> > > 
> > > Along similar lines, I wonder about things like `struct S` vs `S` (in C), 
> > > `signed char` vs `char`, types within anonymous namespaces (where we 
> > > print ``), etc. Basically, any time when the 
> > > printing policy may differ from what the user lexically writes in code.
> > Meanwhile, I realised we are talking of two entirely distinct things. I 
> > will look into how this `PrintingPolicy` stuff works... I agree that the 
> > ignore rules (where the comment was originally posted) should respect the 
> > text written into the code as-is. The diagnostics printing type names could 
> > continue using the proper printing policy (to be in line with how Sema 
> > diagnoses, AFAIK).
> Right, @aaron.ballman I think I got this tested. Please check the C test 
> file. `bool` becomes `_Bool` in C code by the preprocessor, but the printing 
> policy still says both should be printed as `bool`. I added some test cases 
> about this. It is weird, because without doing some extra magic specifically 
> against macros (which might break detecting type names in other locations), I 
> can't really test ignoring `_Bool` but not ignoring `bool`. Now, the 
> diagnostics respect the printing policy, but the type names are taken with an 
> empty printing policy, which //should// give us the result as-is in the code. 
> Unfortunately, "as-is" still means `_Bool` for `bool`'s case, so even if you 
> ignore `bool`, you will still get results where `bool` is written, because 
> `bool` is a macro (Tidy automatically puts a note about this!) and the real 
> type is `_Bool`, as per the macro expansion.
> 
> Wow... okay, that explanation got convoluted.
> Anyways, it's //really weird//. But: we no longer take the actual printing 
> policy anymore, but the default, which should eliminate all these cases.
> The `bool`/`_Bool` case doesn't fail because of the printing policy, it fails 
> because `bool` is a macro in ``.
> 
> Also, the type name ignore list not a full match, but a //substring match// 
> ignore list. So if you have a type named `struct Foo`, if you ignore `Foo`, 
> both `struct Foo`, `Foo`, `MyFoo`, etc. will be also ignored. And it's case 
> sensitive.
Nevermind, I think I figured this out... or at least managed to figure it out 
partially... This "SpellingLoc" and "ExpansionLoc" and all this stuff is really 
convoluted, and there doesn't seem to be any good documentation for them.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-02-09 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 322363.
whisperity added a comment.

**NFC** (With all the restructuring and trying to figure out how to implement 
the latest change, I managed to upload the wrong, unclean diff...)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
+// Even though it is "_Bool" that is written in the code, 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-01-28 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 319840.
whisperity marked 9 inline comments as done.
whisperity added a comment.

- NFC Code style and organisation fixes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 3}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""} \
+// RUN:  ]}' --
+
+int add(int Left, int Right) { return Left + Right; } // NO-WARN: Only 2 parameters.
+
+int magic(int Left, int Right, int X, int Y) { return 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 4 adjacent parameters of 'magic' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:15: note: the first parameter in the range is 'Left'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'Y'
+
+void multipleDistinctTypes(int I, int J, int K,
+   long L, long M,
+   double D, double E, double F) {}
+// CHECK-MESSAGES: :[[@LINE-3]]:28: warning: 3 adjacent parameters of 'multipleDistinctTypes' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:32: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-5]]:46: note: the last parameter in the range is 'K'
+// NO-WARN: The [long, long] range is length of 2.
+// CHECK-MESSAGES: :[[@LINE-5]]:28: warning: 3 adjacent parameters of 'multipleDistinctTypes' of similar type ('double')
+// CHECK-MESSAGES: :[[@LINE-6]]:35: note: the first parameter in the range is 'D'
+// CHECK-MESSAGES: :[[@LINE-7]]:55: note: the last parameter in the range is 'F'
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -0,0 +1,141 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""} \
+// RUN:  ]}' --
+
+#define assert(X)
+
+void declaration(int Param, int Other); // NO-WARN: No chance to change this function.
+
+struct S {};
+
+S *allocate() { return nullptr; }   // NO-WARN: 0 parameters.
+void allocate(S **Out) {}   // NO-WARN: 1 parameter.
+bool operator<(const S , const S ) { return true; } // NO-WARN: Operator.
+
+void redeclChain(int, int, int);
+void redeclChain(int I, int, int);
+void redeclChain(int, int J, int);
+void redeclChain(int I, int J, int K) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 3 adjacent parameters of 'redeclChain' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the last parameter in the range is 'K'
+
+void copyMany(S *Src, S *Dst, unsigned Num) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'copyMany' of similar type ('S *')
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Src'
+// CHECK-MESSAGES: :[[@LINE-3]]:26: note: the last parameter in the range is 'Dst'
+
+template 
+bool binaryPredicate(T L, U R) { return false; } // NO-WARN: Distinct types in template.
+
+template 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-01-28 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:284
+/// The default value for the MinimumLength check option.
+static constexpr unsigned DefaultMinimumLength = 2;
+

aaron.ballman wrote:
> It might be good to move this to a more prominent location since it's a 
> default value.
Moved it to the top.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:302
+ "FowardIt", "bidirit", "BidirIt", "constiterator",
+ "const_iterator", "Const_Iterator", "Constiterator",
+ "ConstIterator"});

aaron.ballman wrote:
> `reverse_iterator` and `reverse_const_iterator` too?
> 
> How about ranges?
> How about ranges?

I would like to say that having an `f(RangeTy, RangeTy)` is //exactly// as 
problematic (especially if both are non-const) as having `f(int, int)` or 
`f(void*, void*)`, and should be taken care of the same way (relatedness 
heuristic, name heuristic).
The idea behind ignoring iterator-ly named things was that //"Iterators more 
often than not comes in pairs and you can't(*) do anything about it"//.

(*): Use ranges. Similarly how `draw(int x, int y)` is `draw(Point2D)` if we 
are enhancing type safety.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:207
+
+  LLVM_DEBUG(QT.dump());
+

Actually this is one of those debug prints that should be removed and remained 
in here by accident.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:657-667
+  // Certain kinds unfortunately need to be side-stepped for canonical type
+  // matching.
+  if (LType->getAs() || RType->getAs()) {
+// Unfortunately, the canonical type of a function pointer becomes the
+// same even if exactly one is "noexcept" and the other isn't, making us
+// give a false positive report irrespective of implicit conversions.
+LLVM_DEBUG(llvm::dbgs()

@aaron.ballman Getting ahead of the curve here. I understand this is ugly. 
Unfortunately, no matter how much I read the standard, I don't get anything of 
"canonical type" mentioned, it seems to me this concept is something inherent 
to the model of Clang.

Basically why this is here: imagine a `void (*)() noexcept` and a `void (*)()`. 
One's `noexcept`, the other isn't. Inside the AST, this is a `ParenType` of a 
`PointerType` to a `FunctionProtoType`. There exists a //one-way// implicit 
conversion from the `noexcept` to the non-noexcept ("noexceptness can be 
discarded", similarly to how "constness can be gained")
Unfortunately, because this is a one-way implicit conversion, it won't return 
on the code path earlier for implicit conversions.

Now because of this, the recursive descent in our code will reach the point 
when the two innermost `FunctionProtoType`s are in our hands. As a fallback 
case, we simply ask Clang "Hey, do //you// think these two are the same?". And 
for some weird reason, Clang will say "Yes."... While one of them is a 
`noexcept` function and the other one isn't.

I do not know the innards of the AST well enough to even have a glimpse of 
whether or not this is a bug. So that's the reason why I went ahead and 
implemented this side-stepping logic. Basically, as the comment says, it'lll 
**force** the information of "No matter what you do, do NOT consider these 
mixable!" back up the recursion chain, and handle it appropriately later.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-implicits.cpp:250-260
+using NonThrowingFunction = void (*)() noexcept;
+
+struct NoexceptMaker {
+  NoexceptMaker(void (*ThrowingFunction)());
+  // Need to use a typedef here because
+  // "conversion function cannot convert to a function type".
+  // operator (void (*)() noexcept) () const;

Now here the warning is justified, however. All these disinfectant-stinking 
examples are to ensure that. In this case, in our hands, on the first level, we 
got the function pointer, and the class. And it **is** the implicit conversion 
modeller that will eventually ask "Can I give that noexcept function to that 
constructor taking a non-noexcept?" and in that case, on the level of function 
pointers, the answer is //yes//, so there will be a warning made.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp:336-337
+
+void functionPrototypeLosesNoexcept(void (*NonThrowing)() noexcept, void 
(*Throwing)()) {}
+// NO-WARN: This call cannot be swapped, even if "getCanonicalType()" believes 
otherwise.

Without this side-stepping logic mentioned above, even **without this patch** 
(so back to the "Ye Olde Strict Type Equality" mode), this particular function 
would be warned about, which is a definite false positive.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not respecting and highlighting fed SourceRanges

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

@aaron.ballman Could you please help me understand this pre-merge buildbot? It 
says that Debian failed, with the following message:

  [15/1038] Running lint check for sanitizer sources...
  FAILED: projects/compiler-rt/lib/CMakeFiles/SanitizerLintCheck
  cd /mnt/disks/ssd0/agent/llvm-project/build/projects/compiler-rt/lib && env 
LLVM_CHECKOUT=/mnt/disks/ssd0/agent/llvm-project/llvm SILENT=1 TMPDIR= 
PYTHON_EXECUTABLE=/usr/bin/python3.8 
COMPILER_RT=/mnt/disks/ssd0/agent/llvm-project/compiler-rt 
/mnt/disks/ssd0/agent/llvm-project/compiler-rt/lib/sanitizer_common/scripts/check_lint.sh
  The following differences between the ABI list and the implemented custom 
wrappers have been found:

Should I be worried because of this, or is this that the patch started building 
when the main branch was broken? I haven't touched `compiler-rt` at all. 
Neither anything that deals with the sanitizers. And this fail is "earlier" 
than the previous one where I indeed missed a test file's update.

And it talks about a lot of stuff like `fork` and such that is really really 
out of scope for the patch itself.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98635/new/

https://reviews.llvm.org/D98635

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 12 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:657-660
+} else {
+  ParamTypes.push_back(QualType());
+  ParamNames.push_back(StringRef());
+}

whisperity wrote:
> aaron.ballman wrote:
> > Can this case happen?
> Oops... It seems I posted the updated patch right where you were writing more 
> comments and we got into a data race. Which case are you referring to? It's 
> now affixed to a `diag(` call for me...
Oh, nevermind, there is a button that shows me the older diff where it's 
aligned properly.

And yeah, it seems it can't, `getParamDecl` always returns a `ParmVarDecl`. 
Weird issues might arise when the vectors that are built here get out of sync 
(such as the issue we had with `operator()` calls before I fixed it!), so I 
understood the reason behind keeping the two functions parallel with each other 
in terms of pure visuals, even.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:743-744
+
+if (AreNamesSimilar)
+  break;
+

aaron.ballman wrote:
> Any reason not to move this below the `switch` and use `=` instead of `|=` 
> within the cases? (Or return from the cases directly?)
Returning from the cases directly is a bad idea because we want to try all 
heuristics and only say `false` if none of them matches.
But this break in a very bad location, I agree.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75041: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with mixability because of implicit conversions

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 5 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:377
+
+  bool indicatesMixability() const { return Flags > MIX_None; }
+

aaron.ballman wrote:
> Should this be `MIX_WorkaroundDisableCanonicalEquivalence` instead of 
> `MIX_None`?
In this patch I changed the value of `None` to be `2`, and `Workaround...` 
became `1`. So everything above `None` means it's a valid mixability (somehow), 
of course only after `sanitize()` so `Workaround... | CanonicalType` becomes 
`None`.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75041/new/

https://reviews.llvm.org/D75041

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331560.
whisperity marked 2 inline comments as done.
whisperity added a comment.

- **NFC** Fixed some nits
- Added a new check option, //`MinimumIdentifierNameLength`// instead of a 
hardcoded `3` value. Defaults to `3`.
- Fixed an issue with heuristics matching only in one direction but not in the 
other direction silenced a warning that clearly should have been there.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,477 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+void foo_8(int frobble1, int frobble2) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test cases for multilevel pointers.
+void multilevel_pointer_parameters(int *const **pp,
+   const int *const *volatile const *qq);
+void multilevel_pointer_parameters2(
+char *nn, char *volatile *const *const *const *const );
+
+typedef float T;
+typedef T *S;
+typedef S *const volatile R;
+typedef R *Q;
+typedef Q *P;
+typedef P *O;
+void multilevel_pointer_parameters3(float **const volatile ***rr, O );
+
+void multilevel_pointer_swap() {
+  int *const **qq;
+  int *const **pp;
+  multilevel_pointer_parameters(qq, pp);

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331564.
whisperity marked 4 inline comments as done.
whisperity added a comment.

**NFC** Turned some `Optional` into just `T`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -0,0 +1,229 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN:  ]}' --
+
+namespace std {
+template 
+T max(const T , const T );
+} // namespace std
+
+bool coin();
+void f(int);
+void g(int);
+void h(int, int);
+void i(int, bool);
+void i(int, char);
+
+struct Tmp {
+  int f(int);
+  int g(int, int);
+};
+
+struct Int {
+  int I;
+};
+
+void compare(int Left, int Right) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'compare' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Left'
+// CHECK-MESSAGES: :[[@LINE-3]]:28: note: the last parameter in the range is 'Right'
+
+int decideSequence(int A, int B) {
+  if (A)
+return 1;
+  if (B)
+return 2;
+  return 3;
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:20: warning: 2 adjacent parameters of 'decideSequence' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-8]]:24: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-9]]:31: note: the last parameter in the range is 'B'
+
+int myMax(int A, int B) { // NO-WARN: Appears in same expression.
+  return A < B ? A : B;
+}
+
+int myMax2(int A, int B) { // NO-WARN: Appears in same expression.
+  if (A < B)
+return A;
+  return B;
+}
+
+int myMax3(int A, int B) { // NO-WARN: Appears in same expression.
+  return std::max(A, B);
+}
+
+int binaryToUnary(int A, int) {
+  return A;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: 2 adjacent parameters of 'binaryToUnary' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:23: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-5]]:29: note: the last parameter in the range is ''
+
+int randomReturn1(int A, int B) { // NO-WARN: Appears in same expression.
+  return coin() ? A : B;
+}
+
+int randomReturn2(int A, int B) { // NO-WARN: Both parameters returned.
+  if (coin())
+return A;
+  return B;
+}
+
+int randomReturn3(int A, int B) { // NO-WARN: Both parameters returned.
+  bool Flip = coin();
+  if (Flip)
+return A;
+  Flip = coin();
+  if (Flip)
+return B;
+  Flip = coin();
+  if (!Flip)
+return 0;
+  return -1;
+}
+
+void passthrough1(int A, 

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:529
+/// ReturnStmts return them from the function.
+class Returned {
+  llvm::SmallVector 
ReturnedParams;

aaron.ballman wrote:
> whisperity wrote:
> > whisperity wrote:
> > > aaron.ballman wrote:
> > > > Question: would it make sense to (someday, not now) consider output 
> > > > parameters similar to return statements? e.g.,
> > > > ```
> > > > void int_swap(int , int ) {
> > > >   int temp = foo;
> > > >   foo = bar;
> > > >   bar = temp;
> > > > }
> > > > ```
> > > > As a question for today: should `co_return` should be handled similarly 
> > > > as `return`?
> > > 1. Maybe. Unfortunately, one needs to be careful with that. Originally I 
> > > did implement a "5th" heuristic that dealt with ignoring parameters that 
> > > had the same builtin operator used on them. However, while it silenced a 
> > > few false positives, it started creating **massive** amounts of false 
> > > negatives.
> > > (In the concrete example, I think `foo = bar` will silence them because 
> > > //"appears in the same expression"//.)
> > > 
> > > 2. I don't know. It would require a deeper understanding of Coroutines 
> > > themselves, and how people use them.
> > If you don't mind me posting images, I can show a direct example. Things 
> > where the inability to track data flow really bites us in the backside.
> > 
> > Examples from Apache Xerces:
> > 
> > Here's a false positive that would be silenced by the logic of //"using the 
> > same operateur on the two params"//.
> > {F15891567}
> > 
> > And here is a false negative from the exact same logic.
> > {F15891568}
> > 
> > Maybe it could be //some// solace that we're restricting to 
> > non-const-lvalue-references (and pointers-to-non-const ??) and only 
> > assignment (**only** assignment?!))...
> Ah, point #1 is an excellent point. As for #2, I think we can handle it in a 
> follow-up, but I believe `co_return` follows the same usage patterns as 
> `return`, generally.
Added a TODO for `co_return`, so we don't forget.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity marked an inline comment as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:657-660
+} else {
+  ParamTypes.push_back(QualType());
+  ParamNames.push_back(StringRef());
+}

aaron.ballman wrote:
> Can this case happen?
Oops... It seems I posted the updated patch right where you were writing more 
comments and we got into a data race. Which case are you referring to? It's now 
affixed to a `diag(` call for me...



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst:61-68
+The *prefix* heuristic reports if one of the strings is a sufficiently long
+prefix of the other string, e.g. ``target`` to ``targetPtr``.
+The similarity percentage is the length ratio of the prefix to the longer
+string, in the previous example, it would be `6 / 9 = 66.66...`\%.
+
+This heuristic can be configured with :ref:`bounds`.
+The default bounds are: below `25`\% dissimilar and above `30`\% similar.

aaron.ballman wrote:
> I wonder how Hungarian notation impacts this heuristic -- I would imagine a 
> lot of similar prefixes in such a code base, and things like `lpstr` as a 
> prefix could be a pretty large chunk of some identifiers.
The switch is only warned if it would be type-safe. If the HN prefix is in both 
//the same way//, then it could be ignored. Thus, given `f(const char* lpszFoo, 
const char* lpszBar, uint16_t psnzXXX)  {}`, if I do a `f(lpszX, lpszA, ...);`, 
it should consider in both cases that the prefix is common and matches. Note 
that to produce a diagnostic, **two** things has to be proven: first, that the 
//current// ordering is dissimilar (below threshold A), and second, that the 
potential swapped ordering is more similar (above threshold B).



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst:75
+In the case of ``oldValue`` and ``value`` compared, the similarity percentage
+is `8 / 5 = 62.5`\%.
+

aaron.ballman wrote:
> Similar to above, I wonder how numeric digits impact this heuristic -- do the 
> defaults consider this to be a swap?
> ```
> void foo(int frobble1, int frobble2);
> foo(frobble2, frobble1); // Hopefully identified as a swap
> foo(bar2, bar1); // How about this?
> ```
Currently, neither of these are matched. I have to look into why the first 
isn't... it really should, based on the "equality" heuristic. It's too trivial.

The second... well... that's trickier. I would say it shouldn't match, because 
if it did, we would be swamped with false positives. The suffix is only 1 
character, and we need 25/30% based on the string's length.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:31-32
+
+  char DissimilarBelow;
+  char SimilarAbove;
+

aaron.ballman wrote:
> `signed char` since we're doing `> -1` below? Or better yet, `int8_t` because 
> these aren't really characters?
Oh right, I always forget `char` isn't guaranteed. `int8_t` seems like a better 
idea anyways (until we have `int6_t`...)



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:51
+{true, 40, 50}, // Substring.
+{true, 50, 66}, // Levenshtein.
+{true, 75, 85}, // Jaro-Winkler.

varjujan wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > We should probably document where all these numbers come from, but `66` 
> > > definitely jumps out at me as being a bit strange. :-D
> > Unfortunately, I have absolutely no idea. All these values are percentages 
> > between 0 and 100 (`-1` is just saying that //"This heuristic doesn't 
> > accept percentages"//), and this is written in the documentation now. 
> > However, the answer to //"**why** 66%?"//, unless @varjujan can say 
> > something, I think is lost to history...
> > 
> > I'll read over his thesis once again, maybe I can find anything with 
> > regards to this.
> > 
> > Either way, I've detailed from both the code and the thesis how the 
> > percentages are meant. In some cases, the % is calculated as //"% of the 
> > longer string's length"//. In the Leventhstein's case, it's actually 
> > inverted:
> > 
> > ```
> > Dist = (1 - Dist / LongerLength) * 100;
> > ```
> > 
> > So what this says is that if the current arg1-param1 arg2-param2 pairing 
> > has less than the inverse of 50% (which is more than 50%) of the longer 
> > string's edit distance, but the arg2-param1 and arg1-param2 (the suggested 
> > swapped order) has more than the inverse of 66% (which is less than 33%), 
> > then the swap will be suggested.
> > 
> > Originally these values were called `LowerBound` and `UpperBound`, 
> > respectively, which was saying **even less** about what they mean...
> Sadly, I think there isn't any scientific reason behind these numbers. They 
> just looked ok after a couple of test runs. (Maybe they make sense for 
> shorter arg names, like the 66 for 3 char long names.)
In [Rice2017], the inflexion point of the precision/recall plot is at around 
`0.55`-ish threshold. They express this threshold as the distance of distances, 
i.e. `0` would mean the (a1, p1) - (a2, p2) pair is good as it is, and `1` 
would mean that it should **definitely** be (a2, p1) - (a1, p2) instead. 



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:347
+// Checks whether ArgType converts implicitly to ParamType.
+static bool areTypesCompatible(QualType ArgType, QualType ParamType,
+   const ASTContext ) {

whisperity wrote:
> aaron.ballman wrote:
> > It seems like we're doing an awful lot of the same work as 
> > `ASTContext::typesAreCompatible()` and type compatibility rules are pretty 
> > complex, so I worry about this implementation being different than the 
> > `ASTContext` implementation. Have you explored whether we can reuse more of 
> > the logic from `ASTContext` here, or are they doing fundamentally different 
> > kinds of type compatibility checks?
> No, I didn't know that function even existed. This check must be older than 
> that function.
Actually, no, that function is pretty old... However, that function, and all 
the function it subsequently calls, require a **non-const** `ASTContext`. I 
have changed `ASTContext`:

```
╰─ git diff --cached --stat
 clang/include/clang/AST/ASTContext.h | 67 
---
 clang/lib/AST/ASTContext.cpp | 72 
+---
 2 files changed, 73 insertions(+), 66 deletions(-)
```

making related member functions and internal static functions take `const 
ASTContext &`/`*`.

This, by itself, did not break any of the tests of `check-clang 
check-clang-unit check-clang-tools check-clang-extra-unit`!



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:347-349
+static bool areTypesCompatible(QualType ArgType, QualType ParamType,
+   const ASTContext ) {
+  if (ArgType.isNull() || ParamType.isNull())

whisperity wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > It seems like we're doing an awful lot of the same work as 
> > > `ASTContext::typesAreCompatible()` and type compatibility rules are 
> > > pretty complex, so I worry about this implementation being different than 
> > > the `ASTContext` implementation. Have you 

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331532.
whisperity marked 3 inline comments as done.
whisperity added a comment.

**NFC** Made the code more legible, updated and clarified some comments, fixed 
grammar issues.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,468 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+}
+
+// Test cases for multilevel pointers.
+void multilevel_pointer_parameters(int *const **pp,
+   const int *const *volatile const *qq);
+void multilevel_pointer_parameters2(
+char *nn, char *volatile *const *const *const *const );
+
+typedef float T;
+typedef T *S;
+typedef S *const volatile R;
+typedef R *Q;
+typedef Q *P;
+typedef P *O;
+void multilevel_pointer_parameters3(float **const volatile ***rr, O );
+
+void multilevel_pointer_swap() {
+  int *const **qq;
+  int *const **pp;
+  multilevel_pointer_parameters(qq, pp);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qq' (passed to 'pp') looks like it might be swapped with the 2nd, 'pp' (passed to 'qq')
+
+  char *mm;
+  char *nn;
+  

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-18 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 8 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:51
+{true, 40, 50}, // Substring.
+{true, 50, 66}, // Levenshtein.
+{true, 75, 85}, // Jaro-Winkler.

aaron.ballman wrote:
> We should probably document where all these numbers come from, but `66` 
> definitely jumps out at me as being a bit strange. :-D
Unfortunately, I have absolutely no idea. All these values are percentages 
between 0 and 100 (`-1` is just saying that //"This heuristic doesn't accept 
percentages"//), and this is written in the documentation now. However, the 
answer to //"**why** 66%?"//, unless @varjujan can say something, I think is 
lost to history...

I'll read over his thesis once again, maybe I can find anything with regards to 
this.

Either way, I've detailed from both the code and the thesis how the percentages 
are meant. In some cases, the % is calculated as //"% of the longer string's 
length"//. In the Leventhstein's case, it's actually inverted:

```
Dist = (1 - Dist / LongerLength) * 100;
```

So what this says is that if the current arg1-param1 arg2-param2 pairing has 
less than the inverse of 50% (which is more than 50%) of the longer string's 
edit distance, but the arg2-param1 and arg1-param2 (the suggested swapped 
order) has more than the inverse of 66% (which is less than 33%), then the swap 
will be suggested.

Originally these values were called `LowerBound` and `UpperBound`, 
respectively, which was saying **even less** about what they mean...



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:271-272
+
+// Checks whether ArgType is an array type identical to ParamType`s array type.
+// Enforces array elements` qualifier compatibility as well.
+static bool isCompatibleWithArrayReference(const QualType ,

aaron.ballman wrote:
> 
Good catch! I believe this is what happens when you write LaTeX and code at the 
same time? I didn't notice this when I was tidying up the code...



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:347
+// Checks whether ArgType converts implicitly to ParamType.
+static bool areTypesCompatible(QualType ArgType, QualType ParamType,
+   const ASTContext ) {

aaron.ballman wrote:
> It seems like we're doing an awful lot of the same work as 
> `ASTContext::typesAreCompatible()` and type compatibility rules are pretty 
> complex, so I worry about this implementation being different than the 
> `ASTContext` implementation. Have you explored whether we can reuse more of 
> the logic from `ASTContext` here, or are they doing fundamentally different 
> kinds of type compatibility checks?
No, I didn't know that function even existed. This check must be older than 
that function.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity marked 2 inline comments as done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:529
+/// ReturnStmts return them from the function.
+class Returned {
+  llvm::SmallVector 
ReturnedParams;

aaron.ballman wrote:
> Question: would it make sense to (someday, not now) consider output 
> parameters similar to return statements? e.g.,
> ```
> void int_swap(int , int ) {
>   int temp = foo;
>   foo = bar;
>   bar = temp;
> }
> ```
> As a question for today: should `co_return` should be handled similarly as 
> `return`?
1. Maybe. Unfortunately, one needs to be careful with that. Originally I did 
implement a "5th" heuristic that dealt with ignoring parameters that had the 
same builtin operator used on them. However, while it silenced a few false 
positives, it started creating **massive** amounts of false negatives.
(In the concrete example, I think `foo = bar` will silence them because 
//"appears in the same expression"//.)

2. I don't know. It would require a deeper understanding of Coroutines 
themselves, and how people use them.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:563-566
+  llvm::Optional SameExpr;
+  llvm::Optional PassToFun;
+  llvm::Optional SameMember;
+  llvm::Optional Returns;

aaron.ballman wrote:
> I don't think there's a need to make these optional when we're using the 
> `Enabled` flag.
The original idea was that each heuristic could be individually toggled by the 
user... But I think we can agree that would be a bad idea and just 
overengineering.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:529
+/// ReturnStmts return them from the function.
+class Returned {
+  llvm::SmallVector 
ReturnedParams;

whisperity wrote:
> aaron.ballman wrote:
> > Question: would it make sense to (someday, not now) consider output 
> > parameters similar to return statements? e.g.,
> > ```
> > void int_swap(int , int ) {
> >   int temp = foo;
> >   foo = bar;
> >   bar = temp;
> > }
> > ```
> > As a question for today: should `co_return` should be handled similarly as 
> > `return`?
> 1. Maybe. Unfortunately, one needs to be careful with that. Originally I did 
> implement a "5th" heuristic that dealt with ignoring parameters that had the 
> same builtin operator used on them. However, while it silenced a few false 
> positives, it started creating **massive** amounts of false negatives.
> (In the concrete example, I think `foo = bar` will silence them because 
> //"appears in the same expression"//.)
> 
> 2. I don't know. It would require a deeper understanding of Coroutines 
> themselves, and how people use them.
If you don't mind me posting images, I can show a direct example. Things where 
the inability to track data flow really bites us in the backside.

Examples from Apache Xerces:

Here's a false positive that would be silenced by the logic of //"using the 
same operateur on the two params"//.
{F15891567}

And here is a false negative from the exact same logic.
{F15891568}

Maybe it could be //some// solace that we're restricting to 
non-const-lvalue-references (and pointers-to-non-const ??) and only assignment 
(**only** assignment?!))...


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331241.
whisperity marked 6 inline comments as done.
whisperity added a subscriber: Szelethus.
whisperity added a comment.

- Add `const reverse iterator` to the default-ignored typename list.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN:  ]}' -- -x c
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+typedef bool MyBool;
+
+#define TheLogicalType bool
+
+void declVoid(void); // NO-WARN: Declaration only.
+void decl(); // NO-WARN: Declaration only.
+void oneParam(int I) {}  // NO-WARN: 1 parameter.
+void variadic(int I, ...) {} // NO-WARN: 1 visible parameter.
+
+void trivial(int I, int J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'trivial' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'J'
+
+void qualifier(int I, const int CI) {} // NO-WARN: Distinct types.
+
+void restrictQualifier(char *restrict CPR1, char *restrict CPR2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 2 adjacent parameters of 'restrictQualifier' of similar type ('char *restrict')
+// CHECK-MESSAGES: :[[@LINE-2]]:39: note: the first parameter in the range is 'CPR1'
+// CHECK-MESSAGES: :[[@LINE-3]]:60: note: the last parameter in the range is 'CPR2'
+
+void pointer1(int *IP1, int *IP2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 2 adjacent parameters of 'pointer1' of similar type ('int *')
+// CHECK-MESSAGES: :[[@LINE-2]]:20: note: the first parameter in the range is 'IP1'
+// CHECK-MESSAGES: :[[@LINE-3]]:30: note: the last parameter in the range is 'IP2'
+
+void pointerConversion(int *IP, long *LP) {}
+// NO-WARN: Even though C can convert any T* to U* back and forth, compiler
+// warnings already exist for this.
+
+void testVariadicsCall() {
+  int IVal = 1;
+  decl(IVal); // NO-WARN: Particular calls to "variadics" are like template
+  // instantiations, and we do not model them.
+
+  variadic(IVal);  // NO-WARN.
+  variadic(IVal, 2, 3, 4); // NO-WARN.
+}
+
+struct S {};
+struct T {};
+
+void taggedTypes1(struct S SVar, struct T TVar) {} // NO-WARN: Distinct types.
+
+void taggedTypes2(struct S SVar1, struct S SVar2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 2 adjacent parameters of 'taggedTypes2' of similar type ('struct S')
+// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'SVar1'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: note: the last parameter in the range is 'SVar2'
+
+void wrappers(struct { int I; } I1, struct { int I; } I2) {} // NO-WARN: Distinct anonymous types.
+
+void knr(I, J)
+  int I;
+  int J;
+{}
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 2 adjacent parameters of 'knr' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-4]]:7: note: the last parameter in the range is 'J'
+
+void boolAsWritten(bool B1, bool B2) {} // NO-WARN: The type name is ignored.
+// Note that "bool" is a macro that expands to "_Bool" internally, but it is
+// only "bool" that is ignored from the two.
+
+void underscoreBoolAsWritten(_Bool B1, _Bool B2) {}
+// Even though it is "_Bool" that is written in the code, the diagnostic message
+// 

[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331242.
whisperity marked 4 inline comments as done.
whisperity added a comment.

- Made the diagnostic message about "binding power" easier to understand.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95736/new/

https://reviews.llvm.org/D95736

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
@@ -111,20 +111,38 @@
 // CHECK-MESSAGES: :[[@LINE-2]]:32: note: the first parameter in the range is 'I1'
 // CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'I2'
 
-void throughTypedef(int I, MyInt1 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'throughTypedef' of similar type ('int')
-// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:35: note: the last parameter in the range is 'J'
+void typedefMultiple(MyInt1 I1, MyInt2 I2x, MyInt2 I2y) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 adjacent parameters of 'typedefMultiple' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I1'
+// CHECK-MESSAGES: :[[@LINE-3]]:52: note: the last parameter in the range is 'I2y'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+void throughTypedef1(int I, MyInt1 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'throughTypedef1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:26: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:36: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+
+void betweenTypedef2(MyInt1 I, MyInt2 J) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 2 adjacent parameters of 'betweenTypedef2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:29: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:39: note: the last parameter in the range is 'J'
+// CHECK-MESSAGES: :[[@LINE-4]]:22: note: after resolving type aliases, the common type of 'MyInt1' and 'MyInt2' is 'int'
+
+typedef MyInt2 MyInt2b;
 
-void betweenTypedef(MyInt1 I, MyInt2 J) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 2 adjacent parameters of 'betweenTypedef' of similar type ('MyInt1')
-// CHECK-MESSAGES: :[[@LINE-2]]:28: note: the first parameter in the range is 'I'
-// CHECK-MESSAGES: :[[@LINE-3]]:38: note: the last parameter in the range is 'J'
+void typedefChain(int I, MyInt1 MI1, MyInt2 MI2, MyInt2b MI2b) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 4 adjacent parameters of 'typedefChain' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:23: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:58: note: the last parameter in the range is 'MI2b'
+// CHECK-MESSAGES: :[[@LINE-4]]:19: note: after resolving type aliases, 'int' and 'MyInt1' are the same
+// CHECK-MESSAGES: :[[@LINE-5]]:19: note: after resolving type aliases, 'int' and 'MyInt2' are the same
+// CHECK-MESSAGES: :[[@LINE-6]]:19: note: after resolving type aliases, 'int' and 'MyInt2b' are the same
 
 typedef long MyLong1;
 using MyLong2 = long;
 
-void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: Not the same type.
+void throughTypedefToOtherType(MyInt1 I, MyLong1 J) {} // NO-WARN: int and long.
 
 void qualified1(int I, const int CI) {} // NO-WARN: Not the same type.
 
@@ -138,18 +156,73 @@
 
 void qualifiedThroughTypedef1(int I, CInt CI) {} // NO-WARN: Not the same type.
 
-void qualifiedThroughTypedef2(CInt CI1, const int CI2) {} // NO-WARN: Not the same type.
-// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type ('CInt')
+void qualifiedThroughTypedef2(CInt CI1, const int CI2) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 2 adjacent parameters of 'qualifiedThroughTypedef2' of similar type are
 // CHECK-MESSAGES: :[[@LINE-2]]:36: note: the first parameter in the range is 'CI1'
 // CHECK-MESSAGES: :[[@LINE-3]]:51: note: the last parameter in the range is 'CI2'
-
-void reference1(int I, int ) {} // NO-WARN: Not the same type.
-
-void reference2(int I, const int ) {} // NO-WARN: Not the same type.
-
-void reference3(int I, int &) {} // NO-WARN: Not the same type.
-
-void reference4(int I, const int &) {} // NO-WARN: Not the same type.
+// 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:363
+/// Returns the diagnostic-friendly name of the node, or empty string.
+static SmallString<64> getName(const NamedDecl *ND) {
+  SmallString<64> Name;

whisperity wrote:
> aaron.ballman wrote:
> > Is this still needed in light of the comments from @riccibruno?
> It doesn't look like to me as if those patches they commented were ever 
> merged, but I'll check it out.
I checked at they haven't been merged yet. Nonetheless, we can remove this 
logic later once that logic is in.

I added a test case for unnamed parameters with the current logic printing 
``, so if the underlying call will return something like `` we will know because that test will blow up.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not respecting and highlighting fed SourceRanges

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331193.
whisperity marked 4 inline comments as done.
whisperity added a comment.

**[NFC]** Fixed nits and code formatting.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98635/new/

https://reviews.llvm.org/D98635

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/infrastructure/export-diagnostics.cpp
  clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
  clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
  clang/include/clang/Tooling/Core/Diagnostic.h
  clang/include/clang/Tooling/DiagnosticsYaml.h
  clang/lib/Tooling/Core/Diagnostic.cpp
  clang/unittests/Tooling/DiagnosticsYamlTest.cpp

Index: clang/unittests/Tooling/DiagnosticsYamlTest.cpp
===
--- clang/unittests/Tooling/DiagnosticsYamlTest.cpp
+++ clang/unittests/Tooling/DiagnosticsYamlTest.cpp
@@ -20,14 +20,16 @@
 using namespace clang::tooling;
 using clang::tooling::Diagnostic;
 
-static DiagnosticMessage makeMessage(const std::string , int FileOffset,
- const std::string ,
- const StringMap ) {
+static DiagnosticMessage
+makeMessage(const std::string , int FileOffset,
+const std::string , const StringMap ,
+const SmallVector ) {
   DiagnosticMessage DiagMessage;
   DiagMessage.Message = Message;
   DiagMessage.FileOffset = FileOffset;
   DiagMessage.FilePath = FilePath;
   DiagMessage.Fix = Fix;
+  DiagMessage.Ranges = Ranges;
   return DiagMessage;
 }
 
@@ -47,8 +49,8 @@
  const StringMap ,
  const SmallVector ) {
   return Diagnostic(DiagnosticName,
-makeMessage(Message, FileOffset, FilePath, Fix), {},
-Diagnostic::Warning, "path/to/build/directory", Ranges);
+makeMessage(Message, FileOffset, FilePath, Fix, Ranges), {},
+Diagnostic::Warning, "path/to/build/directory");
 }
 
 static const char *YAMLContent =
@@ -77,12 +79,12 @@
 "  Offset:  62\n"
 "  Length:  2\n"
 "  ReplacementText: 'replacement #2'\n"
+"  Ranges:\n"
+"- FilePath:'path/to/source.cpp'\n"
+"  FileOffset:  10\n"
+"  Length:  10\n"
 "Level:   Warning\n"
 "BuildDirectory:  'path/to/build/directory'\n"
-"Ranges:\n"
-"  - FilePath:'path/to/source.cpp'\n"
-"FileOffset:  10\n"
-"Length:  10\n"
 "  - DiagnosticName:  'diagnostic#3'\n"
 "DiagnosticMessage:\n"
 "  Message: 'message #3'\n"
@@ -123,9 +125,9 @@
   TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
"path/to/source2.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note1", 88, "path/to/note1.cpp", {}));
+  makeMessage("Note1", 88, "path/to/note1.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note2", 99, "path/to/note2.cpp", {}));
+  makeMessage("Note2", 99, "path/to/note2.cpp", {}, {}));
 
   std::string YamlContent;
   raw_string_ostream YamlContentStream(YamlContent);
@@ -166,7 +168,7 @@
   EXPECT_EQ(100u, Fixes1[0].getOffset());
   EXPECT_EQ(12u, Fixes1[0].getLength());
   EXPECT_EQ("replacement #1", Fixes1[0].getReplacementText());
-  EXPECT_TRUE(D1.Ranges.empty());
+  EXPECT_TRUE(D1.Message.Ranges.empty());
 
   Diagnostic D2 = TUDActual.Diagnostics[1];
   EXPECT_EQ("diagnostic#2", D2.DiagnosticName);
@@ -179,10 +181,10 @@
   EXPECT_EQ(62u, Fixes2[0].getOffset());
   EXPECT_EQ(2u, Fixes2[0].getLength());
   EXPECT_EQ("replacement #2", Fixes2[0].getReplacementText());
-  EXPECT_EQ(1u, D2.Ranges.size());
-  EXPECT_EQ("path/to/source.cpp", D2.Ranges[0].FilePath);
-  EXPECT_EQ(10u, D2.Ranges[0].FileOffset);
-  EXPECT_EQ(10u, D2.Ranges[0].Length);
+  EXPECT_EQ(1u, D2.Message.Ranges.size());
+  EXPECT_EQ("path/to/source.cpp", D2.Message.Ranges[0].FilePath);
+  EXPECT_EQ(10u, D2.Message.Ranges[0].FileOffset);
+  EXPECT_EQ(10u, D2.Message.Ranges[0].Length);
 
   Diagnostic D3 = TUDActual.Diagnostics[2];
   EXPECT_EQ("diagnostic#3", D3.DiagnosticName);
@@ -198,5 +200,5 @@
   EXPECT_EQ("path/to/note2.cpp", D3.Notes[1].FilePath);
   std::vector Fixes3 = getFixes(D3.Message.Fix);
   EXPECT_TRUE(Fixes3.empty());
-  EXPECT_TRUE(D3.Ranges.empty());
+  EXPECT_TRUE(D3.Message.Ranges.empty());
 }
Index: clang/lib/Tooling/Core/Diagnostic.cpp
===
--- clang/lib/Tooling/Core/Diagnostic.cpp
+++ clang/lib/Tooling/Core/Diagnostic.cpp
@@ -53,10 +53,9 

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331244.
whisperity marked 4 inline comments as done.
whisperity added a comment.

- Added some test cases to ensure edge cases won't crash.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.c
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-relatedness.cpp
@@ -0,0 +1,229 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1} \
+// RUN:  ]}' --
+
+namespace std {
+template 
+T max(const T , const T );
+} // namespace std
+
+bool coin();
+void f(int);
+void g(int);
+void h(int, int);
+void i(int, bool);
+void i(int, char);
+
+struct Tmp {
+  int f(int);
+  int g(int, int);
+};
+
+struct Int {
+  int I;
+};
+
+void compare(int Left, int Right) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'compare' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Left'
+// CHECK-MESSAGES: :[[@LINE-3]]:28: note: the last parameter in the range is 'Right'
+
+int decideSequence(int A, int B) {
+  if (A)
+return 1;
+  if (B)
+return 2;
+  return 3;
+}
+// CHECK-MESSAGES: :[[@LINE-7]]:20: warning: 2 adjacent parameters of 'decideSequence' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-8]]:24: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-9]]:31: note: the last parameter in the range is 'B'
+
+int myMax(int A, int B) { // NO-WARN: Appears in same expression.
+  return A < B ? A : B;
+}
+
+int myMax2(int A, int B) { // NO-WARN: Appears in same expression.
+  if (A < B)
+return A;
+  return B;
+}
+
+int myMax3(int A, int B) { // NO-WARN: Appears in same expression.
+  return std::max(A, B);
+}
+
+int binaryToUnary(int A, int) {
+  return A;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: 2 adjacent parameters of 'binaryToUnary' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-4]]:23: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-5]]:29: note: the last parameter in the range is ''
+
+int randomReturn1(int A, int B) { // NO-WARN: Appears in same expression.
+  return coin() ? A : B;
+}
+
+int randomReturn2(int A, int B) { // NO-WARN: Both parameters returned.
+  if (coin())
+return A;
+  return B;
+}
+
+int randomReturn3(int A, int B) { // NO-WARN: Both parameters returned.
+  bool Flip = coin();
+  if (Flip)
+return A;
+  Flip = coin();
+  if (Flip)
+return B;
+  Flip = coin();
+  if (!Flip)
+return 0;
+  return -1;
+}
+
+void passthrough1(int A, int B) { // WARN: 

[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:481
+
+  assert(TargetIdx.hasValue() && "Matched, but didn't find index?");
+  TargetParams[PassedParamOfThisFn].insert(

whisperity wrote:
> aaron.ballman wrote:
> > I *think* you could run into this assert with K C function where there is 
> > a `FunctionDecl` to get back to but the decl claims it has no params 
> > because it has no prototype (while the call expression actually has the 
> > arguments). However, there may be other code that protects us from this 
> > case.
> At face value, I would say the fact that a K function //has no params// 
> declared means that the matcher above will not be able to do 
> `forEachArgumentWithParam`, because the argument vector is N long, but the 
> parameter vector is empty.
> 
> Nevertheless, it won't hurt to add a test case for this though.
No assertion, no crash. But unfortunately, we generate a false positive. But we 
don't crash. I added a test for this, just in case.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:532-536
+  if (find(FD->parameters(), ReturnedParam) == FD->param_end())
+// Returning an Expr to a ParmVarDecl that **isn't** parameter of the
+// function should not be possible. Make sure a mistake of the matcher
+// does **not** interfere with the heuristic's result.
+continue;

whisperity wrote:
> aaron.ballman wrote:
> > Is this a FIXME because there's a matcher issue this works around or should 
> > it be an assertion?
> I was unable to create a test for this case. This part of the code, while I 
> was twisting my head left and right, is one of the strictest remnant of the 
> old version of the check... There definitely was a project in the test set 
> back in December 2019 which made the check crash or emit massive false 
> positives, and this thing was added to guard against that.
> 
> At a hunch, I think //maybe// a lambda returning one of its captures (which 
> are, AFAIK, `ParmVarDecl`s of the constructor!) could be what caused the 
> crash/false positive. I will check this out in detail soon.
I do not remember why I thought this makes crashes because I tried and no 
crashing now (which is good), but lambdas defined inside a function's body is 
definitely a good reproducer for when this is hit.

Rephrased the comment, and added a test about this.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331243.
whisperity marked 6 inline comments as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96355/new/

https://reviews.llvm.org/D96355

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-qualifiermixing.cpp
@@ -0,0 +1,112 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 1} \
+// RUN:  ]}' --
+
+typedef int MyInt1;
+typedef int MyInt2;
+using CInt = const int;
+using CMyInt1 = const MyInt1;
+using CMyInt2 = const MyInt2;
+
+void qualified1(int I, const int CI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified1' of similar type are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:34: note: the last parameter in the range is 'CI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const int' parameters accept and bind the same kind of values
+
+void qualified2(int I, volatile int VI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified2' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'VI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'volatile int' parameters accept and bind the same kind of values
+
+void qualified3(int I, const volatile int CVI) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified3' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:21: note: the first parameter in the range is 'I'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: note: the last parameter in the range is 'CVI'
+// CHECK-MESSAGES: :[[@LINE-4]]:24: note: 'int' and 'const volatile int' parameters accept and bind the same kind of values
+
+void qualified4(int *IP, const int *CIP) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 2 adjacent parameters of 'qualified4' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:22: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:37: note: the last parameter in the range is 'CIP'
+// CHECK-MESSAGES: :[[@LINE-4]]:26: note: 'int *' and 'const int *' parameters accept and bind the same kind of values
+
+void qualified5(const int CI, const long CL) {} // NO-WARN: Not the same type
+
+void qualifiedPtr1(int *IP, int *const IPC) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 2 adjacent parameters of 'qualifiedPtr1' of similar type are
+// CHECK-MESSAGES: :[[@LINE-2]]:25: note: the first parameter in the range is 'IP'
+// CHECK-MESSAGES: :[[@LINE-3]]:40: note: the last 

[PATCH] D97297: [clang-tidy] Suppress reports to patternedly named parameters in 'bugprone-easily-swappable-parameters'

2021-03-17 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 331245.
whisperity marked 5 inline comments as done.
whisperity added a comment.

- Made a precondition check explicit, and added an early `return` to not 
evaluate a case where it would return `false` anyways...


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97297/new/

https://reviews.llvm.org/D97297

Files:
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-easily-swappable-parameters.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-ignore.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len2.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-len3.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-prefixsuffixname.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters.c
@@ -2,7 +2,8 @@
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
-// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"} \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: "bool;MyBool;struct U;MAKE_LOGICAL_TYPE(int)"}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
 // RUN:  ]}' -- -x c
 
 #define bool _Bool
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-prefixsuffixname.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-easily-swappable-parameters-prefixsuffixname.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
+// RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 1} \
+// RUN:  ]}' --
+
+namespace std {
+struct string {};
+} // namespace std
+class Matrix {};
+
+void test1(int Foo, int Bar) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 2 adjacent parameters of 'test1' of similar type ('int') are easily swapped by mistake [bugprone-easily-swappable-parameters]
+// CHECK-MESSAGES: :[[@LINE-2]]:16: note: the first parameter in the range is 'Foo'
+// CHECK-MESSAGES: :[[@LINE-3]]:25: note: the last parameter in the range is 'Bar'
+
+void test2(int A, int B) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 2 adjacent parameters of 'test2' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:16: note: the first parameter in the range is 'A'
+// CHECK-MESSAGES: :[[@LINE-3]]:23: note: the last parameter in the range is 'B'
+
+void test3(int Val1, int Val2) {} // NO-WARN.
+
+void test4(int ValA, int Valb) {} // NO-WARN.
+
+void test5(int Val1, int ValZ) {} // NO-WARN.
+
+void test6(int PValue, int QValue) {} // NO-WARN.
+
+void test7(std::string Astr, std::string Bstr) {} // NO-WARN.
+
+void test8(int Aladdin, int Alabaster) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 2 adjacent parameters of 'test8' of similar type ('int')
+// CHECK-MESSAGES: :[[@LINE-2]]:16: note: the first parameter in the range is 'Aladdin'
+// CHECK-MESSAGES: :[[@LINE-3]]:29: note: the last parameter in the range is 'Alabaster'
+
+void test9(Matrix Qmat, Matrix Rmat, Matrix Tmat) {} // NO-WARN.
+
+void test10(int Something, int Other, int Foo, int Bar1, int Bar2, int Baz, int Qux) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: 4 adjacent parameters of 'test10' of similar type ('int') are
+// CHECK-MESSAGES: :[[@LINE-2]]:17: note: the first parameter in the range is 'Something'
+// CHECK-MESSAGES: :[[@LINE-3]]:52: note: the last parameter in the range is 'Bar1'
+//
+// CHECK-MESSAGES: :[[@LINE-5]]:58: warning: 3 adjacent parameters of 'test10' of similar type ('int') are
+// CHECK-MESSAGES: :[[@LINE-6]]:62: note: the first parameter in the range is 'Bar2'
+// CHECK-MESSAGES: :[[@LINE-7]]:81: note: the last parameter in the range is 'Qux'
+
+void test11(int Foobar, int 

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-10 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 329666.
whisperity edited the summary of this revision.
whisperity added reviewers: hokein, njames93.
whisperity added a comment.

- Massively refactored and modernised the implementation
- Removed spaghetti code related to the check options and made their storage 
and defaults clearer
- Fixed modelling issues that caused false positives around lambdas, overloaded 
call operators, recursive calls, enumconstant arguments
- Made the abbreviation dictionary for the //Abbreviations// heuristic a 
check-option
- Made the check message much more legible
- Fixed a severe modelling issue about not respecting or handling record types 
passed by copy (`CXXConstructExpr`)
- Wrote the documentation for real, including all heuristics, default values, 
options, etc. The original documentation was basically empty. For the docs, I 
used @varjujan's thesis (which subject was this check), which is unfortunately 
only available in Hungarian, but it helped me understand what some of the enums 
and the //Bound// doing on the inside.
- Thanks to having written a proper documentation, I also renamed a few symbols 
and check options to better tell what they are about.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D20689/new/

https://reviews.llvm.org/D20689

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/docs/clang-tidy/checks/readability-suspicious-call-argument.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-suspicious-call-argument.cpp
@@ -0,0 +1,468 @@
+// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11
+
+void foo_1(int aa, int bb) {}
+
+void foo_2(int source, int aa) {}
+
+void foo_3(int valToRet, int aa) {}
+
+void foo_4(int pointer, int aa) {}
+
+void foo_5(int aa, int bb, int cc, ...) {}
+
+void foo_6(const int dd, bool ) {}
+
+void foo_7(int aa, int bb, int cc, int ff = 7) {}
+
+// Test functions for convertible argument--parameter types.
+void fun(const int );
+void fun2() {
+  int m = 3;
+  fun(m);
+}
+
+// Test cases for parameters of const reference and value.
+void value_const_reference(int ll, const int );
+
+void const_ref_value_swapped() {
+  const int  = 42;
+  const int  = 42;
+  value_const_reference(kk, ll);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kk' (passed to 'll') looks like it might be swapped with the 2nd, 'll' (passed to 'kk') [readability-suspicious-call-argument]
+  // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here
+}
+
+// Const, non const references.
+void const_nonconst_parameters(const int , int );
+
+void const_nonconst_swap1() {
+  const int  = 42;
+  int mm;
+  // Do not check, because non-const reference parameter cannot bind to const reference argument.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap3() {
+  const int nn = 42;
+  int m = 42;
+  int  = m;
+  // Do not check, const int does not bind to non const reference.
+  const_nonconst_parameters(nn, mm);
+}
+
+void const_nonconst_swap2() {
+  int nn;
+  int mm;
+  // Check for swapped arguments. (Both arguments are non-const.)
+  const_nonconst_parameters(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+void const_nonconst_pointers(const int *mm, int *nn);
+void const_nonconst_pointers2(const int *mm, const int *nn);
+
+void const_nonconst_pointers_swapped() {
+  int *mm;
+  const int *nn;
+  const_nonconst_pointers(nn, mm);
+}
+
+void const_nonconst_pointers_swapped2() {
+  const int *mm;
+  int *nn;
+  const_nonconst_pointers2(nn, mm);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nn' (passed to 'mm') looks like it might be swapped with the 2nd, 'mm' (passed to 'nn')
+}
+
+// Test cases for pointers and arrays.
+void pointer_array_parameters(
+int *pp, int qq[4]);
+
+void pointer_array_swap() {
+  int qq[5];
+  int *pp;
+  // Check for swapped arguments. An array implicitly converts to a pointer.
+  pointer_array_parameters(qq, pp);
+  // CHECK-MESSAGES: 

[PATCH] D20689: [clang-tidy] Add 'readability-suspicious-call-argument' check

2021-03-19 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp:347
+// Checks whether ArgType converts implicitly to ParamType.
+static bool areTypesCompatible(QualType ArgType, QualType ParamType,
+   const ASTContext ) {

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > whisperity wrote:
> > > > whisperity wrote:
> > > > > aaron.ballman wrote:
> > > > > > It seems like we're doing an awful lot of the same work as 
> > > > > > `ASTContext::typesAreCompatible()` and type compatibility rules are 
> > > > > > pretty complex, so I worry about this implementation being 
> > > > > > different than the `ASTContext` implementation. Have you explored 
> > > > > > whether we can reuse more of the logic from `ASTContext` here, or 
> > > > > > are they doing fundamentally different kinds of type compatibility 
> > > > > > checks?
> > > > > No, I didn't know that function even existed. This check must be 
> > > > > older than that function.
> > > > Actually, no, that function is pretty old... However, that function, 
> > > > and all the function it subsequently calls, require a **non-const** 
> > > > `ASTContext`. I have changed `ASTContext`:
> > > > 
> > > > ```
> > > > ╰─ git diff --cached --stat
> > > >  clang/include/clang/AST/ASTContext.h   
> > > >   | 67 
> > > > ---
> > > >  clang/lib/AST/ASTContext.cpp   
> > > >   | 72 
> > > > +---
> > > >  2 files changed, 73 insertions(+), 66 deletions(-)
> > > > ```
> > > > 
> > > > making related member functions and internal static functions take 
> > > > `const ASTContext &`/`*`.
> > > > 
> > > > This, by itself, did not break any of the tests of `check-clang 
> > > > check-clang-unit check-clang-tools check-clang-extra-unit`!
> > > Doubtful -- `typesAreCompatible()` is critical for checking the semantics 
> > > of assignment in C, overloading in C++, etc. It may have simply been 
> > > overlooked when writing this check. Given the complexities of type 
> > > checking, my intuition is that we should be leaning on `ASTContext` for 
> > > as much of this functionality as we can get away with. That will also get 
> > > us nice "extras" like caring about address spaces, ARC, etc which are 
> > > what got me worried when I started looking at this implementation.
> > @aaron.ballman Changing the function to be 
> > 
> > ```
> > return Ctx.typesAreCompatible(ArgType, ParamType);
> > ```
> > 
> > will make the checker miss the test case about `T`/`const T&` mixup.
> > 
> > ```
> > void value_const_reference(int ll, const int& kk);
> > void const_ref_value_swapped() {
> >   const int& kk = 42;
> >   const int& ll = 42;
> >   value_const_reference(kk, ll);
> >   // error: CHECK-MESSAGES: expected string not found in input:
> >   // warning: 1st argument 'kk' (passed to 'll') looks like it 
> > might be swapped with the 2nd, 'll' (passed to 'kk')
> > }
> > ```
> > 
> > 
> > 
> > Setting `bool CompareUnqualified = true` (3rd argument to 
> > `typesAreCompatible`) doesn't help either.
> > Which is valid from `typesAreCompatible`'s perspective... that function 
> > answer the question, applied to the context of the above test: //"Is 
> > `ll = kk;` valid?"//, which is obviously **false** as both are 
> > `const T&`s.
> Yeah, I expect there to be a delta between the work this check is doing and 
> the existing work done by `typesAreCompatible()`. However, given the 
> complexity of type compatibility checking, I'd say it's better for us to try 
> to refactor the ASTContext functionality so that we can share as much of the 
> implementation as plausible rather than duplicate some really difficult logic 
> in the tidy check.
I talked with @aaron.ballman in private about this a little, and unfortunately, 
the route to call `typesAreCompatible()` is no dice. First things first, in C++ 
mode, that function just early returns (essentially) `==` on the type. 
Otherwise, it would call `QualType ASTContext::mergeTypes(QualType, QualType, 
...)`. Okay, let's delve into this thing. Now, first things first, somewhere 
down the line if you happen to give it something C++-specific (e.g. 
`LValueReferenceType`), it will just assert into your face. (Because C++ things 
are only `compatible` if the types are equal, most likely. In C++ mode, 
`mergeType` shouldn't be, and doesn't get, called.)

But there are even more issues with this function. Put simply, it does not 
perform **any** "implicit conversions". Sic!, I'm putting it in between quotes, 
but the fact is that if one type is `const` and the other isn't, it will just 
say //"Nope, these are not compatible."//.
So modelling the whole idea of //"is 

[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not respecting and highlighting fed SourceRanges

2021-03-15 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D98635#2626464 , @whisperity wrote:

> Strange because I specifically ran both `check-clang` **and** 
> `check-clang-tools` locally, but will look into this.

Turns out there is a `check-clang-extra-unit` too, and it looks like those test 
TUs either didn't compile for me at all (as in, it was not commanded to compile 
them), or I messed something up during the rebase.
(But TIL we finally have some semblance of pre-merge checking instead of always 
reverting commits! )

'll update the patch soon. Gonna do a clean build and a clean check, //just in 
case...//.

What's the outlook on the executive decision... changing the **schema** in 
`libToolingCore`... is such even allowed? I'm venturing into parts unknown here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98635/new/

https://reviews.llvm.org/D98635

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not handlings SourceRange highlights

2021-03-15 Thread Whisperity via Phabricator via cfe-commits
whisperity created this revision.
whisperity added reviewers: aaron.ballman, njames93.
whisperity added projects: clang, clang-tools-extra.
Herald added subscribers: martong, gamesh411, Szelethus, dkrupp, rnkovacs, 
xazax.hun.
whisperity requested review of this revision.
Herald added a subscriber: cfe-commits.

> Fixes bug #49000 .

Currently, when a diagnostic in Clang-Tidy is produced as 
`diag(Var->getLocation(), "foo %0") << "bar" << Var->getSourceRange();`, the 
source range specified to be highlighted is discarded, i.e.

  x.cpp:21:18: warning: foo bar [blah-blah-checker]
  void fun(int I, int J, int K) {}
   ^

is created instead of producing a full highlight:

  x.cpp:21:18: warning: foo bar [blah-blah-checker]
  void fun(int I, int J, int K) {}
   ^

This creates a discrepancy between warnings generated in `Clang::Sema` which 
work properly, and in Tidy.
This patch fixes the issue by making sure Clang-Tidy's logic of decoupling 
ranges from the `SourceManager` and rendering them later respects custom ranges 
that are fed into a diagnostic.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98635

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/test/clang-tidy/infrastructure/export-diagnostics.cpp
  clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
  clang/include/clang/Tooling/Core/Diagnostic.h
  clang/include/clang/Tooling/DiagnosticsYaml.h
  clang/lib/Tooling/Core/Diagnostic.cpp
  clang/unittests/Tooling/DiagnosticsYamlTest.cpp

Index: clang/unittests/Tooling/DiagnosticsYamlTest.cpp
===
--- clang/unittests/Tooling/DiagnosticsYamlTest.cpp
+++ clang/unittests/Tooling/DiagnosticsYamlTest.cpp
@@ -20,14 +20,16 @@
 using namespace clang::tooling;
 using clang::tooling::Diagnostic;
 
-static DiagnosticMessage makeMessage(const std::string , int FileOffset,
- const std::string ,
- const StringMap ) {
+static DiagnosticMessage
+makeMessage(const std::string , int FileOffset,
+const std::string , const StringMap ,
+const SmallVector ) {
   DiagnosticMessage DiagMessage;
   DiagMessage.Message = Message;
   DiagMessage.FileOffset = FileOffset;
   DiagMessage.FilePath = FilePath;
   DiagMessage.Fix = Fix;
+  DiagMessage.Ranges = Ranges;
   return DiagMessage;
 }
 
@@ -47,8 +49,8 @@
  const StringMap ,
  const SmallVector ) {
   return Diagnostic(DiagnosticName,
-makeMessage(Message, FileOffset, FilePath, Fix), {},
-Diagnostic::Warning, "path/to/build/directory", Ranges);
+makeMessage(Message, FileOffset, FilePath, Fix, Ranges), {},
+Diagnostic::Warning, "path/to/build/directory");
 }
 
 static const char *YAMLContent =
@@ -77,12 +79,12 @@
 "  Offset:  62\n"
 "  Length:  2\n"
 "  ReplacementText: 'replacement #2'\n"
+"  Ranges:\n"
+"- FilePath:'path/to/source.cpp'\n"
+"  FileOffset:  10\n"
+"  Length:  10\n"
 "Level:   Warning\n"
 "BuildDirectory:  'path/to/build/directory'\n"
-"Ranges:\n"
-"  - FilePath:'path/to/source.cpp'\n"
-"FileOffset:  10\n"
-"Length:  10\n"
 "  - DiagnosticName:  'diagnostic#3'\n"
 "DiagnosticMessage:\n"
 "  Message: 'message #3'\n"
@@ -123,9 +125,9 @@
   TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
"path/to/source2.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note1", 88, "path/to/note1.cpp", {}));
+  makeMessage("Note1", 88, "path/to/note1.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note2", 99, "path/to/note2.cpp", {}));
+  makeMessage("Note2", 99, "path/to/note2.cpp", {}, {}));
 
   std::string YamlContent;
   raw_string_ostream YamlContentStream(YamlContent);
@@ -166,7 +168,7 @@
   EXPECT_EQ(100u, Fixes1[0].getOffset());
   EXPECT_EQ(12u, Fixes1[0].getLength());
   EXPECT_EQ("replacement #1", Fixes1[0].getReplacementText());
-  EXPECT_TRUE(D1.Ranges.empty());
+  EXPECT_TRUE(D1.Message.Ranges.empty());
 
   Diagnostic D2 = TUDActual.Diagnostics[1];
   EXPECT_EQ("diagnostic#2", D2.DiagnosticName);
@@ -179,10 +181,10 @@
   EXPECT_EQ(62u, Fixes2[0].getOffset());
   EXPECT_EQ(2u, Fixes2[0].getLength());
   EXPECT_EQ("replacement #2", Fixes2[0].getReplacementText());
-  EXPECT_EQ(1u, D2.Ranges.size());
-  EXPECT_EQ("path/to/source.cpp", D2.Ranges[0].FilePath);
-  EXPECT_EQ(10u, D2.Ranges[0].FileOffset);
-  

[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not handlings SourceRange highlights

2021-03-15 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 330687.
whisperity added a comment.

**NFC** I originally wrote a Release Notes entry about this, which I forgot to 
commit before I generated the patch file I uploaded, this is fixed now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98635/new/

https://reviews.llvm.org/D98635

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/infrastructure/export-diagnostics.cpp
  clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
  clang/include/clang/Tooling/Core/Diagnostic.h
  clang/include/clang/Tooling/DiagnosticsYaml.h
  clang/lib/Tooling/Core/Diagnostic.cpp
  clang/unittests/Tooling/DiagnosticsYamlTest.cpp

Index: clang/unittests/Tooling/DiagnosticsYamlTest.cpp
===
--- clang/unittests/Tooling/DiagnosticsYamlTest.cpp
+++ clang/unittests/Tooling/DiagnosticsYamlTest.cpp
@@ -20,14 +20,16 @@
 using namespace clang::tooling;
 using clang::tooling::Diagnostic;
 
-static DiagnosticMessage makeMessage(const std::string , int FileOffset,
- const std::string ,
- const StringMap ) {
+static DiagnosticMessage
+makeMessage(const std::string , int FileOffset,
+const std::string , const StringMap ,
+const SmallVector ) {
   DiagnosticMessage DiagMessage;
   DiagMessage.Message = Message;
   DiagMessage.FileOffset = FileOffset;
   DiagMessage.FilePath = FilePath;
   DiagMessage.Fix = Fix;
+  DiagMessage.Ranges = Ranges;
   return DiagMessage;
 }
 
@@ -47,8 +49,8 @@
  const StringMap ,
  const SmallVector ) {
   return Diagnostic(DiagnosticName,
-makeMessage(Message, FileOffset, FilePath, Fix), {},
-Diagnostic::Warning, "path/to/build/directory", Ranges);
+makeMessage(Message, FileOffset, FilePath, Fix, Ranges), {},
+Diagnostic::Warning, "path/to/build/directory");
 }
 
 static const char *YAMLContent =
@@ -77,12 +79,12 @@
 "  Offset:  62\n"
 "  Length:  2\n"
 "  ReplacementText: 'replacement #2'\n"
+"  Ranges:\n"
+"- FilePath:'path/to/source.cpp'\n"
+"  FileOffset:  10\n"
+"  Length:  10\n"
 "Level:   Warning\n"
 "BuildDirectory:  'path/to/build/directory'\n"
-"Ranges:\n"
-"  - FilePath:'path/to/source.cpp'\n"
-"FileOffset:  10\n"
-"Length:  10\n"
 "  - DiagnosticName:  'diagnostic#3'\n"
 "DiagnosticMessage:\n"
 "  Message: 'message #3'\n"
@@ -123,9 +125,9 @@
   TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
"path/to/source2.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note1", 88, "path/to/note1.cpp", {}));
+  makeMessage("Note1", 88, "path/to/note1.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note2", 99, "path/to/note2.cpp", {}));
+  makeMessage("Note2", 99, "path/to/note2.cpp", {}, {}));
 
   std::string YamlContent;
   raw_string_ostream YamlContentStream(YamlContent);
@@ -166,7 +168,7 @@
   EXPECT_EQ(100u, Fixes1[0].getOffset());
   EXPECT_EQ(12u, Fixes1[0].getLength());
   EXPECT_EQ("replacement #1", Fixes1[0].getReplacementText());
-  EXPECT_TRUE(D1.Ranges.empty());
+  EXPECT_TRUE(D1.Message.Ranges.empty());
 
   Diagnostic D2 = TUDActual.Diagnostics[1];
   EXPECT_EQ("diagnostic#2", D2.DiagnosticName);
@@ -179,10 +181,10 @@
   EXPECT_EQ(62u, Fixes2[0].getOffset());
   EXPECT_EQ(2u, Fixes2[0].getLength());
   EXPECT_EQ("replacement #2", Fixes2[0].getReplacementText());
-  EXPECT_EQ(1u, D2.Ranges.size());
-  EXPECT_EQ("path/to/source.cpp", D2.Ranges[0].FilePath);
-  EXPECT_EQ(10u, D2.Ranges[0].FileOffset);
-  EXPECT_EQ(10u, D2.Ranges[0].Length);
+  EXPECT_EQ(1u, D2.Message.Ranges.size());
+  EXPECT_EQ("path/to/source.cpp", D2.Message.Ranges[0].FilePath);
+  EXPECT_EQ(10u, D2.Message.Ranges[0].FileOffset);
+  EXPECT_EQ(10u, D2.Message.Ranges[0].Length);
 
   Diagnostic D3 = TUDActual.Diagnostics[2];
   EXPECT_EQ("diagnostic#3", D3.DiagnosticName);
@@ -198,5 +200,5 @@
   EXPECT_EQ("path/to/note2.cpp", D3.Notes[1].FilePath);
   std::vector Fixes3 = getFixes(D3.Message.Fix);
   EXPECT_TRUE(Fixes3.empty());
-  EXPECT_TRUE(D3.Ranges.empty());
+  EXPECT_TRUE(D3.Message.Ranges.empty());
 }
Index: clang/lib/Tooling/Core/Diagnostic.cpp
===
--- clang/lib/Tooling/Core/Diagnostic.cpp
+++ clang/lib/Tooling/Core/Diagnostic.cpp
@@ -53,10 +53,9 @@
 

[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not respecting and highlighting fed SourceRanges

2021-03-15 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D98635#2626455 , @aaron.ballman 
wrote:

> It looks like there are some unit test failures from the change: 
> https://buildkite.com/llvm-project/premerge-checks/builds/29754#a9b04ab5-e326-4ff1-beea-773f21a33349

Strange because I specifically ran both `check-clang` **and** 
`check-clang-tools` locally, but will look into this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98635/new/

https://reviews.llvm.org/D98635

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98635: [libtooling][clang-tidy] Fix diagnostics not respecting and highlighting fed SourceRanges

2021-03-15 Thread Whisperity via Phabricator via cfe-commits
whisperity updated this revision to Diff 330737.
whisperity edited the summary of this revision.
whisperity added a subscriber: compositeprimes.
whisperity added a comment.

Fixed a test file that I originally missed to align with the changes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98635/new/

https://reviews.llvm.org/D98635

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/infrastructure/export-diagnostics.cpp
  clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
  clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
  clang/include/clang/Tooling/Core/Diagnostic.h
  clang/include/clang/Tooling/DiagnosticsYaml.h
  clang/lib/Tooling/Core/Diagnostic.cpp
  clang/unittests/Tooling/DiagnosticsYamlTest.cpp

Index: clang/unittests/Tooling/DiagnosticsYamlTest.cpp
===
--- clang/unittests/Tooling/DiagnosticsYamlTest.cpp
+++ clang/unittests/Tooling/DiagnosticsYamlTest.cpp
@@ -20,14 +20,16 @@
 using namespace clang::tooling;
 using clang::tooling::Diagnostic;
 
-static DiagnosticMessage makeMessage(const std::string , int FileOffset,
- const std::string ,
- const StringMap ) {
+static DiagnosticMessage
+makeMessage(const std::string , int FileOffset,
+const std::string , const StringMap ,
+const SmallVector ) {
   DiagnosticMessage DiagMessage;
   DiagMessage.Message = Message;
   DiagMessage.FileOffset = FileOffset;
   DiagMessage.FilePath = FilePath;
   DiagMessage.Fix = Fix;
+  DiagMessage.Ranges = Ranges;
   return DiagMessage;
 }
 
@@ -47,8 +49,8 @@
  const StringMap ,
  const SmallVector ) {
   return Diagnostic(DiagnosticName,
-makeMessage(Message, FileOffset, FilePath, Fix), {},
-Diagnostic::Warning, "path/to/build/directory", Ranges);
+makeMessage(Message, FileOffset, FilePath, Fix, Ranges), {},
+Diagnostic::Warning, "path/to/build/directory");
 }
 
 static const char *YAMLContent =
@@ -77,12 +79,12 @@
 "  Offset:  62\n"
 "  Length:  2\n"
 "  ReplacementText: 'replacement #2'\n"
+"  Ranges:\n"
+"- FilePath:'path/to/source.cpp'\n"
+"  FileOffset:  10\n"
+"  Length:  10\n"
 "Level:   Warning\n"
 "BuildDirectory:  'path/to/build/directory'\n"
-"Ranges:\n"
-"  - FilePath:'path/to/source.cpp'\n"
-"FileOffset:  10\n"
-"Length:  10\n"
 "  - DiagnosticName:  'diagnostic#3'\n"
 "DiagnosticMessage:\n"
 "  Message: 'message #3'\n"
@@ -123,9 +125,9 @@
   TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
"path/to/source2.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note1", 88, "path/to/note1.cpp", {}));
+  makeMessage("Note1", 88, "path/to/note1.cpp", {}, {}));
   TUD.Diagnostics.back().Notes.push_back(
-  makeMessage("Note2", 99, "path/to/note2.cpp", {}));
+  makeMessage("Note2", 99, "path/to/note2.cpp", {}, {}));
 
   std::string YamlContent;
   raw_string_ostream YamlContentStream(YamlContent);
@@ -166,7 +168,7 @@
   EXPECT_EQ(100u, Fixes1[0].getOffset());
   EXPECT_EQ(12u, Fixes1[0].getLength());
   EXPECT_EQ("replacement #1", Fixes1[0].getReplacementText());
-  EXPECT_TRUE(D1.Ranges.empty());
+  EXPECT_TRUE(D1.Message.Ranges.empty());
 
   Diagnostic D2 = TUDActual.Diagnostics[1];
   EXPECT_EQ("diagnostic#2", D2.DiagnosticName);
@@ -179,10 +181,10 @@
   EXPECT_EQ(62u, Fixes2[0].getOffset());
   EXPECT_EQ(2u, Fixes2[0].getLength());
   EXPECT_EQ("replacement #2", Fixes2[0].getReplacementText());
-  EXPECT_EQ(1u, D2.Ranges.size());
-  EXPECT_EQ("path/to/source.cpp", D2.Ranges[0].FilePath);
-  EXPECT_EQ(10u, D2.Ranges[0].FileOffset);
-  EXPECT_EQ(10u, D2.Ranges[0].Length);
+  EXPECT_EQ(1u, D2.Message.Ranges.size());
+  EXPECT_EQ("path/to/source.cpp", D2.Message.Ranges[0].FilePath);
+  EXPECT_EQ(10u, D2.Message.Ranges[0].FileOffset);
+  EXPECT_EQ(10u, D2.Message.Ranges[0].Length);
 
   Diagnostic D3 = TUDActual.Diagnostics[2];
   EXPECT_EQ("diagnostic#3", D3.DiagnosticName);
@@ -198,5 +200,5 @@
   EXPECT_EQ("path/to/note2.cpp", D3.Notes[1].FilePath);
   std::vector Fixes3 = getFixes(D3.Message.Fix);
   EXPECT_TRUE(Fixes3.empty());
-  EXPECT_TRUE(D3.Ranges.empty());
+  EXPECT_TRUE(D3.Message.Ranges.empty());
 }
Index: clang/lib/Tooling/Core/Diagnostic.cpp
===
--- clang/lib/Tooling/Core/Diagnostic.cpp
+++ 

[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D69560#2629555 , @aaron.ballman 
wrote:

> [...] so please hold off on landing it for a bit in case any of the other 
> reviewers want to weigh in.

Due to how the patch itself only being useful in practice if all the pieces 
fall into place, I will definitely keep circling about until the **entire** 
patch tree is ✔. (Including the filtering heuristics, etc.)




Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:56
+
+#ifndef NDEBUG
+

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > Are you planning to remove the debugging code now that the check is 
> > > approaching its final form?
> > Actually, I would prefer not to. I removed every debug thing possible. 
> > However, and this is speaking from experience because I wrote this check 
> > two times already from basically scratch... the rest of the debug code that 
> > is part of the patch has to be there. If anything goes nuts, especially if 
> > there would be false positives later... it would be impossible to figure 
> > out what is going on during the modelling without seeing all the steps 
> > being taken.
> We don't often leave debugging statements in because they tend to cause a 
> maintenance burden that doesn't justify their benefit. However, I agree with 
> your observation that this code is quite difficult to reason through without 
> debugging aids.
> 
> I don't insist on removing the code yet, but would say we should remain open 
> to the idea if it causes a burden in practice. (Either in terms of keeping 
> the debugging code up to date as the check evolves, but also in terms of 
> compile time performance for the check if the debugging code paths turn out 
> to be expensive on build times.)
All debugging code is wrapped into the `LLVM_DEBUG` macro specifically (that's 
why I even put this little "print bits" function behind `NDEBUG`) so they are 
not part of the builds.

I think in general //if// someone puts the effort into reading the code and has 
an interactive debugger they could figure it out (especially if they keep track 
of the recursion constantly), I tried to make everything nicely padded and all 
the variable names and control flow to make sense. (Of course the wealth of 
complexity comes in the follow-up patches.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D97297: [clang-tidy] Suppress reports to patternedly named parameters in 'bugprone-easily-swappable-parameters'

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:384
+  // Pad the two strings to the longer length.
+  std::size_t BiggerLength = std::max(Str1.size(), Str2.size());
+  SmallString<32> S1PadE{Str1}, S2PadE{Str2};

aaron.ballman wrote:
> whisperity wrote:
> > @aaron.ballman I think I'll do something like `if (BiggerLength < 
> > Threshold) return false;`, how does that sound? The comparison is moot in 
> > that case, imagine having strings of 2 and 4, padded to 4, with a threshold 
> > of 6, for example.
> > 
> > That way even if someone accidentally makes `StringRef` overflow the 
> > buffer, we'll be safe on the call paths we have here.
> I think that'd make the behavior much more obvious, but should that be `<=`?
No, because being = to the threshold means that the common prefix/suffix is 
empty string. It'd make variables such as "A" and "X" deemed related. Generally 
not something we want, because that's too broad of an assumption that they are 
"meant to be used together". (Generally you shouldn't name variables like so, 
but still...)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97297/new/

https://reviews.llvm.org/D97297

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69560: [clang-tidy] Add 'bugprone-easily-swappable-parameters' check

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:56
+
+#ifndef NDEBUG
+

aaron.ballman wrote:
> Are you planning to remove the debugging code now that the check is 
> approaching its final form?
Actually, I would prefer not to. I removed every debug thing possible. However, 
and this is speaking from experience because I wrote this check two times 
already from basically scratch... the rest of the debug code that is part of 
the patch has to be there. If anything goes nuts, especially if there would be 
false positives later... it would be impossible to figure out what is going on 
during the modelling without seeing all the steps being taken.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69560/new/

https://reviews.llvm.org/D69560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D96355: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with optionally considering differently qualified types mixable

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:172
+  /// Add the specified qualifiers to the common type in the Mix.
+  MixData operator<<(Qualifiers Quals) const {
+SplitQualType Split = CommonType.split();

aaron.ballman wrote:
> Hmm, use of `<<` is a bit novel but not entirely indefensible. I guess my 
> initial inclination is that you're combing this information into the mix data 
> and so an overload of `|` was what I was sort of expecting to see here 
> (despite it not really being a bitmask operation). These aren't strong 
> opinions, but I'm curious if you have thoughts.
I looked at all the possible operator tokens and this seemed the most 
appropriate. It points to the left, where qualifiers are in LLVM's programming 
style ("west const" and all that). Because sometimes it's variables that get 
passed to these functions, seeing from the get-go that it's not meddling with 
the flags but rather with the types involved seemed appropriate to emphasise.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:327
+
+  if (LType->isPointerType() && RType->isPointerType()) {
+// If both types are pointers, and pointed to the exact same type,

aaron.ballman wrote:
> `isAnyPointerType()` for ObjC pointers? Should we care about rvalue 
> references here similar to pointers?
The reasoning to not be special about && goes back to D95736. If you are given 
any combination of `T`, `T&`, `T&&` and `const T&` parameters and //some// 
values of (essentially) `T`, it's only `T` and `const T&` that **always** mix 
for every potential value of `T`.

`T&&` won't bind variables, and `T&` won't bind temporaries. So their potential 
to mix is an inherent property of the //call site// where the mix might happen. 
If one of them is `T` and the other is `T&` and you happen to pass one variable 
and one literal, and you happen to swap these two, you'll get a compile error.

If both parameters are `T&&`, `LType == RType` for a trivial mix catches it 
early on.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96355/new/

https://reviews.llvm.org/D96355

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D97297: [clang-tidy] Suppress reports to patternedly named parameters in 'bugprone-easily-swappable-parameters'

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity marked an inline comment as not done.
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:364-365
+StringRef S2) {
+  StringRef S1Prefix = S1.take_front(S1.size() - N),
+S2Prefix = S2.take_front(S2.size() - N);
+  return S1Prefix == S2Prefix && !S1Prefix.empty();

aaron.ballman wrote:
> whisperity wrote:
> > aaron.ballman wrote:
> > > Should we be checking that `.size() - N` doesn't cause wraparound?
> > Wraparound as in underflow? Like `2 - 8` becoming multiple millions? The 
> > incoming strings are padded to the common length.
> > 
> > `take_xxx` won't let you go out of bounds, even if the parameter is greater 
> > than the string's length. It will just silently return the entire string.
> > Wraparound as in underflow? Like 2 - 8 becoming multiple millions? The 
> > incoming strings are padded to the common length.
> 
> They are, but I didn't see anything checking that `Threshhold` (which gets 
> passed as `N`) isn't larger than the common string length.
> 
> > take_xxx won't let you go out of bounds, even if the parameter is greater 
> > than the string's length. It will just silently return the entire string.
> 
> Aha, that's the important bit, thanks for verifying that this is safe!
Nevertheless I'll clarify this, specifically because I have to make sure (I was 
thinking for a few minutes then realised the `!S1Prefix.empty()` is actually 
making sure of this...) that if you got parameter names of length 1 (let's say) 
and a threshold of 1, it really shouldn't say that `A` and `B` are "related" 
because the common prefix is `""` and the non-common end differs in one 
character, `A` vs. `B`.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:384
+  // Pad the two strings to the longer length.
+  std::size_t BiggerLength = std::max(Str1.size(), Str2.size());
+  SmallString<32> S1PadE{Str1}, S2PadE{Str2};

@aaron.ballman I think I'll do something like `if (BiggerLength < Threshold) 
return false;`, how does that sound? The comparison is moot in that case, 
imagine having strings of 2 and 4, padded to 4, with a threshold of 6, for 
example.

That way even if someone accidentally makes `StringRef` overflow the buffer, 
we'll be safe on the call paths we have here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97297/new/

https://reviews.llvm.org/D97297

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78652: [clang-tidy] Suppress reports to similarly used parameters in 'bugprone-easily-swappable-parameters'

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:532-536
+  if (find(FD->parameters(), ReturnedParam) == FD->param_end())
+// Returning an Expr to a ParmVarDecl that **isn't** parameter of the
+// function should not be possible. Make sure a mistake of the matcher
+// does **not** interfere with the heuristic's result.
+continue;

aaron.ballman wrote:
> Is this a FIXME because there's a matcher issue this works around or should 
> it be an assertion?
I was unable to create a test for this case. This part of the code, while I was 
twisting my head left and right, is one of the strictest remnant of the old 
version of the check... There definitely was a project in the test set back in 
December 2019 which made the check crash or emit massive false positives, and 
this thing was added to guard against that.

At a hunch, I think //maybe// a lambda returning one of its captures (which 
are, AFAIK, `ParmVarDecl`s of the constructor!) could be what caused the 
crash/false positive. I will check this out in detail soon.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78652/new/

https://reviews.llvm.org/D78652

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D95736: [clang-tidy] Extend 'bugprone-easily-swappable-parameters' with `typedef` and `const &` diagnostics

2021-03-16 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:706
+UniqueBindPower({LType, RType})) {
+  // FIXME: Don't emit multiple combinations here either.
+  StringRef DiagText = "a call site binds an expression to '%0' and "

This is a stale FIXME, the uniqueing of the emission is in the line right 
above...



Comment at: 
clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp:707-708
+  // FIXME: Don't emit multiple combinations here either.
+  StringRef DiagText = "a call site binds an expression to '%0' and "
+   "'%1' with the same force";
+  diag(M.Second->getOuterLocStart(), DiagText, DiagnosticIDs::Note)

aaron.ballman wrote:
> I think "with the same force" is going to be hard for users to make sense of. 
> I'm at a bit of a loss for how to word it though. The issue is that `T` and 
> `const T&` parameters *might* be easily swapped, so maybe it's best to call 
> it out that way?
This is a note tag to explain the reason behind the mix. The warning itself has 
been emitted before. How about

> a `T` and `const T&` parameter accepts all values of `T`

?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95736/new/

https://reviews.llvm.org/D95736

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


<    1   2   3   4   5   6   >