[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-21 Thread Piotr Zegar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa7bdaff7cad9: [clang-tidy] Implement 
bugprone-incorrect-enable-if (authored by ccotter, committed by PiotrZSL).

Changed prior to commit:
  https://reviews.llvm.org/D157239?vs=549777=552077#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy -std=c++11 %s bugprone-incorrect-enable-if %t
+// RUN: %check_clang_tidy -check-suffix=CXX20 -std=c++20 %s bugprone-incorrect-enable-if %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 ::type>
+void valid_function1() {}
+
+template ::type = nullptr>
+void valid_function2() {}
+
+template ::type = nullptr>
+struct ValidClass1 {};
+
+template >
+void invalid() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+// CHECK-FIXES-CXX20: template ::type>
+
+template  >
+void invalid_extra_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type >
+// CHECK-FIXES-CXX20: template ::type >
+
+template >
+void invalid_extra_no_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+// CHECK-FIXES-CXX20: template ::type>
+
+template /*comment3*/>
+void invalid_extra_comment() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type/*comment3*/>
+
+template , typename = std::enable_if>
+void invalid_multiple() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-MESSAGES: [[@LINE-3]]:65: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type, typename = typename std::enable_if::type>
+// CHECK-FIXES-CXX20: template ::type, typename = std::enable_if::type>
+
+template >
+struct InvalidClass {};
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+// CHECK-FIXES-CXX20: template ::type>
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
@@ -94,6 +94,7 @@
:doc:`bugprone-implicit-widening-of-multiplication-result `, "Yes"
:doc:`bugprone-inaccurate-erase `, "Yes"
:doc:`bugprone-inc-dec-in-conditions `,
+   :doc:`bugprone-incorrect-enable-if `, "Yes"
:doc:`bugprone-incorrect-roundings `,
:doc:`bugprone-infinite-loop `,
:doc:`bugprone-integer-division `,
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
@@ -0,0 +1,48 @@
+.. title:: clang-tidy - bugprone-incorrect-enable-if
+
+bugprone-incorrect-enable-if
+
+
+Detects incorrect usages of ``std::enable_if`` that don't name the nested
+``type`` type.
+
+In C++11 introduced ``std::enable_if`` as a convenient way to leverage SFINAE.
+One form of using ``std::enable_if`` is to declare an unnamed template type
+parameter with a default type equal to
+``typename std::enable_if::type``. If the author forgets to name
+the nested type ``type``, then the code will 

[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-21 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL added a comment.

I'm pushing this, if you want to change anything else, just please open new 
review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-14 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL accepted this revision.
PiotrZSL added a comment.
This revision is now accepted and ready to land.

LGTM (+-)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

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

> Do you have plans to also detect the bugprone scenario described in the Notes 
> here?

I didn't have plans in this review, or in the immediate future after. I did 
name this check broadly as "bugprone-incorrect-enable-if," so I imagine this 
other scenario could go into this new check.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-13 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/bugprone/IncorrectEnableIfCheck.cpp:61-62
+
+  FixItHint TypenameHint =
+  FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(), "typename ");
+  FixItHint TypeHint =

PiotrZSL wrote:
> do we still need typename in C++20 in this context ?
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3.html
Oh, I did not know that. Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-13 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 549777.
ccotter marked 9 inline comments as done.
ccotter added a comment.

- Fix docs, handle C++20 simplification


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy -std=c++11 %s bugprone-incorrect-enable-if %t
+// RUN: %check_clang_tidy -check-suffix=CXX20 -std=c++20 %s bugprone-incorrect-enable-if %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 ::type>
+void valid_function1() {}
+
+template ::type = nullptr>
+void valid_function2() {}
+
+template ::type = nullptr>
+struct ValidClass1 {};
+
+template >
+void invalid() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+// CHECK-FIXES-CXX20: template ::type>
+
+template  >
+void invalid_extra_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type >
+// CHECK-FIXES-CXX20: template ::type >
+
+template >
+void invalid_extra_no_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+// CHECK-FIXES-CXX20: template ::type>
+
+template /*comment3*/>
+void invalid_extra_comment() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type/*comment3*/>
+
+template , typename = std::enable_if>
+void invalid_multiple() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-MESSAGES: [[@LINE-3]]:65: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type, typename = typename std::enable_if::type>
+// CHECK-FIXES-CXX20: template ::type, typename = std::enable_if::type>
+
+template >
+struct InvalidClass {};
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+// CHECK-FIXES-CXX20: template ::type>
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
@@ -94,6 +94,7 @@
`bugprone-implicit-widening-of-multiplication-result `_, "Yes"
`bugprone-inaccurate-erase `_, "Yes"
`bugprone-inc-dec-in-conditions `_,
+   `bugprone-incorrect-enable-if `_, "Yes"
`bugprone-incorrect-roundings `_,
`bugprone-infinite-loop `_,
`bugprone-integer-division `_,
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
@@ -0,0 +1,48 @@
+.. title:: clang-tidy - bugprone-incorrect-enable-if
+
+bugprone-incorrect-enable-if
+
+
+Detects incorrect usages of ``std::enable_if`` that don't name the nested 
+``type`` type.
+
+In C++11 introduced ``std::enable_if`` as a convenient way to leverage SFINAE.
+One form of using ``std::enable_if`` is to declare an unnamed template type
+parameter with a default type equal to
+``typename std::enable_if::type``. If the author forgets to name
+the nested type ``type``, then the code will always consider the candidate
+template even if the condition is not met.
+
+Below are some examples of code using ``std::enable_if`` correctly and
+incorrect 

[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-06 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst:6
+
+Detects incorrect usages of std::enable_if that don't name the nested 'type'
+type.

Please synchronize with statement in Release Notes after Piotr's comment 
addressed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-06 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added a comment.

Do you have plans to also detect the bugprone scenario described in the `Notes` 
here?

https://en.cppreference.com/w/cpp/types/enable_if

No need to have it in this patch, but would be good to keep it in mind if we 
want to add it in the future (preferably) or create a separate check.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp:67
+  diag(EnableIf->getBeginLoc(), "incorrect std::enable_if usage detected; use "
+"'typename std::enable_if<...>::type'")
+  << TypenameHint << TypeHint;

PiotrZSL wrote:
> since C++14 we should recommend using enable_if_t
I didn't add replacement logic for C++14 or C++20 since there are separate 
tools for those, and though it'd be cleaner to have independent set of tools 
(e.g., first run bugprone-incorrect-enable-if, then run modernize-type-traits).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-06 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL added inline comments.



Comment at: clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp:57
+
+  const SourceManager  = Result.Context->getSourceManager();
+  SourceLocation RAngleLoc =

Result got source manager
https://clang.llvm.org/doxygen/structclang_1_1ast__matchers_1_1MatchFinder_1_1MatchResult.html



Comment at: 
clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp:61-62
+
+  FixItHint TypenameHint =
+  FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(), "typename ");
+  FixItHint TypeHint =

do we still need typename in C++20 in this context ?
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3.html



Comment at: clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp:67
+  diag(EnableIf->getBeginLoc(), "incorrect std::enable_if usage detected; use "
+"'typename std::enable_if<...>::type'")
+  << TypenameHint << TypeHint;

since C++14 we should recommend using enable_if_t



Comment at: clang-tools-extra/docs/ReleaseNotes.rst:129
+
+  Detects incorrect usages of std::enable_if that don't name the nested 'type'
+  type.





Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst:21
+
+  template ::type>
+  void valid_usage() { ... }

shoudnlt be enable_if ?



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst:34
+  template >
+  void invalid_usage() { ... }
+

this is valid usage, uses enable_if_t



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst:37
+  // The tool suggests the following replacement for 'invalid_usage':
+  template ::type>
+  void invalid_usage() { ... }

this may not compile, anyway, what if "type" got "type" ?:P



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst:44
+`modernize-type-traits <../modernize/type-traits.html>`_ for another tool
+that will replace ``typename std::enable_if<...>::type`` with
+``std::enable_if_t<...>``, and see

should be suffucient



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst:47
+`modernize-use-constraints <../modernize/use-constraints.html>`_ for another
+tool that replaces ``std::enable_if`` with C++20 constraints. Use these
+newer mechanisms where possible.

maybe "Consider" 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

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


[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

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

- Edited wrong file


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157239

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy -std=c++11 %s bugprone-incorrect-enable-if %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 ::type>
+void valid_function1() {}
+
+template ::type = nullptr>
+void valid_function2() {}
+
+template ::type = nullptr>
+struct ValidClass1 {};
+
+template >
+void invalid() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+
+template  >
+void invalid_extra_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type >
+
+template >
+void invalid_extra_no_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+
+template /*comment3*/>
+void invalid_extra_comment() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type/*comment3*/>
+
+template , typename = std::enable_if>
+void invalid_multiple() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-MESSAGES: [[@LINE-3]]:65: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type, typename = typename std::enable_if::type>
+
+template >
+struct InvalidClass {};
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
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
@@ -94,6 +94,7 @@
`bugprone-implicit-widening-of-multiplication-result `_, "Yes"
`bugprone-inaccurate-erase `_, "Yes"
`bugprone-inc-dec-in-conditions `_,
+   `bugprone-incorrect-enable-if `_, "Yes"
`bugprone-incorrect-roundings `_,
`bugprone-infinite-loop `_,
`bugprone-integer-division `_,
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
@@ -0,0 +1,48 @@
+.. title:: clang-tidy - bugprone-incorrect-enable-if
+
+bugprone-incorrect-enable-if
+
+
+Detects incorrect usages of std::enable_if that don't name the nested 'type'
+type.
+
+In C++11 introduced ``std::enable_if`` as a convenient way to leverage SFINAE.
+One form of using ``std::enable_if`` is to declare an unnamed template type
+parameter with a default type equal to
+``typename std::enable_if::type``. If the author forgets to name
+the nested type ``type``, then the code will always consider the candidate
+template even if the condition is not met.
+
+Below are some examples of code using ``std::enable_if`` correctly and
+incorrect examples that this check flags.
+
+.. code-block:: c++
+
+  template ::type>
+  void valid_usage() { ... }
+
+  template >
+  void valid_usage_with_trait_helpers() { ... }
+
+  // The below code is not a correct application of SFINAE. Even if
+  // T::some_trait is not true, the function will still be considered in the
+  // set of function candidates. It can either incorrectly select the function
+ 

[PATCH] D157239: [clang-tidy] Implement bugprone-incorrect-enable-if

2023-08-06 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added subscribers: PiotrZSL, 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.

Detects incorrect usages of std::enable_if that don't name the
nested 'type' type.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157239

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.h
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-if.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy -std=c++11 %s bugprone-incorrect-enable-if %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 ::type>
+void valid_function1() {}
+
+template ::type = nullptr>
+void valid_function2() {}
+
+template ::type = nullptr>
+struct ValidClass1 {};
+
+template >
+void invalid() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+
+template  >
+void invalid_extra_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type >
+
+template >
+void invalid_extra_no_whitespace() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
+
+template /*comment3*/>
+void invalid_extra_comment() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type/*comment3*/>
+
+template , typename = std::enable_if>
+void invalid_multiple() {}
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-MESSAGES: [[@LINE-3]]:65: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type, typename = typename std::enable_if::type>
+
+template >
+struct InvalidClass {};
+// CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
+// CHECK-FIXES: template ::type>
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
@@ -94,6 +94,7 @@
`bugprone-implicit-widening-of-multiplication-result `_, "Yes"
`bugprone-inaccurate-erase `_, "Yes"
`bugprone-inc-dec-in-conditions `_,
+   `bugprone-incorrect-enable-if `_, "Yes"
`bugprone-incorrect-roundings `_,
`bugprone-infinite-loop `_,
`bugprone-integer-division `_,
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.rst
@@ -0,0 +1,48 @@
+.. title:: clang-tidy - bugprone-incorrect-enable-if
+
+bugprone-incorrect-enable-if
+
+
+Detects incorrect usages of std::enable_if that don't name the nested 'type'
+type.
+
+In C++11 introduced ``std::enable_if`` as a convenient way to leverage SFINAE.
+One form of using ``std::enable_if`` is to declare an unnamed template type
+parameter with a default type equal to
+``typename std::enable_if::type``. If the author forgets to name
+the nested type ``type``, then the code will always consider the candidate
+template even if the condition is not met.
+
+Below are some examples of code using ``std::enable_if`` correctly and
+incorrect examples that this check flags.
+
+.. code-block:: c++
+
+  template ::type>
+  void valid_usage() { ... }
+
+  template >
+