File tree Expand file tree Collapse file tree 3 files changed +45
-1
lines changed Expand file tree Collapse file tree 3 files changed +45
-1
lines changed Original file line number Diff line number Diff line change 8
8
9
9
#include " UseConstraintsCheck.h"
10
10
#include " clang/AST/ASTContext.h"
11
+ #include " clang/AST/DeclTemplate.h"
11
12
#include " clang/ASTMatchers/ASTMatchFinder.h"
12
13
#include " clang/Lex/Lexer.h"
13
14
@@ -78,6 +79,15 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) {
78
79
if (!TD || TD->getName () != " enable_if" )
79
80
return std::nullopt;
80
81
82
+ const TemplateParameterList *Params = TD->getTemplateParameters ();
83
+ if (Params->size () != 2 )
84
+ return std::nullopt;
85
+
86
+ const auto *FirstParam =
87
+ dyn_cast<NonTypeTemplateParmDecl>(Params->getParam (0 ));
88
+ if (!FirstParam || !FirstParam->getType ()->isBooleanType ())
89
+ return std::nullopt;
90
+
81
91
int NumArgs = SpecializationLoc.getNumArgs ();
82
92
if (NumArgs != 1 && NumArgs != 2 )
83
93
return std::nullopt;
Original file line number Diff line number Diff line change @@ -136,6 +136,11 @@ Changes in existing checks
136
136
- Improved :doc: `misc-header-include-cycle
137
137
<clang-tidy/checks/misc/header-include-cycle>` check performance.
138
138
139
+ - Fixed a :doc: `modernize-use-constraints
140
+ <clang-tidy/checks/modernize/use-constraints>` crash on uses of
141
+ nonstandard ``enable_if``s with a signature different from
142
+ ``std::enable_if `` (such as ``boost::enable_if ``).
143
+
139
144
- Improved :doc: `modernize-use-designated-initializers
140
145
<clang-tidy/checks/modernize/use-designated-initializers>` check to
141
146
suggest using designated initializers for aliased aggregate types.
Original file line number Diff line number Diff line change 1
- // RUN: %check_clang_tidy -std=c++20 %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
1
+ // RUN: %check_clang_tidy -std=c++20-or-later %s modernize-use-constraints %t -- -- -fno-delayed-template-parsing
2
2
3
3
// NOLINTBEGIN
4
4
namespace std {
@@ -756,3 +756,32 @@ abs(const number<T, ExpressionTemplates> &v) {
756
756
}
757
757
758
758
}
759
+
760
+ template <typename T>
761
+ struct some_type_trait {
762
+ static constexpr bool value = true ;
763
+ };
764
+
765
+ // Fix-its are offered even for a nonstandard enable_if.
766
+ namespace nonstd {
767
+
768
+ template <bool Condition, typename T = void >
769
+ struct enable_if : std::enable_if<Condition, T> {};
770
+
771
+ }
772
+
773
+ template <typename T>
774
+ typename nonstd::enable_if<some_type_trait<T>::value, void >::type nonstd_enable_if () {}
775
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
776
+ // CHECK-FIXES: {{^}}void nonstd_enable_if() requires some_type_trait<T>::value {}{{$}}
777
+
778
+ // But only if the nonstandard enable_if has the same signature as the standard one.
779
+ namespace boost {
780
+
781
+ template <typename Condition, typename T = void >
782
+ struct enable_if : std::enable_if<Condition::value, T> {};
783
+
784
+ }
785
+
786
+ template <typename T>
787
+ typename boost::enable_if<some_type_trait<T>, void >::type boost_enable_if () {}
You can’t perform that action at this time.
0 commit comments