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