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 without
52 // 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-warning
63
64 delete[] d;
65
66 // Final classes cannot have a dynamic type.
67 FinalDerived *fd = new FinalDerived[10];
68
69 fd += 1;
70 // no-warning
71
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-warning
96
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-warning
105}
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(t: 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-warning
129
130 fd += 1;
131 // no-warning
132
133 bp += 1;
134 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on polymorphic object of type 'Base'
135
136 dp += 1;
137 // no-warning
138
139 fdp += 1;
140 // no-warning
141}
142

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/pointer-arithmetic-on-polymorphic-object-decl-only.cpp