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