123 lines · cpp
1// RUN: %check_clang_tidy %s cppcoreguidelines-slicing %t2 3class Base {4 int i;5 void f() {}6 virtual void g() {}7};8 9class DerivedWithMemberVariables : public Base {10 void f();11 int j;12};13 14class TwiceDerivedWithNoMemberVariables : public DerivedWithMemberVariables {15 void f();16};17 18class DerivedWithOverride : public Base {19 void f();20 void g() override {}21};22 23class TwiceDerivedWithNoOverride : public DerivedWithOverride {24 void f();25};26 27void TakesBaseByValue(Base base);28 29DerivedWithMemberVariables ReturnsDerived();30 31void 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 state37 TakesBaseByValue(b);38 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state39 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 state43 44 a = ReturnsDerived();45 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state46}47 48void 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 62void TakesBaseByReference(Base &base);63 64class DerivedThatAddsVirtualH : public Base {65 virtual void h();66};67 68class DerivedThatOverridesH : public DerivedThatAddsVirtualH {69 void h() override;70};71 72void 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 might96 // 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 102namespace PR31187 {103// Don't warn when calling constructor of base virtual class, from104// initialization list of derived class constructor.105 106struct BaseA {107virtual ~BaseA() {}108virtual void foo() {}109 110int i;111};112 113struct BaseB : virtual BaseA {114virtual void foo() {}115};116 117struct ClassWithVirtualBases : BaseB {118 ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}119 ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), BaseB(other) {}120};121 122}123