189a1d03eSRichard // RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t 289a1d03eSRichard 389a1d03eSRichard class DefinesDestructor { 489a1d03eSRichard ~DefinesDestructor(); 589a1d03eSRichard }; 6*aa56e66bSRoy Jacobson // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] 789a1d03eSRichard 889a1d03eSRichard class DefinesDefaultedDestructor { 989a1d03eSRichard ~DefinesDefaultedDestructor() = default; 1089a1d03eSRichard }; 1189a1d03eSRichard // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] 1289a1d03eSRichard 1389a1d03eSRichard class DefinesCopyConstructor { 1489a1d03eSRichard DefinesCopyConstructor(const DefinesCopyConstructor &); 1589a1d03eSRichard }; 1689a1d03eSRichard // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] 1789a1d03eSRichard 1889a1d03eSRichard class DefinesCopyAssignment { 1989a1d03eSRichard DefinesCopyAssignment &operator=(const DefinesCopyAssignment &); 2089a1d03eSRichard }; 2189a1d03eSRichard // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor, a copy constructor, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] 2289a1d03eSRichard 2389a1d03eSRichard class DefinesMoveConstructor { 2489a1d03eSRichard DefinesMoveConstructor(DefinesMoveConstructor &&); 2589a1d03eSRichard }; 2689a1d03eSRichard // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveConstructor' defines a move constructor but does not define a destructor, a copy constructor, a copy assignment operator or a move assignment operator [cppcoreguidelines-special-member-functions] 2789a1d03eSRichard 2889a1d03eSRichard class DefinesMoveAssignment { 2989a1d03eSRichard DefinesMoveAssignment &operator=(DefinesMoveAssignment &&); 3089a1d03eSRichard }; 3189a1d03eSRichard // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveAssignment' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor [cppcoreguidelines-special-member-functions] 3289a1d03eSRichard class DefinesNothing { 3389a1d03eSRichard }; 3489a1d03eSRichard 3589a1d03eSRichard class DefinesEverything { 3689a1d03eSRichard DefinesEverything(const DefinesEverything &); 3789a1d03eSRichard DefinesEverything &operator=(const DefinesEverything &); 3889a1d03eSRichard DefinesEverything(DefinesEverything &&); 3989a1d03eSRichard DefinesEverything &operator=(DefinesEverything &&); 4089a1d03eSRichard ~DefinesEverything(); 4189a1d03eSRichard }; 4289a1d03eSRichard 4389a1d03eSRichard class DeletesEverything { 4489a1d03eSRichard DeletesEverything(const DeletesEverything &) = delete; 4589a1d03eSRichard DeletesEverything &operator=(const DeletesEverything &) = delete; 4689a1d03eSRichard DeletesEverything(DeletesEverything &&) = delete; 4789a1d03eSRichard DeletesEverything &operator=(DeletesEverything &&) = delete; 4889a1d03eSRichard ~DeletesEverything() = delete; 4989a1d03eSRichard }; 5089a1d03eSRichard 5189a1d03eSRichard class DeletesCopyDefaultsMove { 5289a1d03eSRichard DeletesCopyDefaultsMove(const DeletesCopyDefaultsMove &) = delete; 5389a1d03eSRichard DeletesCopyDefaultsMove &operator=(const DeletesCopyDefaultsMove &) = delete; 5489a1d03eSRichard DeletesCopyDefaultsMove(DeletesCopyDefaultsMove &&) = default; 5589a1d03eSRichard DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default; 5689a1d03eSRichard ~DeletesCopyDefaultsMove() = default; 5789a1d03eSRichard }; 5889a1d03eSRichard 5989a1d03eSRichard template <typename T> 6089a1d03eSRichard struct TemplateClass { 6189a1d03eSRichard TemplateClass() = default; 6289a1d03eSRichard TemplateClass(const TemplateClass &); 6389a1d03eSRichard TemplateClass &operator=(const TemplateClass &); 6489a1d03eSRichard TemplateClass(TemplateClass &&); 6589a1d03eSRichard TemplateClass &operator=(TemplateClass &&); 6689a1d03eSRichard ~TemplateClass(); 6789a1d03eSRichard }; 6889a1d03eSRichard 6989a1d03eSRichard // Multiple instantiations of a class template will trigger multiple matches for defined special members. 7089a1d03eSRichard // This should not cause problems. 7189a1d03eSRichard TemplateClass<int> InstantiationWithInt; 7289a1d03eSRichard TemplateClass<double> InstantiationWithDouble; 73