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

source code of clang-tools-extra/test/clang-tidy/checkers/fuchsia/multiple-inheritance.cpp