[PATCH] D140307: Match derived types in in modernize-loop-convert

2022-12-19 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: carlosgalvezp.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

This patch allows clang-tidy to replace traditional for-loops where the
container type inherits its `begin`/`end` methods from a base class.

Test plan: Added unit test cases that confirm the tool replaces the new
pattern.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140307

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = VD.size(); E != I; ++I) {
+printf("Fibonacci number is %d\n", VD[I]);
+Sum += VD[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : VD)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -126,6 +126,10 @@
   void constFoo() const;
 };
 
+template
+class dependent_derived : public dependent {
+};
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -251,17 +251,18 @@
   // functions called begin() and end() taking the container as an argument
   // are also allowed.
   TypeMatcher RecordWithBeginEnd = qualType(anyOf(
-  qualType(
-  isConstQualified(),
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
-  hasMethod(cxxMethodDecl(hasName("end"),
-  isConst()   // hasDeclaration
- ))), // qualType
+  qualType(isConstQualified(),
+   hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst())) // 
hasDeclaration
+  ))), // qualType
   qualType(unless(isConstQualified()),
hasUnqualifiedDesugaredType(recordType(hasDeclaration(
-   cxxRecordDecl(hasMethod(hasName("begin")),
- hasMethod(hasName("end"))) // qualType
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(hasName("begin")),
+   hasMethod(hasName("end") // qualType
   ));
 
   StatementMatcher SizeCallMatcher = cxxMemberCallExpr(


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = VD.size(); E != I; ++I) {
+printf("Fibonacci number is %d\n", VD[I]);
+Sum += VD[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : VD)
+  // CHECK-FIXES-NEXT:

[PATCH] D140307: Match derived types in in modernize-loop-convert

2022-12-27 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

@njames93 would you mind taking a look?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

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


[PATCH] D137205: [clang-tidy] Add performance-unnecessary-copy-on-last-use check

2022-12-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

@Febbe - Really glad to see this phab up! Not having realized this phab was in 
progress, I implemented this a few months back (though, originally not as a 
clang-tidy tool and never published) and thought it'd be worth sharing notes. I 
recently turned my non-clang-tidy implementation into a clang-tidy one here 
.
 A couple suggestions based on my experience writing a similar tool,

- Should we detect "escaped" values, i.e., values who have their address taken, 
and not apply a FixIt in these cases? See this test 
.
- I took a slightly more conservative approach in only moving values whose 
`QualType.isTrivialType()` is true, which addresses the 
`shared_ptr` problem. We can then apply FixIts for containers 
(std::vector etc) and algebraic types (tuple/optional) of said types (and 
containers of containers of ...). In general, the approach I was aiming for was 
to define a classification of "safe to move types" (inferred from 
isTrivialType, and/or using a list of safe types of in the tool configuration 
as you have done). Containers/algebraic types of safe to move types, or smart 
pointers of safe to move types (being careful with any custom allocator which 
might lead to a similar problem as the scope guard case) are also safe to move, 
etc. Having the tool be able to distinguish "safe to move" FixIts from 
"potentially unsafe" (as a tool mode, potentially with "safe" as the default) 
would ensure safe refactoring.
- This might be a nitpick, but in the diagnostic message `warning: Parameter 
'...'`, "Parameter" typically means something more specific (the names given to 
function variables, aka, function parameters). How about `warning: Value '...'`

Would you be interested in collaborating on this? I'm not sure the status of 
when this phab would land, but I could contribute my suggestions after, or 
into, this phab depending on feedback. I wrote up a few more notes on 
https://discourse.llvm.org/t/new-clang-tidy-check-finding-move-candidates/67252 
(again, before I realized that you had started this work already).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137205

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


[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
ccotter added a project: clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a subscriber: cfe-commits.

The modernize-loop-convert check will now match iterator based loops
that call the free functions 'begin'/'end', as well as matching the
free function 'size' on containers.

Test plan: Added unit test cases matching free function calls on
containers, and a single negative test case for length() which is not
supported.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,28 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int& I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -21,6 +21,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
+#include 
 #include 
 
 using namespace clang::ast_matchers;
@@ -129,6 +130,8 @@
 ///e = createIterator(); 

[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485634.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,28 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int& I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -204,6 +204,10 @@
   The check now skips concept definitions since redundant expressions still make sense
   inside them.
 
+- Improved :doc:`modernize-loop-convert ` to
+  refactor container based for loops that initialize iterators with free function calls
+  to ``begin``, ``end``, or ``size``.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -21,6 +21,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
+#include 
 #incl

[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485637.
ccotter added a comment.

Add release note


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = VD.size(); E != I; ++I) {
+printf("Fibonacci number is %d\n", VD[I]);
+Sum += VD[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : VD)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -126,6 +126,10 @@
   void constFoo() const;
 };
 
+template
+class dependent_derived : public dependent {
+};
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -204,6 +204,10 @@
   The check now skips concept definitions since redundant expressions still 
make sense
   inside them.
 
+- Improved :doc:`misc-redundant-expression 
`
+  to check for container functions ``begin``/``end`` etc on base classes of 
the container
+  type, instead of only as direct members of the container type itself.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -251,17 +251,18 @@
   // functions called begin() and end() taking the container as an argument
   // are also allowed.
   TypeMatcher RecordWithBeginEnd = qualType(anyOf(
-  qualType(
-  isConstQualified(),
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
-  hasMethod(cxxMethodDecl(hasName("end"),
-  isConst()   // hasDeclaration
- ))), // qualType
+  qualType(isConstQualified(),
+   hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst())) // 
hasDeclaration
+  ))), // qualType
   qualType(unless(isConstQualified()),
hasUnqualifiedDesugaredType(recordType(hasDeclaration(
-   cxxRecordDecl(hasMethod(hasName("begin")),
- hasMethod(hasName("end"))) // qualType
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(hasName("begin")),
+   hasMethod(hasName("end") // qualType
   ));
 
   StatementMatcher SizeCallMatcher = cxxMemberCallExpr(


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FI

[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

In D140760#4019680 , @Eugene.Zelenko 
wrote:

> I just look into check documentation, new feature should be described with 
> example there too.

Would you mind clarifying where I should add documentation to? In the release 
notes, or within LoopConvertCheck.cpp itself?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

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


[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485643.
ccotter added a comment.

Update docs


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,28 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int& I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
+++ clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
@@ -91,10 +91,18 @@
   for (vector::iterator it = v.begin(); it != v.end(); ++it)
 cout << *it;
 
+  // reasonable conversion
+  for (vector::iterator it = begin(v); it != end(v); ++it)
+cout << *it;
+
   // reasonable conversion
   for (int i = 0; i < v.size(); ++i)
 cout << v[i];
 
+  // reasonable conversion
+  for (int i = 0; i < size(v); ++i)
+cout << v[i];
+
 After applying the check with minimum confidence level set to `reasonable` (default):
 
 .. code-block:: c++
Index: cla

[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485655.
ccotter added a comment.

Update tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -687,7 +687,7 @@
 Sum += V[I] + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
 
@@ -695,7 +695,7 @@
 V[I] = 0;
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int& I : V)
+  // CHECK-FIXES: for (int & I : V)
   // CHECK-FIXES-NEXT: I = 0;
 
   // Although 'length' might be a valid free function, only std::size() is 
standardized
@@ -703,6 +703,14 @@
 printf("Fibonacci number is %d\n", V[I]);
 Sum += V[I] + 2;
   }
+
+  dependent Vals;
+  for (int I = 0, E = size(Vals); E != I; ++I) {
+Sum += Vals[I].X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Val : Vals)
+  // CHECK-FIXES-NEXT: Sum += Val.X;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -687,7 +687,7 @@
 Sum += V[I] + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
 
@@ -695,7 +695,7 @@
 V[I] = 0;
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int& I : V)
+  // CHECK-FIXES: for (int & I : V)
   // CHECK-FIXES-NEXT: I = 0;
 
   // Although 'length' might be a valid free function, only std::size() is standardized
@@ -703,6 +703,14 @@
 printf("Fibonacci number is %d\n", V[I]);
 Sum += V[I] + 2;
   }
+
+  dependent Vals;
+  for (int I = 0, E = size(Vals); E != I; ++I) {
+Sum += Vals[I].X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Val : Vals)
+  // CHECK-FIXES-NEXT: Sum += Val.X;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485656.
ccotter added a comment.

oops, redo diff with correct arc diff command


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,36 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+
+  dependent Vals;
+  for (int I = 0, E = size(Vals); E != I; ++I) {
+Sum += Vals[I].X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Val : Vals)
+  // CHECK-FIXES-NEXT: Sum += Val.X;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
+++ clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
@@ -91,10 +91,18 @@
   for (vector::iterator it = v.begin(); it != v.end(); ++it)
 cout << *it;
 
+  // reasonable conversion
+  for (vector::iterator it = begin(v); it != end(v); ++it)
+cout << *it;
+

[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485665.
ccotter added a comment.

- Remove unused variable


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,36 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+
+  dependent Vals;
+  for (int I = 0, E = size(Vals); E != I; ++I) {
+Sum += Vals[I].X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Val : Vals)
+  // CHECK-FIXES-NEXT: Sum += Val.X;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
+++ clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
@@ -91,10 +91,18 @@
   for (vector::iterator it = v.begin(); it != v.end(); ++it)
 cout << *it;
 
+  // reasonable conversion
+  for (vector::iterator it = begin(v); it != end(v); ++it)
+cout << *it;
+
   // reasonable conv

[PATCH] D140772: Fix minor bug in add_new_check.py

2022-12-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: carlosgalvezp.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

While rebuilding the list of checks in add_new_check.py,
check is a file is a subdirectory before traversing it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140772

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/docs/ReleaseNotes.rst


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,9 @@
 - Change to Python 3 in the shebang of `add_new_check.py` and 
`rename_check.py`,
   as the existing code is not compatible with Python 2.
 
+- Fix a minor bug in `add_new_check.py` to only traverse subdirectories
+  when updating the list of checks in the documentation.
+
 New checks
 ^^
 
Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -322,8 +322,7 @@
 lines = f.readlines()
   # Get all existing docs
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,9 @@
 - Change to Python 3 in the shebang of `add_new_check.py` and `rename_check.py`,
   as the existing code is not compatible with Python 2.
 
+- Fix a minor bug in `add_new_check.py` to only traverse subdirectories
+  when updating the list of checks in the documentation.
+
 New checks
 ^^
 
Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -322,8 +322,7 @@
 lines = f.readlines()
   # Get all existing docs
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485710.
ccotter added a comment.

Fix isdir check


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/docs/ReleaseNotes.rst


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,9 @@
 - Change to Python 3 in the shebang of `add_new_check.py` and 
`rename_check.py`,
   as the existing code is not compatible with Python 2.
 
+- Fix a minor bug in `add_new_check.py` to only traverse subdirectories
+  when updating the list of checks in the documentation.
+
 New checks
 ^^
 
Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -322,8 +322,7 @@
 lines = f.readlines()
   # Get all existing docs
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in filter(lambda s: os.path.isdir(os.path.join(docs_dir, s)), 
os.listdir(docs_dir)):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,9 @@
 - Change to Python 3 in the shebang of `add_new_check.py` and `rename_check.py`,
   as the existing code is not compatible with Python 2.
 
+- Fix a minor bug in `add_new_check.py` to only traverse subdirectories
+  when updating the list of checks in the documentation.
+
 New checks
 ^^
 
Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -322,8 +322,7 @@
 lines = f.readlines()
   # Get all existing docs
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in filter(lambda s: os.path.isdir(os.path.join(docs_dir, s)), os.listdir(docs_dir)):
 for file in filter(lambda s: s.endswith('.rst'), os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/add_new_check.py:324-328
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()

carlosgalvezp wrote:
> It feels this whole code could be made much simpler, readable and safer by 
> just doing:
> 
>   doc_files = glob.glob(os.path.join(docs_dir, "**", "*.rst"), recursive=True)
I gave this a shot, but realized the the glob returned the relative path 
`../docs/clang-tidy/checks//.rst`, and the existing logic only 
adds `[, .rst]` to the list. Python3.10's `glob.glob` has 
root_dir which would do the trick for us, but I don't think we can rely on 
Python3 yet? I think using glob might not improve the readability all that much 
since I'd have to strip out the `docs_dir` subpath, but happy to give that a go 
based on your feedback.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added subscribers: carlosgalvezp, shchenz, kbarton, xazax.hun, nemanjai.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Implement CppCoreGuideline CP.53 to warn when a coroutine accepts
references parameters. Although the guideline mentions that it is safe
to access a reference parameter before suspension points, the guideline
recommends flagging all coroutine parameter references.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rs

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

Passing and accessing a reference is safe if the access is done before any 
suspend point (taking into account whether the initial coroutine suspend 
actually suspends or not). Although CP.53 recommends warning on any reference 
parameter regardless of whether the code only accesses the reference before any 
suspend points, I did implement (not in this changeset - in a separate branch) 
a version of this check that uses the CFG to determine whether reference 
parameters are never accessed after a suspend point. If there's interest, I 
could reimplement this check with this (perhaps as a tool option). That said, I 
do agree with CP.53 that relying on such access being safe is brittle e.g. if 
the code is refactored in the future to rearrange suspend points, so I went 
with this approach for the review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

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


[PATCH] D140794: Add coroutineBodyStmt matcher

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The coroutineBodyStmt matcher matches CoroutineBodyStmt AST nodes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140794

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp


Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,26 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoYieldCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+
+  EXPECT_FALSE(matchesConditionally(NonCoroCode,
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
 }
 
 TEST(Matcher, isClassMessage) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -168,6 +168,7 @@
   REGISTER_MATCHER(complexType);
   REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
+  REGISTER_MATCHER(coroutineBodyStmt);
   REGISTER_MATCHER(coawaitExpr);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constantArrayType);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -909,6 +909,7 @@
 const internal::VariadicDynCastAllOfMatcher caseStmt;
 const internal::VariadicDynCastAllOfMatcher defaultStmt;
 const internal::VariadicDynCastAllOfMatcher compoundStmt;
+const internal::VariadicDynCastAllOfMatcher 
coroutineBodyStmt;
 const internal::VariadicDynCastAllOfMatcher cxxCatchStmt;
 const internal::VariadicDynCastAllOfMatcher cxxTryStmt;
 const internal::VariadicDynCastAllOfMatcher cxxThrowExpr;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2449,6 +2449,17 @@
 extern const internal::VariadicDynCastAllOfMatcher
 coyieldExpr;
 
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+///   generator gen() {
+/// co_return;
+///   }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
+
 /// Matches nullptr literal.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxNullPtrLiteralExpr;
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -855,6 +855,8 @@
 AST Matchers
 
 
+- Add ``coroutineBodyStmt`` matcher.
+
 clang-format
 
 - Add ``RemoveSemicolon`` option for removing ``;`` after a non-empty function 
definition.


Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,26 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, 
+   coroutineBodyStmt(),
+   true, 

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485745.
ccotter added a comment.

move reference link


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==
+
+Warns 

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485746.
ccotter added a comment.

spelling


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==
+
+Warns when a coro

[PATCH] D140794: [ASTMatcher] Add coroutineBodyStmt matcher

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485748.
ccotter added a comment.

- Add hasBody matcher support for coroutineBodyStmt


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140794

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,52 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoYieldCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+
+  EXPECT_FALSE(matchesConditionally(NonCoroCode,
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithDeclCode = R"cpp(
+#include 
+void coro() {
+  int thevar;
+  co_return 1;
+}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithDeclCode,
+  coroutineBodyStmt(hasBody(compoundStmt(
+  has(declStmt(containsDeclaration(0, varDecl(hasName("thevar",
+  true, {"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithTryCatchDeclCode = R"cpp(
+#include 
+void coro() try {
+  int thevar;
+  co_return 1;
+} catch (...) {}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithTryCatchDeclCode,
+  coroutineBodyStmt(hasBody(cxxTryStmt(has(compoundStmt(
+  has(declStmt(containsDeclaration(0, varDecl(hasName("thevar")),
+  true, {"-std=c++20", "-I/"}, M));
 }
 
 TEST(Matcher, isClassMessage) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -168,6 +168,7 @@
   REGISTER_MATCHER(complexType);
   REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
+  REGISTER_MATCHER(coroutineBodyStmt);
   REGISTER_MATCHER(coawaitExpr);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constantArrayType);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -909,6 +909,7 @@
 const internal::VariadicDynCastAllOfMatcher caseStmt;
 const internal::VariadicDynCastAllOfMatcher defaultStmt;
 const internal::VariadicDynCastAllOfMatcher compoundStmt;
+const internal::VariadicDynCastAllOfMatcher coroutineBodyStmt;
 const internal::VariadicDynCastAllOfMatcher cxxCatchStmt;
 const internal::VariadicDynCastAllOfMatcher cxxTryStmt;
 const internal::VariadicDynCastAllOfMatcher cxxThrowExpr;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2449,6 +2449,17 @@
 extern const internal::VariadicDynCastAllOfMatcher
 coyieldExpr;
 
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+///   generator gen() {
+/// co_return;
+///   }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
+
 /// Matches nullptr literal.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxNullPtrLiteralExpr;
@@ -5488,7 +5499,8 @@
   AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
   WhileStmt,
   CXXForRangeStmt,
-  FunctionDecl),
+  FunctionDecl,
+  CoroutineBodyStmt),
   internal::Matcher, InnerMatcher) {
   if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node))
 return f

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-31 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485782.
ccotter added a comment.

- run clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==
+
+Warns w

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-31 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485783.
ccotter added a comment.

- Does not offer fixes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_,
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==
+
+Warns whe

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2023-01-01 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485824.
ccotter added a comment.

- Cleanups


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst


Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,7 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables 
`_,
-   `cppcoreguidelines-avoid-reference-coroutine-parameters 
`_, "Yes"
+   `cppcoreguidelines-avoid-reference-coroutine-parameters 
`_,
`cppcoreguidelines-init-variables 
`_, "Yes"
`cppcoreguidelines-interfaces-global-init 
`_,
`cppcoreguidelines-macro-usage `_,
Index: 
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- 
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
+++ 
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -17,4 +17,4 @@
   }
 
 This check implements
-`CppCoreGuideline CP.53 
`_.
+`CppCoreGuideline CP.53 
`_.
Index: 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
===
--- 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
+++ 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
@@ -23,11 +23,12 @@
 /// 
http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.html
 class AvoidReferenceCoroutineParametersCheck : public ClangTidyCheck {
 public:
-  AvoidReferenceCoroutineParametersCheck(StringRef Name, ClangTidyContext 
*Context)
+  AvoidReferenceCoroutineParametersCheck(StringRef Name,
+ ClangTidyContext *Context)
   : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  bool isLanguageVersionSupported(const LangOptions &LO) const override {
+  bool isLanguageVersionSupported(const LangOpts &LO) const override {
 return LO.CPlusPlus20;
   }
 };
Index: 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
===
--- 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
+++ 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
@@ -28,9 +28,9 @@
 
 void AvoidReferenceCoroutineParametersCheck::check(
 const MatchFinder::MatchResult &Result) {
-  const auto *Param = Result.Nodes.getNodeAs("param");
-
-  diag(Param->getBeginLoc(), "coroutine parameters should not be references");
+  if (const auto *Param = Result.Nodes.getNodeAs("param")) {
+diag(Param->getBeginLoc(), "coroutine parameters should not be 
references");
+  }
 }
 
 } // namespace cppcoreguidelines


Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,7 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
-   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_,
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -17,4 +17,4 @@
   }
 
 This check implements
-`CppCoreGuideline CP.53 

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2023-01-01 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485827.
ccotter added a comment.

- oops - bad arc diff / bad change


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_,
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2023-01-02 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked 4 inline comments as done.
ccotter added a comment.

In D140793#4021694 , @carlosgalvezp 
wrote:

> LGTM, thanks for the patch! Maybe wait a couple days before landing to give 
> some extra time for other reviewers. You might also want to mark the comments 
> as "Done", so reviewers can get a quick overview of unresolved issues (if 
> any).

Done, and thanks! I don't have permissions to land, so could you help land this 
for me after a few days have passed (assuming now further feedback)? You can 
use `Chris Cotter `


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

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


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2023-01-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

@carlosgalvezp - could you also help commit this if it looks good?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2023-01-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 486716.
ccotter added a comment.

- Match derived types in in modernize-loop-convert
- fix typo


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = VD.size(); E != I; ++I) {
+printf("Fibonacci number is %d\n", VD[I]);
+Sum += VD[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : VD)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -126,6 +126,10 @@
   void constFoo() const;
 };
 
+template
+class dependent_derived : public dependent {
+};
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -204,6 +204,10 @@
   The check now skips concept definitions since redundant expressions still 
make sense
   inside them.
 
+- Improved :doc:`modernize-loop-convert 
`
+  to check for container functions ``begin``/``end`` etc on base classes of 
the container
+  type, instead of only as direct members of the container type itself.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -251,17 +251,18 @@
   // functions called begin() and end() taking the container as an argument
   // are also allowed.
   TypeMatcher RecordWithBeginEnd = qualType(anyOf(
-  qualType(
-  isConstQualified(),
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
-  hasMethod(cxxMethodDecl(hasName("end"),
-  isConst()   // hasDeclaration
- ))), // qualType
+  qualType(isConstQualified(),
+   hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst())) // 
hasDeclaration
+  ))), // qualType
   qualType(unless(isConstQualified()),
hasUnqualifiedDesugaredType(recordType(hasDeclaration(
-   cxxRecordDecl(hasMethod(hasName("begin")),
- hasMethod(hasName("end"))) // qualType
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(hasName("begin")),
+   hasMethod(hasName("end") // qualType
   ));
 
   StatementMatcher SizeCallMatcher = cxxMemberCallExpr(


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fib

[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2023-01-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked 2 inline comments as done.
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:258
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst())) // 
hasDeclaration

carlosgalvezp wrote:
> Replace tabs with spaces
Ah, I think this was before I figured out `arc diff` and was copy/pasting diff 
files around :/

Thanks for catching this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

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


[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2023-01-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:258
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst())) // 
hasDeclaration

ccotter wrote:
> carlosgalvezp wrote:
> > Replace tabs with spaces
> Ah, I think this was before I figured out `arc diff` and was copy/pasting 
> diff files around :/
> 
> Thanks for catching this.
just to confirm, how did you notice the tabs? I couldnt find them when I 
downloaded the phab raw diff for any of the versions in the history. I still 
see a double right arrow `»` in the phab diff - is that indicating a tab or 
something else?

As a sanity check, I ran `./clang/tools/clang-format/git-clang-format --binary 
build/bin/clang-format` from the root of my project and the tool did not 
produce any changes with the latest version of the changes I submitted.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added subscribers: carlosgalvezp, shchenz, kbarton, xazax.hun, nemanjai.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Warn when a lambda specifies a default capture and captures
``this``. Offer FixIts to correct the code.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-this-with-capture-default %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { return x > 10; 

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 486873.
ccotter marked an inline comment as done.
ccotter added a comment.

- docs feedback


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-this-with-capture-default %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture this should not specify a capture default [cppcoreguideline

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487081.
ccotter added a comment.

- Use "capture default" consistently and update diagnostic message


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -6,47 +6,47 @@
 int local2{};
 
 auto explicit_this_capture = [=, this]() { };
-// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [this]() { };
 
 auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [local, this]() { return (local+x) > 10; };
 
 auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
 
 auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
 
 auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
 
 auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
 
 auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
 // CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
 
 auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
-// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture this should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-MESSA

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487082.
ccotter added a comment.

oops, bad 'arc diff' again


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-this-with-capture-default %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-c

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487084.
ccotter added a comment.

- typo


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-this-with-capture-default %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-cap

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp:9
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this 
should not specify a capture default 
[cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };

carlosgalvezp wrote:
> carlosgalvezp wrote:
> > carlosgalvezp wrote:
> > > "default capture"?
> > I find the check name a bit unintuitive. If you are up for a rename (you 
> > can use `rename_check.py`), I would consider renaming to something like 
> > `cppcoreguidelines-avoid-default-capture-when-capturing-this`
> > 
> > Like, what should be avoided is not "capturing this", it's using a default 
> > capture.
> > 
> > Would be good to get other reviewers opinion before spending time on 
> > renaming.
> Maybe put it within quotes so clarify it's a C++ keyword? Either backticks 
> `this` or single quotes 'this' would work I think, unless we have some other 
> convention.
I updated all references to capture default to say "capture default" as this is 
how it is spelled in the standard. The CppCoreGuideline for F.54 does use 
"default capture" though, so I'll open an issue seeing if that wording should 
instead say "capture default." Also for reference, `git grep` within the 
llvm-project repo shows

```
$ git grep -i 'capture default' | wc -l
  43
$ git grep -i 'default capture' | wc -l
  54
$ git grep -i 'capture.default' | wc -l # E.g., 'capture-default' or 'capture 
default'
 105
```



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp:9
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this 
should not specify a capture default 
[cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };

ccotter wrote:
> carlosgalvezp wrote:
> > carlosgalvezp wrote:
> > > carlosgalvezp wrote:
> > > > "default capture"?
> > > I find the check name a bit unintuitive. If you are up for a rename (you 
> > > can use `rename_check.py`), I would consider renaming to something like 
> > > `cppcoreguidelines-avoid-default-capture-when-capturing-this`
> > > 
> > > Like, what should be avoided is not "capturing this", it's using a 
> > > default capture.
> > > 
> > > Would be good to get other reviewers opinion before spending time on 
> > > renaming.
> > Maybe put it within quotes so clarify it's a C++ keyword? Either backticks 
> > `this` or single quotes 'this' would work I think, unless we have some 
> > other convention.
> I updated all references to capture default to say "capture default" as this 
> is how it is spelled in the standard. The CppCoreGuideline for F.54 does use 
> "default capture" though, so I'll open an issue seeing if that wording should 
> instead say "capture default." Also for reference, `git grep` within the 
> llvm-project repo shows
> 
> ```
> $ git grep -i 'capture default' | wc -l
>   43
> $ git grep -i 'default capture' | wc -l
>   54
> $ git grep -i 'capture.default' | wc -l # E.g., 'capture-default' or 'capture 
> default'
>  105
> ```
Updated with a single quote. I didn't find any clang-tidy diagnostics emitting 
backticks, but saw usage of single quotes when referring to identifiers like 
variable or class names.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp:9
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this 
should not specify a capture default 
[cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };

ccotter wrote:
> ccotter wrote:
> > carlosgalvezp wrote:
> > > carlosgalvezp wrote:
> > > > carlosgalvezp wrote:
> > > > > "default capture"?
> > > > I find the check name a bit unintuitive. If you are up for a rename 
> > > > (you can use `rename_check.py`), I would consider renaming to something 
> > > > like `cppcoreguidelines-avoid-default-capture-when-capturing-this`
> > > > 
> > > > Like, what should be avoided is not "capturing this", it's using a 
> > > > default capture.
> > > > 
> > > > Would be good to get other reviewers opinion before spending time on 
> > > > renaming.
> > > Maybe put it within quotes so clarify it's a C++ keyword? Either 
> > > backticks `this` or single quotes 'this' would work I think, unless we 
> > > have some other convention.
> > I updated all references to capture default to say "capture default" as 
> > this is how it is spelled in the standard. The CppCoreGuideline for F.54 
> > does use "default capture" though, so I'll open an i

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done and an inline comment as not done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp:9
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this 
should not specify a capture default 
[cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };

ccotter wrote:
> ccotter wrote:
> > ccotter wrote:
> > > carlosgalvezp wrote:
> > > > carlosgalvezp wrote:
> > > > > carlosgalvezp wrote:
> > > > > > "default capture"?
> > > > > I find the check name a bit unintuitive. If you are up for a rename 
> > > > > (you can use `rename_check.py`), I would consider renaming to 
> > > > > something like 
> > > > > `cppcoreguidelines-avoid-default-capture-when-capturing-this`
> > > > > 
> > > > > Like, what should be avoided is not "capturing this", it's using a 
> > > > > default capture.
> > > > > 
> > > > > Would be good to get other reviewers opinion before spending time on 
> > > > > renaming.
> > > > Maybe put it within quotes so clarify it's a C++ keyword? Either 
> > > > backticks `this` or single quotes 'this' would work I think, unless we 
> > > > have some other convention.
> > > I updated all references to capture default to say "capture default" as 
> > > this is how it is spelled in the standard. The CppCoreGuideline for F.54 
> > > does use "default capture" though, so I'll open an issue seeing if that 
> > > wording should instead say "capture default." Also for reference, `git 
> > > grep` within the llvm-project repo shows
> > > 
> > > ```
> > > $ git grep -i 'capture default' | wc -l
> > >   43
> > > $ git grep -i 'default capture' | wc -l
> > >   54
> > > $ git grep -i 'capture.default' | wc -l # E.g., 'capture-default' or 
> > > 'capture default'
> > >  105
> > > ```
> > Updated with a single quote. I didn't find any clang-tidy diagnostics 
> > emitting backticks, but saw usage of single quotes when referring to 
> > identifiers like variable or class names.
> +1 - I admit, I struggled naming this check. More feedback welcome on the name
https://github.com/isocpp/CppCoreGuidelines/pull/2016 for "capture default" vs 
"default capture"


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp:9
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture this 
should not specify a capture default 
[cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };

carlosgalvezp wrote:
> ccotter wrote:
> > ccotter wrote:
> > > ccotter wrote:
> > > > ccotter wrote:
> > > > > carlosgalvezp wrote:
> > > > > > carlosgalvezp wrote:
> > > > > > > carlosgalvezp wrote:
> > > > > > > > "default capture"?
> > > > > > > I find the check name a bit unintuitive. If you are up for a 
> > > > > > > rename (you can use `rename_check.py`), I would consider renaming 
> > > > > > > to something like 
> > > > > > > `cppcoreguidelines-avoid-default-capture-when-capturing-this`
> > > > > > > 
> > > > > > > Like, what should be avoided is not "capturing this", it's using 
> > > > > > > a default capture.
> > > > > > > 
> > > > > > > Would be good to get other reviewers opinion before spending time 
> > > > > > > on renaming.
> > > > > > Maybe put it within quotes so clarify it's a C++ keyword? Either 
> > > > > > backticks `this` or single quotes 'this' would work I think, unless 
> > > > > > we have some other convention.
> > > > > I updated all references to capture default to say "capture default" 
> > > > > as this is how it is spelled in the standard. The CppCoreGuideline 
> > > > > for F.54 does use "default capture" though, so I'll open an issue 
> > > > > seeing if that wording should instead say "capture default." Also for 
> > > > > reference, `git grep` within the llvm-project repo shows
> > > > > 
> > > > > ```
> > > > > $ git grep -i 'capture default' | wc -l
> > > > >   43
> > > > > $ git grep -i 'default capture' | wc -l
> > > > >   54
> > > > > $ git grep -i 'capture.default' | wc -l # E.g., 'capture-default' or 
> > > > > 'capture default'
> > > > >  105
> > > > > ```
> > > > Updated with a single quote. I didn't find any clang-tidy diagnostics 
> > > > emitting backticks, but saw usage of single quotes when referring to 
> > > > identifiers like variable or class names.
> > > +1 - I admit, I struggled naming this check. More feedback welcome on the 
> > > name
> > https://github.com/isocpp/CppCoreGuidelines/pull/2016 for "capture default" 
> > vs "default capture"
> Interesting, thanks for investigating this! cppreference also uses that 
> terminology. 
> It sounds quite strange to me since that's not how humans read english text 
> (which is what the diagnostic is meant for). We use "default constructor", 
> "default arguments", etc. 
> 
> Anyhow this is a minor detail that shouldn't block the patch. Thanks for 
> opening the pull requet towards CppCoreGuidelines!
Since this is a more minor detail, we could probably follow up on the "capture 
default" wording on the CppCoreGuidelines issue I opened. I'll add that I 
*just* changed the lone occurrence of "default capture" in 
https://en.cppreference.com/mwiki/index.php?title=cpp%2Flanguage%2Flambda&diff=146169&oldid=145543,
 since the other 15 references were phrased "capture default" or 
"capture-default."


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487130.
ccotter added a comment.

- rm trace; tidy docs


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-this-with-capture-default %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-captur

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-07 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked 2 inline comments as done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp:35
+Capture.getLocation(), SourceMgr, Context.getLangOpts(), tok::amp);
+llvm::errs() << "FOR REF capture loc= "
+ << Capture.getLocation().printToString(SourceMgr)

carlosgalvezp wrote:
> Not having being involved in the development of this check I don't quite 
> understand what this error message means, could you provide a more 
> descriptive message?
> 
> It's also unclear if the program is supposed to abort when entering this 
> branch, or if it's expected that it returns just fine? If it's supposed to 
> return just fine, I think the check should not print anything, to keep the 
> users' logs clean.
My bad - I forgot to remove this trace. Both branches are valid branches for 
normal program execution.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-08 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487189.
ccotter added a comment.

- Use const&


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureThisWithCaptureDefaultCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-this-with-capture-default.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-this-with-capture-default %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-with-capture-default]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-this-wi

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-08 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487193.
ccotter added a comment.

- rename to avoid-capture-deafult-when-capturing-this


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture 'this' should n

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-08 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added a comment.

Thanks!

I opted for 'avoid-capture-default-when-capturing-this' and updated the name 
and docs etc in the most recent diff.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-08 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487195.
ccotter added a comment.

- tidy up docs


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [&  local, &local2, this]() { return (local+x) > 10; }
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [& /* byref */ local, &local2, this]() { return (local+x) > 10; }
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this]() { return x > 10; };
+
+auto implicit_this_capture_local = [=]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that capture 'this' should not specify a capture default [cppcoregu

[PATCH] D140794: [ASTMatcher] Add coroutineBodyStmt matcher

2023-01-09 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:5503
+  FunctionDecl,
+  CoroutineBodyStmt),
   internal::Matcher, InnerMatcher) {

aaron.ballman wrote:
> I'm not certain it makes sense to me to add `CoroutineBodyStmt` to `hasBody` 
> -- in this case, it doesn't *have* a body, it *is* the body.
With respect to `hasBody()`, my intent was to treat the CoroutineBodyStmt node 
as analogous to a FunctionDecl or WhileStmt. WhileStmts have information like 
the loop condition expression, as CoroutineBodyStmts contain the synthesized 
expressions such as the initial suspend Stmt. Both WhileStmts and 
CoroutineBodyStmts then have the `getBody()` methods, usually a CompoundStmt 
for WhileStmts and either a CompoundStmt or TryStmt for CoroutineBodyStmts.

Ultimately, I wanted to be able to match the CoroutineBodyStmt's 
`function-body` (using the grammar) from the standard, e.g., 
`coroutineBodyStmt(hasBody(compoundStmt().bind(...)))`. If there is a different 
approach you'd recommend that's in line with the AST matcher design strategy, I 
can use that instead.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140794

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


[PATCH] D140794: [ASTMatcher] Add coroutineBodyStmt matcher

2023-01-09 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487661.
ccotter marked an inline comment as not done.
ccotter added a comment.

- Add hasBody matcher support for coroutineBodyStmt
- update doc
- Sort list
- clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140794

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,48 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, coroutineBodyStmt(), true,
+   {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, coroutineBodyStmt(), true,
+   {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoYieldCode, coroutineBodyStmt(), true,
+   {"-std=c++20", "-I/"}, M));
+
+  EXPECT_FALSE(matchesConditionally(NonCoroCode, coroutineBodyStmt(), true,
+{"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithDeclCode = R"cpp(
+#include 
+void coro() {
+  int thevar;
+  co_return 1;
+}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithDeclCode,
+  coroutineBodyStmt(hasBody(compoundStmt(
+  has(declStmt(containsDeclaration(0, varDecl(hasName("thevar",
+  true, {"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithTryCatchDeclCode = R"cpp(
+#include 
+void coro() try {
+  int thevar;
+  co_return 1;
+} catch (...) {}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithTryCatchDeclCode,
+  coroutineBodyStmt(hasBody(cxxTryStmt(has(compoundStmt(has(
+  declStmt(containsDeclaration(0, varDecl(hasName("thevar")),
+  true, {"-std=c++20", "-I/"}, M));
 }
 
 TEST(Matcher, isClassMessage) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -175,6 +175,7 @@
   REGISTER_MATCHER(containsDeclaration);
   REGISTER_MATCHER(continueStmt);
   REGISTER_MATCHER(coreturnStmt);
+  REGISTER_MATCHER(coroutineBodyStmt);
   REGISTER_MATCHER(coyieldExpr);
   REGISTER_MATCHER(cudaKernelCallExpr);
   REGISTER_MATCHER(cxxBaseSpecifier);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -909,6 +909,8 @@
 const internal::VariadicDynCastAllOfMatcher caseStmt;
 const internal::VariadicDynCastAllOfMatcher defaultStmt;
 const internal::VariadicDynCastAllOfMatcher compoundStmt;
+const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
 const internal::VariadicDynCastAllOfMatcher cxxCatchStmt;
 const internal::VariadicDynCastAllOfMatcher cxxTryStmt;
 const internal::VariadicDynCastAllOfMatcher cxxThrowExpr;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2449,6 +2449,17 @@
 extern const internal::VariadicDynCastAllOfMatcher
 coyieldExpr;
 
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+///   generator gen() {
+/// co_return;
+///   }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
+
 /// Matches nullptr literal.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxNullPtrLiteralExpr;
@@ -5460,9 +5471,9 @@
 }
 
 /// Matches a 'for', 'while', 'do while' statement or a function
-/// definition that has a given body. Note that in case of functions
-/// this matcher only matches the definition itself and not the other
-/// declarations of the same function.
+/// or coroutine definition that has a given body. Note that in case of
+/// functions this matcher only matches the definition itself and not
+/// the other declarations of the same function.
 ///
 /// Given
 /// \code
@@ -5484,12 +5495,11 @@
 ///   matching '{}'
 ///   but does not match 'void f();'
 
-AST_POLYMORPHIC_MATCHER_P(hasBody,
-  AST_POLYMORPHIC_SUPPORTED_TYPES(DoStm

[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487778.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

Files:
  clang-tools-extra/docs/ReleaseNotes.rst


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -216,7 +216,7 @@
   :doc: `readability-redundant-string-cstr 
`
   check.
 
-- Improved :doc:`misc-redundant-expression 
`
+- Improved :doc:`modernize-loop-convert 
`
   to check for container functions ``begin``/``end`` etc on base classes of 
the container
   type, instead of only as direct members of the container type itself.
 


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -216,7 +216,7 @@
   :doc: `readability-redundant-string-cstr `
   check.
 
-- Improved :doc:`misc-redundant-expression `
+- Improved :doc:`modernize-loop-convert `
   to check for container functions ``begin``/``end`` etc on base classes of the container
   type, instead of only as direct members of the container type itself.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487781.
ccotter added a comment.

rebase?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = VD.size(); E != I; ++I) {
+printf("Fibonacci number is %d\n", VD[I]);
+Sum += VD[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : VD)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -126,6 +126,10 @@
   void constFoo() const;
 };
 
+template
+class dependent_derived : public dependent {
+};
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -216,6 +216,10 @@
   :doc: `readability-redundant-string-cstr 
`
   check.
 
+- Improved :doc:`modernize-loop-convert 
`
+  to check for container functions ``begin``/``end`` etc on base classes of 
the container
+  type, instead of only as direct members of the container type itself.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -252,17 +252,18 @@
   // functions called begin() and end() taking the container as an argument
   // are also allowed.
   TypeMatcher RecordWithBeginEnd = qualType(anyOf(
-  qualType(
-  isConstQualified(),
-  hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(
-  hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
-  hasMethod(cxxMethodDecl(hasName("end"),
-  isConst()   // hasDeclaration
- ))), // qualType
+  qualType(isConstQualified(),
+   hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst())) // 
hasDeclaration
+  ))), // qualType
   qualType(unless(isConstQualified()),
hasUnqualifiedDesugaredType(recordType(hasDeclaration(
-   cxxRecordDecl(hasMethod(hasName("begin")),
- hasMethod(hasName("end"))) // qualType
+   cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
+   hasMethod(hasName("begin")),
+   hasMethod(hasName("end") // qualType
   ));
 
   StatementMatcher SizeCallMatcher = cxxMemberCallExpr(


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -575,6 +575,7 @@
 const dependent *Pconstv;
 
 transparent> Cv;
+dependent_derived VD;
 
 void f() {
   int Sum = 0;
@@ -653,6 +654,15 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = VD.size(); 

[PATCH] D140307: [clang-tidy] Match derived types in in modernize-loop-convert

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

Rebased! Sorry for the multiple diffs on this phab - I'm still getting the hang 
of `arc diff`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140307

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


[PATCH] D140794: [ASTMatcher] Add coroutineBodyStmt matcher

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487789.
ccotter added a comment.

- Fix ParserTest.Errors


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140794

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
  clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp

Index: clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
===
--- clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -366,7 +366,8 @@
 "to build matcher: mapAnyOf.",
 ParseWithError("mapAnyOf(\"foo\")"));
   EXPECT_EQ("Input value has unresolved overloaded type: "
-"Matcher",
+"Matcher",
 ParseMatcherWithError("hasBody(stmt())"));
   EXPECT_EQ(
   "1:1: Error parsing argument 1 for matcher decl.\n"
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,48 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, coroutineBodyStmt(), true,
+   {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, coroutineBodyStmt(), true,
+   {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoYieldCode, coroutineBodyStmt(), true,
+   {"-std=c++20", "-I/"}, M));
+
+  EXPECT_FALSE(matchesConditionally(NonCoroCode, coroutineBodyStmt(), true,
+{"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithDeclCode = R"cpp(
+#include 
+void coro() {
+  int thevar;
+  co_return 1;
+}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithDeclCode,
+  coroutineBodyStmt(hasBody(compoundStmt(
+  has(declStmt(containsDeclaration(0, varDecl(hasName("thevar",
+  true, {"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithTryCatchDeclCode = R"cpp(
+#include 
+void coro() try {
+  int thevar;
+  co_return 1;
+} catch (...) {}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithTryCatchDeclCode,
+  coroutineBodyStmt(hasBody(cxxTryStmt(has(compoundStmt(has(
+  declStmt(containsDeclaration(0, varDecl(hasName("thevar")),
+  true, {"-std=c++20", "-I/"}, M));
 }
 
 TEST(Matcher, isClassMessage) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -175,6 +175,7 @@
   REGISTER_MATCHER(containsDeclaration);
   REGISTER_MATCHER(continueStmt);
   REGISTER_MATCHER(coreturnStmt);
+  REGISTER_MATCHER(coroutineBodyStmt);
   REGISTER_MATCHER(coyieldExpr);
   REGISTER_MATCHER(cudaKernelCallExpr);
   REGISTER_MATCHER(cxxBaseSpecifier);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -909,6 +909,8 @@
 const internal::VariadicDynCastAllOfMatcher caseStmt;
 const internal::VariadicDynCastAllOfMatcher defaultStmt;
 const internal::VariadicDynCastAllOfMatcher compoundStmt;
+const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
 const internal::VariadicDynCastAllOfMatcher cxxCatchStmt;
 const internal::VariadicDynCastAllOfMatcher cxxTryStmt;
 const internal::VariadicDynCastAllOfMatcher cxxThrowExpr;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2449,6 +2449,17 @@
 extern const internal::VariadicDynCastAllOfMatcher
 coyieldExpr;
 
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+///   generator gen() {
+/// co_return;
+///   }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
+
 /// Matches nullptr literal.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxNullPtrLiteralExpr;
@@ -5460,9 +5471,9 @@
 }
 
 /// Matches a 'for', 'while', 'do while' statement or a function
-/// definition that has a given body. Note that in case of 

[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487794.
ccotter added a comment.

- [clang-tidy] Support begin/end free functions in modernize-loop-convert
- Add release note
- Update docs
- Fix tests
- Remove unused variable


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,36 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+
+  dependent Vals;
+  for (int I = 0, E = size(Vals); E != I; ++I) {
+Sum += Vals[I].X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Val : Vals)
+  // CHECK-FIXES-NEXT: Sum += Val.X;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
+++ clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
@@ -91,10 +91,18 @@
   for (vector::iterator it = v.begin(); it != v.end(); ++it)
 cout << *it;
 
+  // reas

[PATCH] D140794: [ASTMatcher] Add coroutineBodyStmt matcher

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:5503
+  FunctionDecl,
+  CoroutineBodyStmt),
   internal::Matcher, InnerMatcher) {

aaron.ballman wrote:
> ccotter wrote:
> > aaron.ballman wrote:
> > > I'm not certain it makes sense to me to add `CoroutineBodyStmt` to 
> > > `hasBody` -- in this case, it doesn't *have* a body, it *is* the body.
> > With respect to `hasBody()`, my intent was to treat the CoroutineBodyStmt 
> > node as analogous to a FunctionDecl or WhileStmt. WhileStmts have 
> > information like the loop condition expression, as CoroutineBodyStmts 
> > contain the synthesized expressions such as the initial suspend Stmt. Both 
> > WhileStmts and CoroutineBodyStmts then have the `getBody()` methods, 
> > usually a CompoundStmt for WhileStmts and either a CompoundStmt or TryStmt 
> > for CoroutineBodyStmts.
> > 
> > Ultimately, I wanted to be able to match the CoroutineBodyStmt's 
> > `function-body` (using the grammar) from the standard, e.g., 
> > `coroutineBodyStmt(hasBody(compoundStmt().bind(...)))`. If there is a 
> > different approach you'd recommend that's in line with the AST matcher 
> > design strategy, I can use that instead.
> What concerns me about the approach you have is that it doesn't model the 
> AST. A coroutine body statement is a special kind of function body, so it 
> does not itself *have* a body. So this is a bit like adding `CompoundStmt` to 
> the `hasBody` matcher in that regard.
> 
> To me, the correct way to surface this would be to write the matcher: 
> `functionDecl(hasBody(coroutineBodyStmt()))` to get to the coroutine body, 
> and if you want to bind to the compound statement, I'd imagine 
> `functionDecl(hasBody(coroutineBodyStmt(has(compoundStmt().bind(...)` 
> would be the correct approach. My thinking there is that we'd use the `has()` 
> traversal matcher to go from the coroutine body to any of the extra 
> information it tracks (the compound statement, the promise, 
> allocate/deallocate, etc).
> 
> Pinging @klimek and @sammccall for additional opinions.
I think I see. With my proposal, the match would be 
`functionDecl(hasBody(coroutineBodyStmt(hasBody(stmt().bind(...)`. For 
completeness, your suggestion would need 
`functionDecl(hasBody(coroutineBodyStmt(has(stmt(anyOf(cxxTryStmt(), 
compoundStmt()).bind(...))`.

I am a bit hung up though on two things, and clarifications on both would help 
solidify my understanding of the design philosophy of the matchers. First, 
since `CoroutineBodyStmt` has a `getBody()` method, I assumed it would make it 
eligible for the `hasBody` matcher, although perhaps I am making an incorrect 
assumption/generalization here?

Second, the `has()` approach seems less accurate since we would be relying on 
the fact that the other children nodes of `CoroutineBodyStmt` (initial or final 
suspend point, etc) would never be a `CompoundStmt` or `CXXTryStmt`, else we 
might get unintentional matches. Or, one might miss the CXXTryStmt corner case.

Follow up question - should a need arise (say, authoring many clang-tidy checks 
that need extensive coroutine matcher support on the initial suspend point 
etc), would we see the matchers supporting things like 
`coroutineBodyStmt(hasInitialSuspendPoint(...), hasFinalSuspendPoint(..))`, or 
rely on a combination of `has` approach / non-ASTMatcher logic (or locally 
defined ASTMatchers within the clang-tidy library)?

It looks like this phab can be broken down into two changes - first, the 
addition of a `coroutineBodyStmt` matcher, and second, a `hasBody` traversal 
matcher for `coroutineBodyStmt`. Happy to separate these out depending on the 
direction of the discussion.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140794

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


[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487807.
ccotter added a comment.

- alpha


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
  clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -445,6 +445,34 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & I : Dpp)
   // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+
+  for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
 }
 
 // Tests to verify the proper use of auto where the init variable type and the
@@ -653,6 +681,36 @@
   // CHECK-FIXES: for (int I : V)
   // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
   // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = size(V); E != I; ++I) {
+V[I] = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : V)
+  // CHECK-FIXES-NEXT: I = 0;
+
+  // Although 'length' might be a valid free function, only std::size() is standardized
+  for (int I = 0, E = length(V); E != I; ++I) {
+printf("Fibonacci number is %d\n", V[I]);
+Sum += V[I] + 2;
+  }
+
+  dependent Vals;
+  for (int I = 0, E = size(Vals); E != I; ++I) {
+Sum += Vals[I].X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Val : Vals)
+  // CHECK-FIXES-NEXT: Sum += Val.X;
 }
 
 // Ensure that 'const auto &' is used with containers of non-trivial types.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/loop-convert/structures.h
@@ -39,6 +39,14 @@
   iterator end();
 };
 
+S::const_iterator begin(const S& s);
+S::const_iterator end(const S& s);
+S::const_iterator cbegin(const S& s);
+S::const_iterator cend(const S& s);
+S::iterator begin(S& s);
+S::iterator end(S& s);
+unsigned size(const S& s);
+
 struct T {
   typedef int value_type;
   struct iterator {
@@ -126,6 +134,11 @@
   void constFoo() const;
 };
 
+template
+unsigned size(const dependent&);
+template
+unsigned length(const dependent&);
+
 template
 class doublyDependent{
  public:
Index: clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
+++ clang-tools-extra/docs/clang-tidy/checks/modernize/loop-convert.rst
@@ -91,10 +91,18 @@
   for (vector::iterator it = v.begin(); it != v.end(); ++it)
 cout << *it;
 
+  // reasonable conversion
+  for (vector::iterator it = begin(v); it != end(v); ++it)
+cout << *it;
+
   // reasonable conversion
   for (in

[PATCH] D141391: [NFC] [clang-tools-extra] Alphabetize clang-tidy release notes

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Alphabetize order of clang-tidy release notes, and fix `:doc:` link.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141391

Files:
  clang-tools-extra/docs/ReleaseNotes.rst


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -167,6 +167,12 @@
   ` check for 
exceptions
   thrown by code emitted from macros in system headers.
 
+- Improved :doc:`misc-redundant-expression 
`
+  check.
+
+  The check now skips concept definitions since redundant expressions still 
make sense
+  inside them.
+
 - Improved :doc:`modernize-use-emplace 
`
   check.
 
@@ -206,14 +212,8 @@
   ` to not
   warn about `const` value parameters of declarations inside macros.
 
-- Improved :doc:`misc-redundant-expression 
`
-  check.
-
-  The check now skips concept definitions since redundant expressions still 
make sense
-  inside them.
-
 - Support removing ``c_str`` calls from ``std::string_view`` constructor calls 
in
-  :doc: `readability-redundant-string-cstr 
`
+  :doc:`readability-redundant-string-cstr 
`
   check.
 
 Removed checks


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -167,6 +167,12 @@
   ` check for exceptions
   thrown by code emitted from macros in system headers.
 
+- Improved :doc:`misc-redundant-expression `
+  check.
+
+  The check now skips concept definitions since redundant expressions still make sense
+  inside them.
+
 - Improved :doc:`modernize-use-emplace `
   check.
 
@@ -206,14 +212,8 @@
   ` to not
   warn about `const` value parameters of declarations inside macros.
 
-- Improved :doc:`misc-redundant-expression `
-  check.
-
-  The check now skips concept definitions since redundant expressions still make sense
-  inside them.
-
 - Support removing ``c_str`` calls from ``std::string_view`` constructor calls in
-  :doc: `readability-redundant-string-cstr `
+  :doc:`readability-redundant-string-cstr `
   check.
 
 Removed checks
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140760: [clang-tidy] Support begin/end free functions in modernize-loop-convert

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: clang-tools-extra/docs/ReleaseNotes.rst:219
 
+- Improved :doc:`modernize-loop-convert 
` to
+  refactor container based for loops that initialize iterators with free 
function calls

Eugene.Zelenko wrote:
> Please keep alphabetical order (for check names) in this section.
Done, and I fixed what looks like an existing out of order check in the release 
notes: https://reviews.llvm.org/D141391


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140760

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


[PATCH] D141391: [NFC] [clang-tools-extra] Alphabetize clang-tidy release notes

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

I can't land these myself, so if you are able to, would you mind doing so? 
Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141391

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


[PATCH] D141391: [NFC] [clang-tools-extra] Alphabetize clang-tidy release notes

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 487813.
ccotter added a comment.

- merge from upstream


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141391

Files:
  clang-tools-extra/docs/ReleaseNotes.rst


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -167,6 +167,16 @@
   ` check for 
exceptions
   thrown by code emitted from macros in system headers.
 
+- Improved :doc:`misc-redundant-expression 
`
+  check.
+
+  The check now skips concept definitions since redundant expressions still 
make sense
+  inside them.
+
+- Improved :doc:`modernize-loop-convert 
`
+  to check for container functions ``begin``/``end`` etc on base classes of 
the container
+  type, instead of only as direct members of the container type itself.
+
 - Improved :doc:`modernize-use-emplace 
`
   check.
 
@@ -206,20 +216,10 @@
   ` to not
   warn about `const` value parameters of declarations inside macros.
 
-- Improved :doc:`misc-redundant-expression 
`
-  check.
-
-  The check now skips concept definitions since redundant expressions still 
make sense
-  inside them.
-
 - Support removing ``c_str`` calls from ``std::string_view`` constructor calls 
in
-  :doc: `readability-redundant-string-cstr 
`
+  :doc:`readability-redundant-string-cstr 
`
   check.
 
-- Improved :doc:`modernize-loop-convert 
`
-  to check for container functions ``begin``/``end`` etc on base classes of 
the container
-  type, instead of only as direct members of the container type itself.
-
 Removed checks
 ^^
 


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -167,6 +167,16 @@
   ` check for exceptions
   thrown by code emitted from macros in system headers.
 
+- Improved :doc:`misc-redundant-expression `
+  check.
+
+  The check now skips concept definitions since redundant expressions still make sense
+  inside them.
+
+- Improved :doc:`modernize-loop-convert `
+  to check for container functions ``begin``/``end`` etc on base classes of the container
+  type, instead of only as direct members of the container type itself.
+
 - Improved :doc:`modernize-use-emplace `
   check.
 
@@ -206,20 +216,10 @@
   ` to not
   warn about `const` value parameters of declarations inside macros.
 
-- Improved :doc:`misc-redundant-expression `
-  check.
-
-  The check now skips concept definitions since redundant expressions still make sense
-  inside them.
-
 - Support removing ``c_str`` calls from ``std::string_view`` constructor calls in
-  :doc: `readability-redundant-string-cstr `
+  :doc:`readability-redundant-string-cstr `
   check.
 
-- Improved :doc:`modernize-loop-convert `
-  to check for container functions ``begin``/``end`` etc on base classes of the container
-  type, instead of only as direct members of the container type itself.
-
 Removed checks
 ^^
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488084.
ccotter added a comment.

- clang-format
- Show whether 'this' is implicitly captured
- fix docs


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-this-with-capture-default.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_locals2 = [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref = [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref2 = [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref3 = [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref4 = [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_extra_whitespace = [&  local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_with_comment = [& /* byref */ local, &local2, this]() { return (local+x) > 10; };
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that imp

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488085.
ccotter added a comment.

- Rename test to match check name


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_locals2 = [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref = [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref2 = [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref3 = [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref4 = [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_extra_whitespace = [&  local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_with_comment = [& /* byref */ local, &local2, this]() { return (local+x) > 10; };
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that implicitly capture 'this' should n

[PATCH] D141463: [clang-tidy] Improve rename_check.py

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

rename_check.py now find and renames the test file. rename_check.py
also will now use 'git mv', so the developer no longer has to manually
add the file after running the script.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141463

Files:
  clang-tools-extra/clang-tidy/rename_check.py


Index: clang-tools-extra/clang-tidy/rename_check.py
===
--- clang-tools-extra/clang-tidy/rename_check.py
+++ clang-tools-extra/clang-tidy/rename_check.py
@@ -15,6 +15,7 @@
 import io
 import os
 import re
+import subprocess
 
 def replaceInFileRegex(fileName, sFrom, sTo):
   if sFrom == sTo:
@@ -71,7 +72,7 @@
 return fileName
   newFileName = fileName.replace(sFrom, sTo)
   print("Renaming '%s' -> '%s'..." % (fileName, newFileName))
-  os.rename(fileName, newFileName)
+  subprocess.check_call(["git", "mv", fileName, newFileName])
   return newFileName
 
 
@@ -93,12 +94,9 @@
 
 
 def getListOfFiles(clang_tidy_path):
-  files = glob.glob(os.path.join(clang_tidy_path, '*'))
-  for dirname in files:
-if os.path.isdir(dirname):
-  files += glob.glob(os.path.join(dirname, '*'))
+  files = glob.glob(os.path.join(clang_tidy_path, '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'test',
-  'clang-tidy', '*'))
+  'clang-tidy', 'checkers', '**'), 
recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'docs',
   'clang-tidy', 'checks', '*'))
   return [filename for filename in files if os.path.isfile(filename)]
@@ -273,10 +271,12 @@
 deleteMatchingLines(os.path.join(old_module_path, modulecpp),
   '\\b' + check_name_camel + '|\\b' + args.old_check_name)
 
+  old_check_filename = '-'.join(args.old_check_name.split('-')[1:])
+  new_check_filename = '-'.join(args.new_check_name.split('-')[1:])
+
   for filename in getListOfFiles(clang_tidy_path):
 originalName = filename
-filename = fileRename(filename, args.old_check_name,
-  args.new_check_name)
+filename = fileRename(filename, old_check_filename, new_check_filename)
 filename = fileRename(filename, check_name_camel, new_check_name_camel)
 replaceInFile(filename, generateCommentLineHeader(originalName),
   generateCommentLineHeader(filename))


Index: clang-tools-extra/clang-tidy/rename_check.py
===
--- clang-tools-extra/clang-tidy/rename_check.py
+++ clang-tools-extra/clang-tidy/rename_check.py
@@ -15,6 +15,7 @@
 import io
 import os
 import re
+import subprocess
 
 def replaceInFileRegex(fileName, sFrom, sTo):
   if sFrom == sTo:
@@ -71,7 +72,7 @@
 return fileName
   newFileName = fileName.replace(sFrom, sTo)
   print("Renaming '%s' -> '%s'..." % (fileName, newFileName))
-  os.rename(fileName, newFileName)
+  subprocess.check_call(["git", "mv", fileName, newFileName])
   return newFileName
 
 
@@ -93,12 +94,9 @@
 
 
 def getListOfFiles(clang_tidy_path):
-  files = glob.glob(os.path.join(clang_tidy_path, '*'))
-  for dirname in files:
-if os.path.isdir(dirname):
-  files += glob.glob(os.path.join(dirname, '*'))
+  files = glob.glob(os.path.join(clang_tidy_path, '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'test',
-  'clang-tidy', '*'))
+  'clang-tidy', 'checkers', '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'docs',
   'clang-tidy', 'checks', '*'))
   return [filename for filename in files if os.path.isfile(filename)]
@@ -273,10 +271,12 @@
 deleteMatchingLines(os.path.join(old_module_path, modulecpp),
   '\\b' + check_name_camel + '|\\b' + args.old_check_name)
 
+  old_check_filename = '-'.join(args.old_check_name.split('-')[1:])
+  new_check_filename = '-'.join(args.new_check_name.split('-')[1:])
+
   for filename in getListOfFiles(clang_tidy_path):
 originalName = filename
-filename = fileRename(filename, args.old_check_name,
-  args.new_check_name)
+filename = fileRename(filename, old_check_filename, new_check_filename)
 filename = fileRename(filename, check_name_camel, new_check_name_camel)
 replaceInFile(filename, generateCommentLineHeader(originalName),
   generateCommentLineHeader(filename))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141463: [clang-tidy] Improve rename_check.py

2023-01-10 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

I tested with https://reviews.llvm.org/D141133 where I renamed my new check, 
but noticed rename_tool.py did not rename or update the check name in the test 
file. The result of running the updated script against my tool is on github: 
https://github.com/ccotter/llvm-project/commit/b0f5118d4a2d1c5100170784117b26e59d4df0bc


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141463

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


[PATCH] D141463: [clang-tidy] Improve rename_check.py

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/rename_check.py:97
 def getListOfFiles(clang_tidy_path):
-  files = glob.glob(os.path.join(clang_tidy_path, '*'))
-  for dirname in files:
-if os.path.isdir(dirname):
-  files += glob.glob(os.path.join(dirname, '*'))
+  files = glob.glob(os.path.join(clang_tidy_path, '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'test',

carlosgalvezp wrote:
> Why is this change needed? I'd expect only line 99 to be needed to fix moving 
> the test.
Ah, it's not needed, but I thought it was a bit cleaner to have both the globs 
take the same approach and be recursive, avoiding the for-loop over the 
subdirectories.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141463

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


[PATCH] D141463: [clang-tidy] Improve rename_check.py

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488169.
ccotter added a comment.

- revert git changes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141463

Files:
  clang-tools-extra/clang-tidy/rename_check.py


Index: clang-tools-extra/clang-tidy/rename_check.py
===
--- clang-tools-extra/clang-tidy/rename_check.py
+++ clang-tools-extra/clang-tidy/rename_check.py
@@ -93,12 +93,9 @@
 
 
 def getListOfFiles(clang_tidy_path):
-  files = glob.glob(os.path.join(clang_tidy_path, '*'))
-  for dirname in files:
-if os.path.isdir(dirname):
-  files += glob.glob(os.path.join(dirname, '*'))
+  files = glob.glob(os.path.join(clang_tidy_path, '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'test',
-  'clang-tidy', '*'))
+  'clang-tidy', 'checkers', '**'), 
recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'docs',
   'clang-tidy', 'checks', '*'))
   return [filename for filename in files if os.path.isfile(filename)]
@@ -273,10 +270,12 @@
 deleteMatchingLines(os.path.join(old_module_path, modulecpp),
   '\\b' + check_name_camel + '|\\b' + args.old_check_name)
 
+  old_check_filename = '-'.join(args.old_check_name.split('-')[1:])
+  new_check_filename = '-'.join(args.new_check_name.split('-')[1:])
+
   for filename in getListOfFiles(clang_tidy_path):
 originalName = filename
-filename = fileRename(filename, args.old_check_name,
-  args.new_check_name)
+filename = fileRename(filename, old_check_filename, new_check_filename)
 filename = fileRename(filename, check_name_camel, new_check_name_camel)
 replaceInFile(filename, generateCommentLineHeader(originalName),
   generateCommentLineHeader(filename))


Index: clang-tools-extra/clang-tidy/rename_check.py
===
--- clang-tools-extra/clang-tidy/rename_check.py
+++ clang-tools-extra/clang-tidy/rename_check.py
@@ -93,12 +93,9 @@
 
 
 def getListOfFiles(clang_tidy_path):
-  files = glob.glob(os.path.join(clang_tidy_path, '*'))
-  for dirname in files:
-if os.path.isdir(dirname):
-  files += glob.glob(os.path.join(dirname, '*'))
+  files = glob.glob(os.path.join(clang_tidy_path, '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'test',
-  'clang-tidy', '*'))
+  'clang-tidy', 'checkers', '**'), recursive=True)
   files += glob.glob(os.path.join(clang_tidy_path, '..', 'docs',
   'clang-tidy', 'checks', '*'))
   return [filename for filename in files if os.path.isfile(filename)]
@@ -273,10 +270,12 @@
 deleteMatchingLines(os.path.join(old_module_path, modulecpp),
   '\\b' + check_name_camel + '|\\b' + args.old_check_name)
 
+  old_check_filename = '-'.join(args.old_check_name.split('-')[1:])
+  new_check_filename = '-'.join(args.new_check_name.split('-')[1:])
+
   for filename in getListOfFiles(clang_tidy_path):
 originalName = filename
-filename = fileRename(filename, args.old_check_name,
-  args.new_check_name)
+filename = fileRename(filename, old_check_filename, new_check_filename)
 filename = fileRename(filename, check_name_camel, new_check_name_camel)
 replaceInFile(filename, generateCommentLineHeader(originalName),
   generateCommentLineHeader(filename))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141463: [clang-tidy] Improve rename_check.py

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/rename_check.py:75
   print("Renaming '%s' -> '%s'..." % (fileName, newFileName))
-  os.rename(fileName, newFileName)
+  subprocess.check_call(["git", "mv", fileName, newFileName])
   return newFileName

carlosgalvezp wrote:
> I'm not sure it's the responsibility of this check to do git stuff, there may 
> be use cases where this is not wanted / users might not expect this behavior. 
> Introducing a dependency to git might also make this script harder to unit 
> test in the future.
> 
> Thus I think it'd be better to keep the original behavior so the script has 
> one single responsibility. What do you think @njames93 ?
I wasn't sure about this - reverted this. Single responsibility is better.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141463

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp:1
+// RUN: %check_clang_tidy -std=c++14-or-later %s 
cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- 
-fno-delayed-template-parsing
+

carlosgalvezp wrote:
> You specified C++11 in the LangOpts, but test against C++14 or later in the 
> test, maybe change it here to c++11-or-later?
The test uses generalize lambda capture, so it needs 14. Should I split the 
tests that use C++14 features to a separate file, and update this test file to 
use 11?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp:1
+// RUN: %check_clang_tidy -std=c++14-or-later %s 
cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- 
-fno-delayed-template-parsing
+

ccotter wrote:
> carlosgalvezp wrote:
> > You specified C++11 in the LangOpts, but test against C++14 or later in the 
> > test, maybe change it here to c++11-or-later?
> The test uses generalize lambda capture, so it needs 14. Should I split the 
> tests that use C++14 features to a separate file, and update this test file 
> to use 11?
Ah, and use of `auto` parameters in other lambdas. So there are a few tests 
that would need to be split out to a separate file, use an `ifdef __cplusplus` 
check (I see one other cppcoreguidelines test does this).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 491978.
ccotter added a comment.

- Fix universal reference check; move diagnostic location to parameter name


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,286 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:47: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguideline

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 491989.
ccotter added a comment.

- Use match instead of bespoke traversal


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,286 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:47: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp:13
+
+#include 
+

carlosgalvezp wrote:
> Not sure if this is allowed in the repo or if we should use something 
> equivalent from ADT.
I was able to replace this with a cleaner solution


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added a comment.

In D141569#4048359 , @njames93 wrote:

> What happens with code like this
>
>   void foo(bar&& B) {
> std::move(B);
>   }

https://github.com/isocpp/CppCoreGuidelines/issues/2026#issuecomment-1402454584 
pointed out there's another guideline, ES.56, which a "useless" `move` such as 
this example would violate. I imagine this should be a different clang-tidy 
check though?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp:1
+// RUN: %check_clang_tidy -std=c++14-or-later %s 
cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- 
-fno-delayed-template-parsing
+

carlosgalvezp wrote:
> ccotter wrote:
> > ccotter wrote:
> > > carlosgalvezp wrote:
> > > > You specified C++11 in the LangOpts, but test against C++14 or later in 
> > > > the test, maybe change it here to c++11-or-later?
> > > The test uses generalize lambda capture, so it needs 14. Should I split 
> > > the tests that use C++14 features to a separate file, and update this 
> > > test file to use 11?
> > Ah, and use of `auto` parameters in other lambdas. So there are a few tests 
> > that would need to be split out to a separate file, use an `ifdef 
> > __cplusplus` check (I see one other cppcoreguidelines test does this).
> Oops I forgot to submit my comment. Yes I think we could keep everything in 
> one test file running `c++11-or-later`, and `#ifdef` the C++14 parts.
This didn't actually end up working. The test failed looking for expected 
CHECK-MESSAGES, e.g.,

```
#if __cplusplus >= 201402L
/* bad code */
// CHECK-MESSAGES
#endif
```

I'll go the separate file route then?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 491992.
ccotter added a comment.

- Use multiple runs on the same test file


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,293 @@
+// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -check-suffix=,CXX14 -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+#if __cplusplus >= 201402L
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj other{o1

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-24 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked an inline comment as done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp:1
+// RUN: %check_clang_tidy -std=c++14-or-later %s 
cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- 
-fno-delayed-template-parsing
+

carlosgalvezp wrote:
> ccotter wrote:
> > carlosgalvezp wrote:
> > > ccotter wrote:
> > > > ccotter wrote:
> > > > > carlosgalvezp wrote:
> > > > > > You specified C++11 in the LangOpts, but test against C++14 or 
> > > > > > later in the test, maybe change it here to c++11-or-later?
> > > > > The test uses generalize lambda capture, so it needs 14. Should I 
> > > > > split the tests that use C++14 features to a separate file, and 
> > > > > update this test file to use 11?
> > > > Ah, and use of `auto` parameters in other lambdas. So there are a few 
> > > > tests that would need to be split out to a separate file, use an `ifdef 
> > > > __cplusplus` check (I see one other cppcoreguidelines test does this).
> > > Oops I forgot to submit my comment. Yes I think we could keep everything 
> > > in one test file running `c++11-or-later`, and `#ifdef` the C++14 parts.
> > This didn't actually end up working. The test failed looking for expected 
> > CHECK-MESSAGES, e.g.,
> > 
> > ```
> > #if __cplusplus >= 201402L
> > /* bad code */
> > // CHECK-MESSAGES
> > #endif
> > ```
> > 
> > I'll go the separate file route then?
> Hmm right.
> 
> What about 2 `RUN` commands in the same file? One of them you run it for 
> `c++11` and the other for `c++14-or-later`. You can add a `check-prefix` for 
> the C++14 case, then use `CHECK-MESSAGES-SOMEPREFIX` such that it only 
> applies to that test invocation. No need to duplicate `CHECK-MESSAGES` for 
> both runs - if no prefix is specified, it will apply to all runs. 
> 
> Something like:
> 
> ```
> #if __cplusplus >= 201402L
> /* bad code */
> // CHECK-MESSAGES-CXX14
> #endif
> ```
> 
> If it gets too messy maybe a separate test file is the better option, I'm 
> hoping there's not much duplication that needs to be maintaned.
Perfect - I didn't realize the test/checker framework was this flexible. Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-27 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 492981.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture = [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_locals1 = [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_locals2 = [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref = [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref2 = [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref3 = [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref4 = [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_extra_whitespace = [&  local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_with_comment = [& /* byref */ local, &local2, this]() { return (local+x) > 10; };
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas 

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 493004.
ccotter marked an inline comment as done.
ccotter added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,293 @@
+// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -check-suffix=,CXX14 -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+#if __cplusplus >= 201402L
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj o

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

In https://github.com/isocpp/CppCoreGuidelines/issues/2026, it looks like the 
core guideline will not permit exceptions for code that accepts an rvalue ref 
parameter, and the function body `moves` members of the parameter. So, my 
`moves_member_of_parameter` test case would be flagged. In theory, we could add 
a tool option to allow someone to live more "dangerously" and have the tool 
accept code like `moves_member_of_parameter`, with the caveat that the tool (as 
I have written it so far) would not be smart enough to detect that all static 
paths move every data member of the object. In any case, I'll update my test 
and the tool to align exactly with the guideline.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141892: Implement modernize-use-constraints

2023-01-28 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 493050.
ccotter added a comment.

Rebase + Simplify match logic


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int& reference_of_enable_

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-29 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

Gentle poke for any last reviews?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked 2 inline comments as done.
ccotter added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp:81
+  Lambda->getCaptureDefaultLoc(),
+  "lambdas that capture 'this' should not specify a capture default");
+

carlosgalvezp wrote:
> njames93 wrote:
> > Would be nice to show if `this` is implicitly captured.
> Was this comment addressed? I see it marked as "Not Done".
oh yes, I forgot to mark addressed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141892: Implement modernize-use-constraints

2023-02-02 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

This is more or less ready for review (not planning on making any further 
changes; there are more features to be added, but I was thinking of handling 
those in follow up changesets). I know it's a relatively large review, but let 
me know if anyone can take a first pass. Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141892

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-02-04 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 494850.
ccotter added a comment.

- Add parameter name to diagnostic


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,293 @@
+// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -check-suffix=,CXX14 -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+#if __cplusplus >= 201402L
+  auto never_moves_with_auto_param = [](

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-02-04 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 494852.
ccotter added a comment.

- Update per https://github.com/isocpp/CppCoreGuidelines/issues/2026


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,295 @@
+// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -check-suffix=,CXX14 -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- -- -fno-delayed-template-parsing
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+#if __cplusplus >= 201402L
+  auto

[PATCH] D139122: Generalize clang-tidy modernize-pass-by-value

2023-02-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp:11
+#include "../utils/Aliasing.h"
+#include "../utils/ExprSequence.h"
 #include "clang/AST/ASTContext.h"

I think you need to add `clangAnalysis` (for Analysis/CFG.h) to the link 
libraries in modernize/CMakeLists.txt.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139122

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


[PATCH] D139122: Generalize clang-tidy modernize-pass-by-value

2023-02-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

https://reviews.llvm.org/D137205 looks to be similar in part, as it applies a 
FixIt to a any last use of an object if the use a copy, including parameters 
and local objects.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139122

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


[PATCH] D137205: [clang-tidy] Add performance-unnecessary-copy-on-last-use check

2023-02-05 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.
Herald added a subscriber: ChuanqiXu.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-on-last-use.cpp:77
+
+Movable testReturn2(Movable && Mov, bool F) {
+  return F? Mov: Movable{}; 

Could you add another test where `Mov` is just a `Movable` value?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137205

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


[PATCH] D141569: Implement CppCoreGuideline F.18

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added subscribers: carlosgalvezp, shchenz, kbarton, nemanjai.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Warn when an rvalue reference function paramter is never moved
from within the function body.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,224 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+struct remove_reference<_Tp &> {
+  typedef _Tp type;
+};
+
+template 
+struct remove_reference<_Tp &&> {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept {
+  return static_cast::type &&>(__t);
+}
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept {
+  return static_cast<_Tp &&>(__t);
+}
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:25: 

[PATCH] D141570: [clang] Add no-argument dump to DynTypedNode

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: carlosgalvezp.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

Provide a no-argument dump methods to avoid having to do
additional gymnastics to dump a DynTypedNode.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141570

Files:
  clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
  clang/include/clang/AST/ASTTypeTraits.h
  clang/lib/AST/ASTTypeTraits.cpp


Index: clang/lib/AST/ASTTypeTraits.cpp
===
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -213,6 +213,17 @@
 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
 }
 
+void DynTypedNode::dump() const {
+  if (const Decl *D = get())
+D->dump();
+  else if (const Stmt *S = get())
+S->dump();
+  else if (const Type *T = get())
+T->dump();
+  else
+llvm::errs() << "Unable to dump values of type " << NodeKind.asStringRef() 
<< "\n";
+}
+
 SourceRange DynTypedNode::getSourceRange() const {
   if (const CXXCtorInitializer *CCI = get())
 return CCI->getSourceRange();
Index: clang/include/clang/AST/ASTTypeTraits.h
===
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -296,6 +296,9 @@
   /// Dumps the node to the given output stream.
   void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
+  /// Dumps the node to \c llvm::errs().
+  void dump() const;
+
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
   SourceRange getSourceRange() const;
Index: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -430,6 +430,9 @@
 // be fine since for the statements we care about there should only be one
 // parent, except for the case specified below.
 
+llvm::errs() << "DUMP\n";
+Start.dump();
+
 assert(MacroLoc.isFileID());
 
 while (true) {


Index: clang/lib/AST/ASTTypeTraits.cpp
===
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -213,6 +213,17 @@
 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
 }
 
+void DynTypedNode::dump() const {
+  if (const Decl *D = get())
+D->dump();
+  else if (const Stmt *S = get())
+S->dump();
+  else if (const Type *T = get())
+T->dump();
+  else
+llvm::errs() << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
+}
+
 SourceRange DynTypedNode::getSourceRange() const {
   if (const CXXCtorInitializer *CCI = get())
 return CCI->getSourceRange();
Index: clang/include/clang/AST/ASTTypeTraits.h
===
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -296,6 +296,9 @@
   /// Dumps the node to the given output stream.
   void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
+  /// Dumps the node to \c llvm::errs().
+  void dump() const;
+
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
   SourceRange getSourceRange() const;
Index: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -430,6 +430,9 @@
 // be fine since for the statements we care about there should only be one
 // parent, except for the case specified below.
 
+llvm::errs() << "DUMP\n";
+Start.dump();
+
 assert(MacroLoc.isFileID());
 
 while (true) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141570: [clang] Add no-argument dump to DynTypedNode

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488494.
ccotter added a comment.

format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141570

Files:
  clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
  clang/include/clang/AST/ASTTypeTraits.h
  clang/lib/AST/ASTTypeTraits.cpp


Index: clang/lib/AST/ASTTypeTraits.cpp
===
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -213,6 +213,18 @@
 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
 }
 
+void DynTypedNode::dump() const {
+  if (const Decl *D = get())
+D->dump();
+  else if (const Stmt *S = get())
+S->dump();
+  else if (const Type *T = get())
+T->dump();
+  else
+llvm::errs() << "Unable to dump values of type " << NodeKind.asStringRef()
+ << "\n";
+}
+
 SourceRange DynTypedNode::getSourceRange() const {
   if (const CXXCtorInitializer *CCI = get())
 return CCI->getSourceRange();
Index: clang/include/clang/AST/ASTTypeTraits.h
===
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -296,6 +296,9 @@
   /// Dumps the node to the given output stream.
   void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
+  /// Dumps the node to \c llvm::errs().
+  void dump() const;
+
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
   SourceRange getSourceRange() const;
Index: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -430,6 +430,9 @@
 // be fine since for the statements we care about there should only be one
 // parent, except for the case specified below.
 
+llvm::errs() << "DUMP\n";
+Start.dump();
+
 assert(MacroLoc.isFileID());
 
 while (true) {


Index: clang/lib/AST/ASTTypeTraits.cpp
===
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -213,6 +213,18 @@
 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
 }
 
+void DynTypedNode::dump() const {
+  if (const Decl *D = get())
+D->dump();
+  else if (const Stmt *S = get())
+S->dump();
+  else if (const Type *T = get())
+T->dump();
+  else
+llvm::errs() << "Unable to dump values of type " << NodeKind.asStringRef()
+ << "\n";
+}
+
 SourceRange DynTypedNode::getSourceRange() const {
   if (const CXXCtorInitializer *CCI = get())
 return CCI->getSourceRange();
Index: clang/include/clang/AST/ASTTypeTraits.h
===
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -296,6 +296,9 @@
   /// Dumps the node to the given output stream.
   void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
+  /// Dumps the node to \c llvm::errs().
+  void dump() const;
+
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
   SourceRange getSourceRange() const;
Index: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -430,6 +430,9 @@
 // be fine since for the statements we care about there should only be one
 // parent, except for the case specified below.
 
+llvm::errs() << "DUMP\n";
+Start.dump();
+
 assert(MacroLoc.isFileID());
 
 while (true) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141570: [clang] Add no-argument dump to DynTypedNode

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488495.
ccotter added a comment.

remove accidental change


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141570

Files:
  clang/include/clang/AST/ASTTypeTraits.h
  clang/lib/AST/ASTTypeTraits.cpp


Index: clang/lib/AST/ASTTypeTraits.cpp
===
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -213,6 +213,18 @@
 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
 }
 
+void DynTypedNode::dump() const {
+  if (const Decl *D = get())
+D->dump();
+  else if (const Stmt *S = get())
+S->dump();
+  else if (const Type *T = get())
+T->dump();
+  else
+llvm::errs() << "Unable to dump values of type " << NodeKind.asStringRef()
+ << "\n";
+}
+
 SourceRange DynTypedNode::getSourceRange() const {
   if (const CXXCtorInitializer *CCI = get())
 return CCI->getSourceRange();
Index: clang/include/clang/AST/ASTTypeTraits.h
===
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -296,6 +296,9 @@
   /// Dumps the node to the given output stream.
   void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
+  /// Dumps the node to \c llvm::errs().
+  void dump() const;
+
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
   SourceRange getSourceRange() const;


Index: clang/lib/AST/ASTTypeTraits.cpp
===
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -213,6 +213,18 @@
 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
 }
 
+void DynTypedNode::dump() const {
+  if (const Decl *D = get())
+D->dump();
+  else if (const Stmt *S = get())
+S->dump();
+  else if (const Type *T = get())
+T->dump();
+  else
+llvm::errs() << "Unable to dump values of type " << NodeKind.asStringRef()
+ << "\n";
+}
+
 SourceRange DynTypedNode::getSourceRange() const {
   if (const CXXCtorInitializer *CCI = get())
 return CCI->getSourceRange();
Index: clang/include/clang/AST/ASTTypeTraits.h
===
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -296,6 +296,9 @@
   /// Dumps the node to the given output stream.
   void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
+  /// Dumps the node to \c llvm::errs().
+  void dump() const;
+
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
   SourceRange getSourceRange() const;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141570: [clang] Add no-argument dump to DynTypedNode

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

I usually use `dump()` when authoring/debugging clang-tidy or similar checks. I 
don't always have ASTContext handy when working with a DynTypedNode (without 
temporarily changing my call stack to pass the ASTContext around for the 
purposes of `dump`).

I put up this as a way of asking whether this kind of change would be 
considered (just as easy to code this up as ask in Discord etc). Thoughts?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141570

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-11 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488497.
ccotter added a comment.

- Does not offer fixits


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,224 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+struct remove_reference<_Tp &> {
+  typedef _Tp type;
+};
+
+template 
+struct remove_reference<_Tp &&> {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept {
+  return static_cast::type &&>(__t);
+}
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept {
+  return static_cast<_Tp &&>(__t);
+}
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj other{o1};
+  }

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 488943.
ccotter added a comment.

- Finish stengthening CHECK-FIXES


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t
+
+struct Obj {
+  void lambdas_that_warn_default_capture_copy() {
+int local{};
+int local2{};
+
+auto explicit_this_capture = [=, this]() { };
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture = [this]() { };
+
+auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_locals1 = [local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_locals2 = [local, local2, this]() { return (local+local2) > 10; };
+
+auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref = [this, &local]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref2 = [&local, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref3 = [&local, this, &local2]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref4 = [&local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_extra_whitespace = [=, &  local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_extra_whitespace = [&  local, &local2, this]() { return (local+x) > 10; };
+
+auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; };
+// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this]
+// CHECK-FIXES: auto explicit_this_capture_local_ref_with_comment = [& /* byref */ local, &local2, this]() { return (local+x) > 10; };
+
+auto implicit_this_capture = [=]() { return x > 10; };
+// CHECK-MESSAGES: :[[@LIN

[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter marked 2 inline comments as done.
ccotter added a comment.

Thanks for pointing that out.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141133: [clang-tidy] Implement CppCoreGuideline F.54

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

My latest update to the diff was the result of a rebase, then addressing the 
final comments. What I've been doing is something like

  git pull upstream main --rebase
  # make more edits
  git commit -am 
  arc diff --update D141133 upstream/main

I'm not sure if this is the best way to rebase phabs, but please let me know if 
there's a better way for phab to understand.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141133

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

> What happens with code like this
>
>   void foo(bar&& B) {
> std::move(B);
>   }

My new check does not flag this function, although it looks like another check 
flagged the move expression: `ignoring return value of function declared with 
const attribute [clang-diagnostic-unused-value]`. Guideline F.18 only says to 
flag functions where "the function body uses them without std::move." I think 
this could be improved with something like "the function body does not move 
construct or move assign the parameter, and does not pass the result of move() 
to another function which accepts rvalue references". I can open an issue on 
the CppCoreGuidelines repo to discuss this. On a related note, I believe 
there's another clang-tidy check that flags `move` on const values, so I could 
see clang-tidy similarly checking other "nonsense" move expressions such as 
this one (separate check).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp:3-35
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {

njames93 wrote:
> You can just declare these methods and the base struct, no need to do 
> anything fancy in here and put definitions in there
Ah, I picked a different test to copy/paste from which does define them 😛. Will 
fix.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp:3-35
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {

ccotter wrote:
> njames93 wrote:
> > You can just declare these methods and the base struct, no need to do 
> > anything fancy in here and put definitions in there
> Ah, I picked a different test to copy/paste from which does define them 😛. 
> Will fix.
Note, I think all but one existing checks end up defining a more thorough 
definition of remove_reference:

```
 git grep 'struct remove_ref' | sed -r 's/:.*//' | sort | uniq -c | sort -n
   1 modernize/use-transparent-functors.cpp
   2 cppcoreguidelines/rvalue-reference-param-not-moved.cpp
   3 bugprone/Inputs/unchecked-optional-access/absl/types/optional.h
   3 bugprone/forwarding-reference-overload.cpp
   3 misc/throw-by-value-catch-by-reference.cpp
   3 misc/unconventional-assign-operator.cpp
   3 modernize/use-emplace.cpp
   3 performance/for-range-copy.cpp
   3 performance/move-constructor-init.cpp
   4 bugprone/move-forwarding-reference.cpp
   4 bugprone/use-after-move.cpp
   4 performance/move-const-arg-const-ref.cpp
   4 performance/move-const-arg-trivially-copyable.cpp
   4 performance/move-const-arg.cpp
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

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


[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 489007.
ccotter added a comment.

- two more tests
- Minimize test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,222 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+// Negative tests - below functions d

[PATCH] D141569: [clang-tidy] Implement CppCoreGuideline F.18

2023-01-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 489174.
ccotter added a comment.

- Match unresolved calls to move


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141569

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/rvalue-reference-param-not-moved.cpp
@@ -0,0 +1,230 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-rvalue-reference-param-not-moved %t
+
+// NOLINTBEGIN
+namespace std {
+template 
+struct remove_reference;
+
+template 
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template 
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;
+
+template 
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept;
+
+}
+// NOLINTEND
+
+struct Obj {
+  Obj();
+  Obj(const Obj&);
+  Obj& operator=(const Obj&);
+  Obj(Obj&&);
+  Obj& operator=(Obj&&);
+  void member() const;
+};
+
+void consumes_object(Obj);
+
+void never_moves_param(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void copies_object(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  Obj copy = o;
+}
+
+template 
+void never_moves_param_template(Obj&& o, T t) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  o.member();
+}
+
+void never_moves_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void never_moves_some_params(Obj&& o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  Obj other{std::move(o2)};
+}
+
+void never_moves_mixed(Obj o1, Obj&& o2) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value(Obj&& o) {
+  auto f = [o]() {
+consumes_object(std::move(o));
+  };
+  // CHECK-MESSAGES: :[[@LINE-4]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+void lambda_captures_parameter_as_value_nested(Obj&& o) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+  auto f = [&o]() {
+auto f_nested = [o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f2 = [o]() {
+auto f_nested = [&o]() {
+  consumes_object(std::move(o));
+};
+  };
+  auto f3 = [o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [&o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+  auto f4 = [&o]() {
+auto f_nested = [&o]() {
+  auto f_nested_inner = [o]() {
+consumes_object(std::move(o));
+  };
+};
+  };
+}
+
+void misc_lambda_checks() {
+  auto never_moves = [](Obj&& o1) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:25: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+
+  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
+Obj other{o1};
+  };
+  // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: rvalue reference parameter is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
+}
+
+// Negative tests - below functions d

[PATCH] D141892: Implement modernize-use-constraints

2023-01-16 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: carlosgalvezp.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Add new check to replace enable_if with C++20 constraints


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141892

Files:
  clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
  clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints-first-greatergreater.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp
@@ -0,0 +1,693 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t
+
+// NOLINTBEGIN
+namespace std {
+template  struct enable_if { };
+
+template  struct enable_if { typedef T type; };
+
+template 
+using enable_if_t = typename enable_if::type;
+
+} // namespace std
+// NOLINTEND
+
+template 
+struct ConsumeVariadic;
+
+struct Obj {
+};
+
+namespace enable_if_in_return_type {
+
+
+// Section 1: enable_if in return type of function
+
+
+
+// General tests
+
+
+template 
+typename std::enable_if::type basic() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t basic_t() {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}Obj basic_t() requires T::some_value {{{$}}
+
+template 
+auto basic_trailing() -> typename std::enable_if::type {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:26: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}auto basic_trailing() -> Obj requires T::some_value {{{$}}
+
+template 
+typename std::enable_if::type existing_constraint() requires (T::another_value) {
+  return Obj{};
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}typename std::enable_if::type existing_constraint() requires (T::another_value) {{{$}}
+
+template 
+typename std::enable_if::type decl_without_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def();
+
+template 
+typename std::enable_if::type decl_with_separate_def() {
+  return Obj{};
+}
+// FIXME - Support definitions with separate decls
+
+template 
+std::enable_if_t no_dependent_type(U) {
+  return Obj{};
+}
+// FIXME - Support non-dependent enable_ifs. Low priority though...
+
+template 
+typename std::enable_if::type* pointer_of_enable_if() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t* pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int* pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+const std::enable_if_t* const_pointer_of_enable_if_t() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}const int* const_pointer_of_enable_if_t() requires T::some_value {{{$}}
+
+template 
+std::enable_if_t const * const_pointer_of_enable_if_t2() {
+  return nullptr;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
+// CHECK-FIXES: {{^}}template {{$}}
+// CHECK-FIXES-NEXT: {{^}}int const * const_pointer_of_enable_if_t2() requires T::some_value {{{$}}
+
+
+template 
+std::enable_if_t& reference_of_enable_if_t() {
+  static int x; return x;
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++20 requires constraints instead of enable_if 

[PATCH] D141892: Implement modernize-use-constraints

2023-01-16 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

For the sake of demonstration, 
https://github.com/llvm/llvm-project/commit/9c556ce59edf5a4293d4497d5815544afc0eb878
 is the result of running this tool on all headers under clang/include/clang 
and llvm/include/llvm.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141892

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


  1   2   3   >