1 // RUN: %check_clang_tidy -std=c++11 %s bugprone-incorrect-enable-if %t
2 // RUN: %check_clang_tidy -check-suffix=CXX20 -std=c++20 %s bugprone-incorrect-enable-if %t
3
4 // NOLINTBEGIN
5 namespace std {
6 template <bool B, class T = void> struct enable_if { };
7
8 template <class T> struct enable_if<true, T> { typedef T type; };
9
10 template <bool B, class T = void>
11 using enable_if_t = typename enable_if<B, T>::type;
12
13 } // namespace std
14 // NOLINTEND
15
16 template <typename T, typename = typename std::enable_if<T::some_value>::type>
valid_function1()17 void valid_function1() {}
18
19 template <typename T, typename std::enable_if<T::some_value>::type = nullptr>
valid_function2()20 void valid_function2() {}
21
22 template <typename T, typename std::enable_if<T::some_value>::type = nullptr>
23 struct ValidClass1 {};
24
25 template <typename T, typename = std::enable_if<T::some_value>>
invalid()26 void invalid() {}
27 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
28 // CHECK-FIXES: template <typename T, typename = typename std::enable_if<T::some_value>::type>
29 // CHECK-FIXES-CXX20: template <typename T, typename = std::enable_if<T::some_value>::type>
30
31 template <typename T, typename = std::enable_if<T::some_value> >
invalid_extra_whitespace()32 void invalid_extra_whitespace() {}
33 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
34 // CHECK-FIXES: template <typename T, typename = typename std::enable_if<T::some_value>::type >
35 // CHECK-FIXES-CXX20: template <typename T, typename = std::enable_if<T::some_value>::type >
36
37 template <typename T, typename=std::enable_if<T::some_value>>
invalid_extra_no_whitespace()38 void invalid_extra_no_whitespace() {}
39 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
40 // CHECK-FIXES: template <typename T, typename=typename std::enable_if<T::some_value>::type>
41 // CHECK-FIXES-CXX20: template <typename T, typename=std::enable_if<T::some_value>::type>
42
43 template <typename T, typename /*comment1*/ = /*comment2*/std::enable_if<T::some_value>/*comment3*/>
invalid_extra_comment()44 void invalid_extra_comment() {}
45 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
46 // CHECK-FIXES: template <typename T, typename /*comment1*/ = /*comment2*/typename std::enable_if<T::some_value>::type/*comment3*/>
47
48 template <typename T, typename = std::enable_if<T::some_value>, typename = std::enable_if<T::other_value>>
invalid_multiple()49 void invalid_multiple() {}
50 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
51 // CHECK-MESSAGES: [[@LINE-3]]:65: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
52 // CHECK-FIXES: template <typename T, typename = typename std::enable_if<T::some_value>::type, typename = typename std::enable_if<T::other_value>::type>
53 // CHECK-FIXES-CXX20: template <typename T, typename = std::enable_if<T::some_value>::type, typename = std::enable_if<T::other_value>::type>
54
55 template <typename T, typename = std::enable_if<T::some_value>>
56 struct InvalidClass {};
57 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: incorrect std::enable_if usage detected; use 'typename std::enable_if<...>::type' [bugprone-incorrect-enable-if]
58 // CHECK-FIXES: template <typename T, typename = typename std::enable_if<T::some_value>::type>
59 // CHECK-FIXES-CXX20: template <typename T, typename = std::enable_if<T::some_value>::type>
60