// RUN: %check_clang_tidy %s portability-template-virtual-member-function %t namespace UninstantiatedVirtualMember { template struct CrossPlatformError { virtual ~CrossPlatformError() = default; static void used() {} // CHECK-MESSAGES: [[#@LINE+1]]:18: warning: unspecified virtual member function instantiation virtual void unused() { T MSVCError = this; }; }; int main() { // CHECK-MESSAGES: [[#@LINE+1]]:5: note: template instantiated here CrossPlatformError::used(); return 0; } } // namespace UninstantiatedVirtualMember namespace UninstantiatedVirtualMembers { template struct CrossPlatformError { virtual ~CrossPlatformError() = default; static void used() {} // CHECK-MESSAGES: [[#@LINE+2]]:18: warning: unspecified virtual member function instantiation // CHECK-MESSAGES: [[#@LINE+13]]:5: note: template instantiated here virtual void unused() { T MSVCError = this; }; // CHECK-MESSAGES: [[#@LINE+2]]:18: warning: unspecified virtual member function instantiation // CHECK-MESSAGES: [[#@LINE+7]]:5: note: template instantiated here virtual void unused2() { T MSVCError = this; }; }; int main() { CrossPlatformError::used(); return 0; } } // namespace UninstantiatedVirtualMembers namespace UninstantiatedVirtualDestructor { template struct CrossPlatformError { // CHECK-MESSAGES: [[#@LINE+2]]:13: warning: unspecified virtual member function instantiation // CHECK-MESSAGES: [[#@LINE+9]]:5: note: template instantiated here virtual ~CrossPlatformError() { T MSVCError = this; }; static void used() {} }; int main() { CrossPlatformError::used(); return 0; } } // namespace UninstantiatedVirtualDestructor namespace MultipleImplicitInstantiations { template struct CrossPlatformError { virtual ~CrossPlatformError() = default; static void used() {} // CHECK-MESSAGES: [[#@LINE+2]]:18: warning: unspecified virtual member function instantiation // CHECK-MESSAGES: [[#@LINE+7]]:5: note: template instantiated here virtual void unused() { T MSVCError = this; }; }; int main() { CrossPlatformError::used(); CrossPlatformError::used(); CrossPlatformError::used(); return 0; } } // namespace MultipleImplicitInstantiations namespace SomeImplicitInstantiationError { template struct CrossPlatformError { virtual ~CrossPlatformError() = default; static void used() {} // CHECK-MESSAGES: [[#@LINE+2]]:18: warning: unspecified virtual member function instantiation // CHECK-MESSAGES: [[#@LINE+5]]:5: note: template instantiated here virtual void unused(){}; }; int main() { CrossPlatformError::used(); CrossPlatformError NoError; return 0; } } // namespace SomeImplicitInstantiationError namespace InstantiatedVirtualMemberFunctions { template struct NoError { virtual ~NoError() {}; virtual void unused() {}; virtual void unused2() {}; virtual void unused3() {}; }; int main() { NoError Ne; return 0; } } // namespace InstantiatedVirtualMemberFunctions namespace UninstantiatedNonVirtualMemberFunctions { template struct NoError { static void used() {}; void unused() {}; void unused2() {}; void unused3() {}; }; int main() { NoError::used(); return 0; } } // namespace UninstantiatedNonVirtualMemberFunctions namespace PartialSpecializationError { template struct CrossPlatformError {}; template struct CrossPlatformError{ virtual ~CrossPlatformError() = default; static void used() {} // CHECK-MESSAGES: [[#@LINE+2]]:18: warning: unspecified virtual member function instantiation // CHECK-MESSAGES: [[#@LINE+7]]:5: note: template instantiated here virtual void unused() { U MSVCError = this; }; }; int main() { CrossPlatformError::used(); return 0; } } // namespace PartialSpecializationError namespace PartialSpecializationNoInstantiation { template struct NoInstantiation {}; template struct NoInstantiation{ virtual ~NoInstantiation() = default; static void used() {} virtual void unused() { U MSVCError = this; }; }; } // namespace PartialSpecializationNoInstantiation namespace PureVirtual { template struct Base { virtual void foo() = 0; }; struct Derived : public Base { void foo() {} }; void test() { Derived{}.foo(); } }