forked from OSchip/llvm-project
182 lines
4.5 KiB
C++
182 lines
4.5 KiB
C++
// RUN: %check_clang_tidy %s misc-definitions-in-headers %t
|
|
|
|
int f() {
|
|
// 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]
|
|
// CHECK-FIXES: inline int f() {
|
|
return 1;
|
|
}
|
|
|
|
class CA {
|
|
void f1() {} // OK: inline class member function definition.
|
|
void f2();
|
|
template<typename T>
|
|
T f3() {
|
|
T a = 1;
|
|
return a;
|
|
}
|
|
template<typename T>
|
|
struct CAA {
|
|
struct CAB {
|
|
void f4();
|
|
};
|
|
};
|
|
};
|
|
|
|
void CA::f2() { }
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file;
|
|
// CHECK-FIXES: inline void CA::f2() {
|
|
|
|
template <>
|
|
int CA::f3() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: full function template specialization 'f3<int>' defined in a header file;
|
|
// CHECK-FIXES: inline int CA::f3() {
|
|
int a = 1;
|
|
return a;
|
|
}
|
|
|
|
template <typename T>
|
|
void CA::CAA<T>::CAB::f4() {
|
|
// OK: member function definition of a nested template class in a class.
|
|
}
|
|
|
|
template <typename T>
|
|
struct CB {
|
|
void f1();
|
|
struct CCA {
|
|
void f2(T a);
|
|
};
|
|
struct CCB; // OK: forward declaration.
|
|
static int a; // OK: class static data member declaration.
|
|
};
|
|
|
|
template <typename T>
|
|
void CB<T>::f1() { // OK: Member function definition of a class template.
|
|
}
|
|
|
|
template <typename T>
|
|
void CB<T>::CCA::f2(T a) {
|
|
// OK: member function definition of a nested class in a class template.
|
|
}
|
|
|
|
template <typename T>
|
|
struct CB<T>::CCB {
|
|
void f3();
|
|
};
|
|
|
|
template <typename T>
|
|
void CB<T>::CCB::f3() {
|
|
// OK: member function definition of a nested class in a class template.
|
|
}
|
|
|
|
template <typename T>
|
|
int CB<T>::a = 2; // OK: static data member definition of a class template.
|
|
|
|
template class CB<int>; // OK: explicitly instantiated static data member of a class template.
|
|
inline int callCB() {
|
|
CB<double> cb; // OK: implicitly instantiated static data member of a class template.
|
|
return cb.a;
|
|
}
|
|
|
|
template <typename T>
|
|
T tf() { // OK: template function definition.
|
|
T a;
|
|
return a;
|
|
}
|
|
|
|
|
|
namespace NA {
|
|
int f() { return 1; }
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f' defined in a header file;
|
|
// CHECK-FIXES: inline int f() { return 1; }
|
|
}
|
|
|
|
template <typename T>
|
|
T f3() {
|
|
T a = 1;
|
|
return a;
|
|
}
|
|
|
|
template <>
|
|
int f3() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full function template specialization 'f3<int>' defined in a header file;
|
|
// CHECK-FIXES: inline int f3() {
|
|
int a = 1;
|
|
return a;
|
|
}
|
|
|
|
int f5(); // OK: function declaration.
|
|
inline int f6() { return 1; } // OK: inline function definition.
|
|
namespace {
|
|
int f7() { return 1; }
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f7' defined in a header file;
|
|
}
|
|
|
|
int f8() = delete; // OK: the function being marked delete is not callable.
|
|
|
|
template <typename T>
|
|
int f9(T t) { return 1; }
|
|
|
|
inline void callF9() { f9(1); } // OK: implicitly instantiated function.
|
|
template int f9(double); // OK: explicitly instantiated function.
|
|
|
|
int a = 1;
|
|
// 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]
|
|
CA a1;
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:4: warning: variable 'a1' defined in a header file;
|
|
|
|
namespace NB {
|
|
int b = 1;
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'b' defined in a header file;
|
|
const int c = 1; // OK: internal linkage variable definition.
|
|
}
|
|
|
|
class CC {
|
|
static int d; // OK: class static data member declaration.
|
|
};
|
|
|
|
int CC::d = 1;
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: variable 'd' defined in a header file;
|
|
|
|
const char* ca = "foo";
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'ca' defined in a header file;
|
|
|
|
namespace {
|
|
int e = 2;
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'e' defined in a header file;
|
|
}
|
|
|
|
const char* const g = "foo"; // OK: internal linkage variable definition.
|
|
static int h = 1; // OK: internal linkage variable definition.
|
|
const int i = 1; // OK: internal linkage variable definition.
|
|
extern int j; // OK: internal linkage variable definition.
|
|
|
|
template <typename T, typename U>
|
|
struct CD {
|
|
int f();
|
|
};
|
|
|
|
template <typename T>
|
|
struct CD<T, int> {
|
|
int f();
|
|
};
|
|
|
|
template <>
|
|
struct CD<int, int> {
|
|
int f();
|
|
};
|
|
|
|
int CD<int, int>::f() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: function 'f' defined in a header file;
|
|
// CHECK-FIXES: inline int CD<int, int>::f() {
|
|
return 0;
|
|
}
|
|
|
|
template <typename T>
|
|
int CD<T, int>::f() { // OK: partial template specialization.
|
|
return 0;
|
|
}
|
|
|
|
constexpr int k = 1; // OK: constexpr variable has internal linkage.
|
|
|
|
constexpr int f10() { return 0; } // OK: constexpr function definition.
|