141 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-pointer-arithmetic-on-polymorphic-object %t --2 3class Base {4public: 5 virtual ~Base() {}6};7 8class Derived : public Base {};9 10class FinalDerived final : public Base {};11 12class AbstractBase {13public:14 virtual void f() = 0;15 virtual ~AbstractBase() {}16};17 18class AbstractInherited : public AbstractBase {};19 20class AbstractOverride : public AbstractInherited {21public:22 void f() override {}23};24 25void operators() {26 Base *b = new Derived[10];27 28 b += 1;29 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base' can result in undefined behavior if the dynamic type differs from the pointer type [bugprone-pointer-arithmetic-on-polymorphic-object]30 31 b = b + 1;32 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer arithmetic on polymorphic object of type 'Base' can result in undefined behavior if the dynamic type differs from the pointer type [bugprone-pointer-arithmetic-on-polymorphic-object]33 34 b++;35 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base' can result in undefined behavior if the dynamic type differs from the pointer type [bugprone-pointer-arithmetic-on-polymorphic-object]36 37 --b;38 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pointer arithmetic on polymorphic object of type 'Base' can result in undefined behavior if the dynamic type differs from the pointer type [bugprone-pointer-arithmetic-on-polymorphic-object]39 40 b[1];41 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base' can result in undefined behavior if the dynamic type differs from the pointer type [bugprone-pointer-arithmetic-on-polymorphic-object]42 43 delete[] static_cast<Derived*>(b);44}45 46void subclassWarnings() {47 Base *b = new Base[10];48 49 // False positive that's impossible to distinguish without50 // path-sensitive analysis, but the code is bug-prone regardless.51 b += 1;52 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base'53 54 delete[] b;55 56 // Common false positive is a class that overrides all parent functions.57 // Is a warning because of the check configuration.58 Derived *d = new Derived[10];59 60 d += 1;61 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Derived'62 63 delete[] d;64 65 // Final classes cannot have a dynamic type.66 FinalDerived *fd = new FinalDerived[10];67 68 fd += 1;69 // no-warning70 71 delete[] fd;72}73 74void abstractWarnings() {75 // Classes with an abstract member funtion are always matched.76 AbstractBase *ab = new AbstractOverride[10];77 78 ab += 1;79 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'AbstractBase'80 81 delete[] static_cast<AbstractOverride*>(ab);82 83 AbstractInherited *ai = new AbstractOverride[10];84 85 ai += 1;86 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'AbstractInherited'87 88 delete[] static_cast<AbstractOverride*>(ai);89 90 // Is a warning because of the check configuration.91 AbstractOverride *ao = new AbstractOverride[10];92 93 ao += 1;94 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'AbstractOverride'95 96 delete[] ao;97}98 99template <typename T>100void templateWarning(T *t) {101 // FIXME: Tidy doesn't support template instantiation locations properly.102 t += 1;103 // no-warning104}105 106void functionArgument(Base *b) {107 b += 1;108 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base'109 110 templateWarning(b);111}112 113using BaseAlias = Base;114using DerivedAlias = Derived;115using FinalDerivedAlias = FinalDerived;116 117using BasePtr = Base*;118using DerivedPtr = Derived*;119using FinalDerivedPtr = FinalDerived*;120 121void typeAliases(BaseAlias *b, DerivedAlias *d, FinalDerivedAlias *fd,122 BasePtr bp, DerivedPtr dp, FinalDerivedPtr fdp) {123 b += 1;124 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base'125 126 d += 1;127 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Derived'128 129 fd += 1;130 // no-warning131 132 bp += 1;133 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base'134 135 dp += 1;136 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Derived'137 138 fdp += 1;139 // no-warning140}141