2016-07-22 21:45:00 +08:00
// RUN: %check_clang_tidy %s cppcoreguidelines-slicing %t
class Base {
int i ;
void f ( ) { }
virtual void g ( ) { }
} ;
class DerivedWithMemberVariables : public Base {
void f ( ) ;
int j ;
} ;
class TwiceDerivedWithNoMemberVariables : public DerivedWithMemberVariables {
void f ( ) ;
} ;
class DerivedWithOverride : public Base {
void f ( ) ;
void g ( ) override { }
} ;
class TwiceDerivedWithNoOverride : public DerivedWithOverride {
void f ( ) ;
} ;
void TakesBaseByValue ( Base base ) ;
DerivedWithMemberVariables ReturnsDerived ( ) ;
void positivesWithMemberVariables ( ) {
DerivedWithMemberVariables b ;
Base a { b } ;
2016-12-22 22:12:31 +08:00
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state [cppcoreguidelines-slicing]
2016-07-22 21:45:00 +08:00
a = b ;
2016-12-22 22:12:31 +08:00
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
2016-07-22 21:45:00 +08:00
TakesBaseByValue ( b ) ;
2016-12-22 22:12:31 +08:00
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
2016-07-22 21:45:00 +08:00
TwiceDerivedWithNoMemberVariables c ;
a = c ;
2016-12-22 22:12:31 +08:00
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'TwiceDerivedWithNoMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
2016-07-22 21:45:00 +08:00
a = ReturnsDerived ( ) ;
2016-12-22 22:12:31 +08:00
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
2016-07-22 21:45:00 +08:00
}
void positivesWithOverride ( ) {
DerivedWithOverride b ;
Base a { b } ;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
a = b ;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
TakesBaseByValue ( b ) ;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
TwiceDerivedWithNoOverride c ;
a = c ;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
}
void TakesBaseByReference ( Base & base ) ;
class DerivedThatAddsVirtualH : public Base {
virtual void h ( ) ;
} ;
class DerivedThatOverridesH : public DerivedThatAddsVirtualH {
void h ( ) override ;
} ;
void negatives ( ) {
// OK, simple copying from the same type.
Base a ;
TakesBaseByValue ( a ) ;
DerivedWithMemberVariables b ;
DerivedWithMemberVariables c { b } ;
b = c ;
// OK, derived type does not have extra state.
TwiceDerivedWithNoMemberVariables d ;
DerivedWithMemberVariables e { d } ;
e = d ;
// OK, derived does not override any method.
TwiceDerivedWithNoOverride f ;
DerivedWithOverride g { f } ;
g = f ;
// OK, no copying.
TakesBaseByReference ( d ) ;
TakesBaseByReference ( f ) ;
// Derived type overrides methods, but these methods are not in the base type,
// so cannot be called accidentally. Right now this triggers, but we might
// want to allow it.
DerivedThatOverridesH h ;
a = h ;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
}