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