151 lines · cpp
1// RUN: %check_clang_tidy %s fuchsia-multiple-inheritance %t2 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 inheritance64class 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 inheritance70class 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 147void test_no_crash() {148 auto foo = []() {};149 WithTemplBase<decltype(foo)>();150}151