1 // RUN: %check_clang_tidy -std=c++17 %s readability-redundant-inline-specifier %t
2 // RUN: %check_clang_tidy -std=c++17 -check-suffixes=,STRICT %s readability-redundant-inline-specifier %t -- -config="{CheckOptions: {readability-redundant-inline-specifier.StrictMode: 'true'}}"
3 
f()4 template <typename T> inline T f()
5 // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:23: warning: function 'f' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
6 // CHECK-FIXES-STRICT: template <typename T> T f()
7 {
8     return T{};
9 }
10 
11 template <> inline double f<double>() = delete;
12 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: function 'f<double>' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
13 // CHECK-FIXES: template <> double f<double>() = delete;
14 
g(float a)15 inline int g(float a)
16 {
17     return static_cast<int>(a - 5.F);
18 }
19 
20 inline int g(double) = delete;
21 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: function 'g' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
22 // CHECK-FIXES: int g(double) = delete;
23 
24 class C
25 {
26   public:
27     inline C& operator=(const C&) = delete;
28     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'operator=' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
29     // CHECK-FIXES: C& operator=(const C&) = delete;
30 
31     inline C(const C&) = default;
32     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'C' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
33     // CHECK-FIXES: C(const C&) = default;
34 
35     constexpr inline C& operator=(int a);
36     // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: function 'operator=' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
37     // CHECK-FIXES: constexpr C& operator=(int a);
38 
C()39     inline C() {}
40     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'C' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
41     // CHECK-FIXES: C() {}
42 
43     constexpr inline C(int);
44     // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: function 'C' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
45     // CHECK-FIXES: constexpr C(int);
46 
Get42() const47     inline int Get42() const { return 42; }
48     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'Get42' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
49     // CHECK-FIXES: int Get42() const { return 42; }
50 
51     static inline constexpr int C_STATIC = 42;
52     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'C_STATIC' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
53     // CHECK-FIXES: static constexpr int C_STATIC = 42;
54 
55     static constexpr int C_STATIC_2 = 42;
56 };
57 
Get42()58 constexpr inline int Get42() { return 42; }
59 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'Get42' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
60 // CHECK-FIXES: constexpr int Get42() { return 42; }
61 
62 
63 static constexpr inline int NAMESPACE_STATIC = 42;
64 
fn0(int i)65 inline static int fn0(int i)
66 // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:1: warning: function 'fn0' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
67 // CHECK-FIXES-STRICT: static int fn0(int i)
68 {
69     return i - 1;
70 }
71 
fn1(int i)72 static constexpr inline int fn1(int i)
73 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: function 'fn1' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
74 // CHECK-FIXES: static constexpr int fn1(int i)
75 {
76     return i - 1;
77 }
78 
79 namespace
80 {
fn2(int i)81     inline int fn2(int i)
82     // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:5: warning: function 'fn2' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
83     // CHECK-FIXES-STRICT: int fn2(int i)
84     {
85         return i - 1;
86     }
87 
fn3(int i)88     inline constexpr int fn3(int i)
89     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'fn3' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
90     // CHECK-FIXES: constexpr int fn3(int i)
91     {
92         return i - 1;
93     }
94 
95     inline constexpr int MY_CONSTEXPR_VAR = 42;
96     // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:5: warning: variable 'MY_CONSTEXPR_VAR' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
97     // CHECK-FIXES-STRICT: constexpr int MY_CONSTEXPR_VAR = 42;
98 }
99 
100 namespace ns
101 {
fn4(int i)102     inline int fn4(int i)
103     {
104         return i - 1;
105     }
106 
fn5(int i)107     inline constexpr int fn5(int i)
108     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'fn5' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
109     // CHECK-FIXES: constexpr int fn5(int i)
110     {
111         return i - 1;
112     }
113 }
114 
__anon97d869680202()115 auto fn6 = [](){};
116 
117 template <typename T> inline T fn7();
118 
fn7()119 template <typename T> T fn7()
120 {
121     return T{};
122 }
123 
124 template <typename T>  T fn8();
125 
fn8()126 template <typename T> inline T fn8()
127 // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:23: warning: function 'fn8' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
128 // CHECK-FIXES-STRICT: template <typename T> T fn8()
129 {
130     return T{};
131 }
132 
133 #define INLINE_MACRO() inline void fn9() { }
INLINE_MACRO()134 INLINE_MACRO()
135 
136 #define INLINE_KW inline
137 INLINE_KW void fn10() { }
138 
139 namespace {
140 class A
141 {
142 public:
143   static inline float test = 3.0F;
144   static inline double test2 = 3.0;
145   static inline int test3 = 3;
146 
147   static inline float test4;
148   // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:10: warning: variable 'test4' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier]
149   // CHECK-FIXES-STRICT: static float test4;
150 };
151 }
152