1 // RUN: %check_clang_tidy %s cppcoreguidelines-slicing %t
2
3 class Base {
4 int i;
f()5 void f() {}
g()6 virtual void g() {}
7 };
8
9 class DerivedWithMemberVariables : public Base {
10 void f();
11 int j;
12 };
13
14 class TwiceDerivedWithNoMemberVariables : public DerivedWithMemberVariables {
15 void f();
16 };
17
18 class DerivedWithOverride : public Base {
19 void f();
g()20 void g() override {}
21 };
22
23 class TwiceDerivedWithNoOverride : public DerivedWithOverride {
24 void f();
25 };
26
27 void TakesBaseByValue(Base base);
28
29 DerivedWithMemberVariables ReturnsDerived();
30
positivesWithMemberVariables()31 void positivesWithMemberVariables() {
32 DerivedWithMemberVariables b;
33 Base a{b};
34 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state [cppcoreguidelines-slicing]
35 a = b;
36 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
37 TakesBaseByValue(b);
38 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
39
40 TwiceDerivedWithNoMemberVariables c;
41 a = c;
42 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'TwiceDerivedWithNoMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
43
44 a = ReturnsDerived();
45 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
46 }
47
positivesWithOverride()48 void positivesWithOverride() {
49 DerivedWithOverride b;
50 Base a{b};
51 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
52 a = b;
53 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
54 TakesBaseByValue(b);
55 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
56
57 TwiceDerivedWithNoOverride c;
58 a = c;
59 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
60 }
61
62 void TakesBaseByReference(Base &base);
63
64 class DerivedThatAddsVirtualH : public Base {
65 virtual void h();
66 };
67
68 class DerivedThatOverridesH : public DerivedThatAddsVirtualH {
69 void h() override;
70 };
71
negatives()72 void negatives() {
73 // OK, simple copying from the same type.
74 Base a;
75 TakesBaseByValue(a);
76 DerivedWithMemberVariables b;
77 DerivedWithMemberVariables c{b};
78 b = c;
79
80 // OK, derived type does not have extra state.
81 TwiceDerivedWithNoMemberVariables d;
82 DerivedWithMemberVariables e{d};
83 e = d;
84
85 // OK, derived does not override any method.
86 TwiceDerivedWithNoOverride f;
87 DerivedWithOverride g{f};
88 g = f;
89
90 // OK, no copying.
91 TakesBaseByReference(d);
92 TakesBaseByReference(f);
93
94 // Derived type overrides methods, but these methods are not in the base type,
95 // so cannot be called accidentally. Right now this triggers, but we might
96 // want to allow it.
97 DerivedThatOverridesH h;
98 a = h;
99 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
100 }
101
102 namespace PR31187 {
103 // Don't warn when calling constructor of base virtual class, from
104 // initialization list of derived class constructor.
105
106 struct BaseA {
~BaseAPR31187::BaseA107 virtual ~BaseA() {}
fooPR31187::BaseA108 virtual void foo() {}
109
110 int i;
111 };
112
113 struct BaseB : virtual BaseA {
fooPR31187::BaseB114 virtual void foo() {}
115 };
116
117 struct ClassWithVirtualBases : BaseB {
ClassWithVirtualBasesPR31187::ClassWithVirtualBases118 ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
ClassWithVirtualBasesPR31187::ClassWithVirtualBases119 ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), BaseB(other) {}
120 };
121
122 }
123