|
| 1 | +// RUN: %check_clang_tidy %s misc-multiple-inheritance %t |
| 2 | + |
| 3 | +class Base_A { |
| 4 | +public: |
| 5 | + virtual int foo() { return 0; } |
| 6 | +}; |
| 7 | + |
| 8 | +class Base_B { |
| 9 | +public: |
| 10 | + virtual int bar() { return 0; } |
| 11 | +}; |
| 12 | + |
| 13 | +class Base_A_child : public Base_A { |
| 14 | +public: |
| 15 | + virtual int baz() { return 0; } |
| 16 | +}; |
| 17 | + |
| 18 | +class Interface_A { |
| 19 | +public: |
| 20 | + virtual int foo() = 0; |
| 21 | +}; |
| 22 | + |
| 23 | +class Interface_B { |
| 24 | +public: |
| 25 | + virtual int bar() = 0; |
| 26 | +}; |
| 27 | + |
| 28 | +class Interface_C { |
| 29 | +public: |
| 30 | + virtual int blat() = 0; |
| 31 | +}; |
| 32 | + |
| 33 | +class Interface_A_with_member { |
| 34 | +public: |
| 35 | + virtual int foo() = 0; |
| 36 | + int val = 0; |
| 37 | +}; |
| 38 | + |
| 39 | +class Interface_with_A_Parent : public Base_A { |
| 40 | +public: |
| 41 | + virtual int baz() = 0; |
| 42 | +}; |
| 43 | + |
| 44 | +// Shouldn't warn on forward declarations. |
| 45 | +class Bad_Child1; |
| 46 | + |
| 47 | +// Inherits from multiple concrete classes. |
| 48 | +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 49 | +// CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {}; |
| 50 | +class Bad_Child1 : public Base_A, Base_B {}; |
| 51 | + |
| 52 | +// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 53 | +class Bad_Child2 : public Base_A, Interface_A_with_member { |
| 54 | + virtual int foo() override { return 0; } |
| 55 | +}; |
| 56 | + |
| 57 | +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 58 | +// CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B { |
| 59 | +class Bad_Child3 : public Interface_with_A_Parent, Base_B { |
| 60 | + virtual int baz() override { return 0; } |
| 61 | +}; |
| 62 | + |
| 63 | +// Easy cases of single inheritance |
| 64 | +class Simple_Child1 : public Base_A {}; |
| 65 | +class Simple_Child2 : public Interface_A { |
| 66 | + virtual int foo() override { return 0; } |
| 67 | +}; |
| 68 | + |
| 69 | +// Valid uses of multiple inheritance |
| 70 | +class Good_Child1 : public Interface_A, Interface_B { |
| 71 | + virtual int foo() override { return 0; } |
| 72 | + virtual int bar() override { return 0; } |
| 73 | +}; |
| 74 | + |
| 75 | +class Good_Child2 : public Base_A, Interface_B { |
| 76 | + virtual int bar() override { return 0; } |
| 77 | +}; |
| 78 | + |
| 79 | +class Good_Child3 : public Base_A_child, Interface_C, Interface_B { |
| 80 | + virtual int bar() override { return 0; } |
| 81 | + virtual int blat() override { return 0; } |
| 82 | +}; |
| 83 | + |
| 84 | +struct B1 { int x; }; |
| 85 | +struct B2 { int x;}; |
| 86 | +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 87 | +// CHECK-NEXT: struct D : B1, B2 {}; |
| 88 | +struct D1 : B1, B2 {}; |
| 89 | + |
| 90 | +struct Base1 { virtual void foo() = 0; }; |
| 91 | +struct V1 : virtual Base1 {}; |
| 92 | +struct V2 : virtual Base1 {}; |
| 93 | +struct D2 : V1, V2 {}; |
| 94 | + |
| 95 | +struct Base2 { virtual void foo(); }; |
| 96 | +struct V3 : virtual Base2 {}; |
| 97 | +struct V4 : virtual Base2 {}; |
| 98 | +struct D3 : V3, V4 {}; |
| 99 | + |
| 100 | +struct Base3 {}; |
| 101 | +struct V5 : virtual Base3 { virtual void f(); }; |
| 102 | +struct V6 : virtual Base3 { virtual void g(); }; |
| 103 | +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 104 | +// CHECK-NEXT: struct D4 : V5, V6 {}; |
| 105 | +struct D4 : V5, V6 {}; |
| 106 | + |
| 107 | +struct Base4 {}; |
| 108 | +struct V7 : virtual Base4 { virtual void f() = 0; }; |
| 109 | +struct V8 : virtual Base4 { virtual void g() = 0; }; |
| 110 | +struct D5 : V7, V8 {}; |
| 111 | + |
| 112 | +struct Base5 { virtual void f() = 0; }; |
| 113 | +struct V9 : virtual Base5 { virtual void f(); }; |
| 114 | +struct V10 : virtual Base5 { virtual void g() = 0; }; |
| 115 | +struct D6 : V9, V10 {}; |
| 116 | + |
| 117 | +struct Base6 { virtual void f(); }; |
| 118 | +struct Base7 { virtual void g(); }; |
| 119 | +struct V15 : virtual Base6 { virtual void f() = 0; }; |
| 120 | +struct V16 : virtual Base7 { virtual void g() = 0; }; |
| 121 | +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 122 | +// CHECK-NEXT: struct D9 : V15, V16 {}; |
| 123 | +struct D9 : V15, V16 {}; |
| 124 | + |
| 125 | +struct Static_Base { static void foo(); }; |
| 126 | +struct V11 : virtual Static_Base {}; |
| 127 | +struct V12 : virtual Static_Base {}; |
| 128 | +struct D7 : V11, V12 {}; |
| 129 | + |
| 130 | +struct Static_Base_2 {}; |
| 131 | +struct V13 : virtual Static_Base_2 { static void f(); }; |
| 132 | +struct V14 : virtual Static_Base_2 { static void g(); }; |
| 133 | +struct D8 : V13, V14 {}; |
| 134 | + |
| 135 | +template<typename T> struct A : T {}; |
| 136 | +template<typename T> struct B : virtual T {}; |
| 137 | + |
| 138 | +template<typename> struct C {}; |
| 139 | +template<typename T> struct D : C<T> {}; |
| 140 | + |
| 141 | +// Check clang_tidy does not crash on this code. |
| 142 | +template <class T> |
| 143 | +struct WithTemplBase : T { |
| 144 | + WithTemplBase(); |
| 145 | +}; |
| 146 | + |
| 147 | +void test_no_crash() { |
| 148 | + auto foo = []() {}; |
| 149 | + WithTemplBase<decltype(foo)>(); |
| 150 | +} |
| 151 | + |
| 152 | +struct S1 {}; |
| 153 | +struct S2 {}; |
| 154 | + |
| 155 | +struct S3 : S1, S2 {}; |
| 156 | + |
| 157 | +namespace N { |
| 158 | + |
| 159 | +struct S1 { int i; }; |
| 160 | +struct S2 { int i; }; |
| 161 | + |
| 162 | +// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance] |
| 163 | +struct S3 : S1, S2 {}; |
| 164 | + |
| 165 | +} // namespace N |
0 commit comments