1 // RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: [{key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions, value: true}, {key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor, value: true}]}" --
2 
3 class DefinesDestructor {
4   ~DefinesDestructor();
5 };
6 // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
7 
8 class DefinesDefaultedDestructor {
9   ~DefinesDefaultedDestructor() = default;
10 };
11 
12 class DefinesCopyConstructor {
13   DefinesCopyConstructor(const DefinesCopyConstructor &);
14 };
15 // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
16 
17 class DefinesCopyAssignment {
18   DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
19 };
20 // CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor or a copy constructor [cppcoreguidelines-special-member-functions]
21 
22 class DefinesMoveConstructor {
23   DefinesMoveConstructor(DefinesMoveConstructor &&);
24 };
25 // 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]
26 
27 class DefinesMoveAssignment {
28   DefinesMoveAssignment &operator=(DefinesMoveAssignment &&);
29 };
30 // 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]
31 class DefinesNothing {
32 };
33 
34 class DefinesEverything {
35   DefinesEverything(const DefinesEverything &);
36   DefinesEverything &operator=(const DefinesEverything &);
37   DefinesEverything(DefinesEverything &&);
38   DefinesEverything &operator=(DefinesEverything &&);
39   ~DefinesEverything();
40 };
41 
42 class DeletesEverything {
43   DeletesEverything(const DeletesEverything &) = delete;
44   DeletesEverything &operator=(const DeletesEverything &) = delete;
45   DeletesEverything(DeletesEverything &&) = delete;
46   DeletesEverything &operator=(DeletesEverything &&) = delete;
47   ~DeletesEverything() = delete;
48 };
49 
50 class DeletesCopyDefaultsMove {
51   DeletesCopyDefaultsMove(const DeletesCopyDefaultsMove &) = delete;
52   DeletesCopyDefaultsMove &operator=(const DeletesCopyDefaultsMove &) = delete;
53   DeletesCopyDefaultsMove(DeletesCopyDefaultsMove &&) = default;
54   DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default;
55   ~DeletesCopyDefaultsMove() = default;
56 };
57 
58 template <typename T>
59 struct TemplateClass {
60   TemplateClass() = default;
61   TemplateClass(const TemplateClass &);
62   TemplateClass &operator=(const TemplateClass &);
63   TemplateClass(TemplateClass &&);
64   TemplateClass &operator=(TemplateClass &&);
65   ~TemplateClass();
66 };
67 
68 // Multiple instantiations of a class template will trigger multiple matches for defined special members.
69 // This should not cause problems.
70 TemplateClass<int> InstantiationWithInt;
71 TemplateClass<double> InstantiationWithDouble;
72