1 // RUN: %check_clang_tidy %s misc-definitions-in-headers %t -- --fix-notes 2 3 int f() { 4 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f' defined in a header file; function definitions in header files can lead to ODR violations [misc-definitions-in-headers] 5 // CHECK-MESSAGES: :[[@LINE-2]]:5: note: mark the definition as 'inline' 6 // CHECK-FIXES: inline int f() { 7 return 1; 8 } 9 10 class CA { 11 void f1() {} // OK: inline class member function definition. 12 void f2(); 13 template<typename T> 14 T f3() { 15 T a = 1; 16 return a; 17 } 18 template<typename T> 19 struct CAA { 20 struct CAB { 21 void f4(); 22 }; 23 }; 24 }; 25 26 void CA::f2() { } 27 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file; 28 // CHECK-FIXES: inline void CA::f2() { 29 30 template <> 31 int CA::f3() { 32 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: full function template specialization 'f3<int>' defined in a header file; 33 // CHECK-FIXES: inline int CA::f3() { 34 int a = 1; 35 return a; 36 } 37 38 template <typename T> 39 void CA::CAA<T>::CAB::f4() { 40 // OK: member function definition of a nested template class in a class. 41 } 42 43 template <typename T> 44 struct CB { 45 void f1(); 46 struct CCA { 47 void f2(T a); 48 }; 49 struct CCB; // OK: forward declaration. 50 static int a; // OK: class static data member declaration. 51 }; 52 53 template <typename T> 54 void CB<T>::f1() { // OK: Member function definition of a class template. 55 } 56 57 template <typename T> 58 void CB<T>::CCA::f2(T a) { 59 // OK: member function definition of a nested class in a class template. 60 } 61 62 template <typename T> 63 struct CB<T>::CCB { 64 void f3(); 65 }; 66 67 template <typename T> 68 void CB<T>::CCB::f3() { 69 // OK: member function definition of a nested class in a class template. 70 } 71 72 template <typename T> 73 int CB<T>::a = 2; // OK: static data member definition of a class template. 74 75 template class CB<int>; // OK: explicitly instantiated static data member of a class template. 76 inline int callCB() { 77 CB<double> cb; // OK: implicitly instantiated static data member of a class template. 78 return cb.a; 79 } 80 81 template <typename T> 82 T tf() { // OK: template function definition. 83 T a; 84 return a; 85 } 86 87 88 namespace NA { 89 int f() { return 1; } 90 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f' defined in a header file; 91 // CHECK-FIXES: inline int f() { return 1; } 92 } 93 94 template <typename T> 95 T f3() { 96 T a = 1; 97 return a; 98 } 99 100 template <> 101 int f3() { 102 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full function template specialization 'f3<int>' defined in a header file; 103 // CHECK-FIXES: inline int f3() { 104 int a = 1; 105 return a; 106 } 107 108 int f5(); // OK: function declaration. 109 inline int f6() { return 1; } // OK: inline function definition. 110 namespace { 111 int f7() { return 1; } // OK: each TU defines the function in a unique namespace. 112 } 113 114 int f8() = delete; // OK: the function being marked delete is not callable. 115 116 template <typename T> 117 int f9(T t) { return 1; } 118 119 inline void callF9() { f9(1); } // OK: implicitly instantiated function. 120 template int f9(double); // OK: explicitly instantiated function. 121 122 int a = 1; 123 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'a' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers] 124 CA a1; 125 // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: variable 'a1' defined in a header file; 126 127 namespace NB { 128 int b = 1; 129 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'b' defined in a header file; 130 const int c = 1; // OK: internal linkage variable definition. 131 } 132 133 class CC { 134 static int d; // OK: class static data member declaration. 135 }; 136 137 int CC::d = 1; 138 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: variable 'd' defined in a header file; 139 140 const char* ca = "foo"; 141 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'ca' defined in a header file; 142 143 namespace { 144 int e = 2; // OK: each TU defines the variable in a unique namespace. 145 } 146 147 const char* const g = "foo"; // OK: internal linkage variable definition. 148 static int h = 1; // OK: internal linkage variable definition. 149 const int i = 1; // OK: internal linkage variable definition. 150 extern int j; // OK: internal linkage variable definition. 151 152 template <typename T, typename U> 153 struct CD { 154 int f(); 155 }; 156 157 template <typename T> 158 struct CD<T, int> { 159 int f(); 160 }; 161 162 template <> 163 struct CD<int, int> { 164 int f(); 165 }; 166 167 int CD<int, int>::f() { 168 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: function 'f' defined in a header file; 169 // CHECK-FIXES: inline int CD<int, int>::f() { 170 return 0; 171 } 172 173 template <typename T> 174 int CD<T, int>::f() { // OK: partial template specialization. 175 return 0; 176 } 177 178 constexpr int k = 1; // OK: constexpr variable has internal linkage. 179 180 constexpr int f10() { return 0; } // OK: constexpr function definition. 181 182 const int f11() { return 0; } 183 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'f11' defined in a header file; 184 // CHECK-FIXES: inline const int f11() { return 0; } 185 186 template <typename T> 187 const T f12(); 188 189 template <> 190 const int f12() { return 0; } 191 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: full function template specialization 'f12<int>' defined in a header file; 192 // CHECK-FIXES: inline const int f12() { return 0; } 193 194 template <typename T1, typename T2> 195 constexpr bool f13 = false; 196 197 template <typename T> 198 constexpr bool f13<T, int> = true; // OK: template partial specialization 199 200 template <> 201 constexpr bool f13<void, int> = false; 202 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: variable 'f13<void, int>' defined in a header file; 203 204 int main() {} 205 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'main' defined in a header file; 206 // CHECK-FIXES: {{^}}int main() { 207