diff options
author | Clement Courbet <courbet@google.com> | 2016-07-22 12:42:19 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2016-07-22 12:42:19 +0000 |
commit | f67fbfaa8c627bfbc628adecd4eed80fd85100b4 (patch) | |
tree | 391ced0e52aa55a963cb8753d8defe44d642fdda /clang-tools-extra/test | |
parent | a81f4728f370541c8fd51bbad29771fa3c152069 (diff) | |
download | bcm5719-llvm-f67fbfaa8c627bfbc628adecd4eed80fd85100b4.tar.gz bcm5719-llvm-f67fbfaa8c627bfbc628adecd4eed80fd85100b4.zip |
[clang-tidy] new cppcoreguidelines-slicing
Flags slicing of member variables or vtable. See:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es63-dont-slice
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c145-access-polymorphic-objects-through-pointers-and-references
Differential revision:
http://reviews.llvm.org/D21974
llvm-svn: 276408
Diffstat (limited to 'clang-tools-extra/test')
-rw-r--r-- | clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp new file mode 100644 index 00000000000..4fc22f9dc24 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-slicing.cpp @@ -0,0 +1,100 @@ +// 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}; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}}*sizeof(char) bytes of state [cppcoreguidelines-slicing] + a = b; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}}*sizeof(char) bytes of state + TakesBaseByValue(b); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}}*sizeof(char) bytes of state + + TwiceDerivedWithNoMemberVariables c; + a = c; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'TwiceDerivedWithNoMemberVariables' to 'Base' discards {{[0-9]*}}*sizeof(char) bytes of state + + a = ReturnsDerived(); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards 4*sizeof(char) bytes of state +} + +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' +} |