bugprone-virtual-near-miss.cpp
4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// RUN: %check_clang_tidy %s bugprone-virtual-near-miss %t
class NoDefinedClass1;
class NoDefinedClass2;
struct Base {
virtual void func();
virtual void gunk();
virtual ~Base();
virtual Base &operator=(const Base &);
virtual NoDefinedClass1 *f();
};
struct Derived : Base {
// Should not warn "do you want to override 'gunk'?", because gunk is already
// overriden by this class.
virtual void funk();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::funk' has a similar name and the same signature as virtual method 'Base::func'; did you mean to override it? [bugprone-virtual-near-miss]
// CHECK-FIXES: virtual void func();
void func2();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::func2' has {{.*}} 'Base::func'
// CHECK-FIXES: void func();
void func22(); // Should not warn.
void gunk(); // Should not warn: gunk is override.
void fun();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::fun' has {{.*}} 'Base::func'
// CHECK-FIXES: void func();
Derived &operator==(const Base &); // Should not warn: operators are ignored.
virtual NoDefinedClass2 *f1(); // Should not crash: non-defined class return type is ignored.
};
template <typename T>
struct TBase {
virtual void tfunc(T t);
};
template <typename T>
struct TDerived : TBase<T> {
virtual void tfunk(T t);
// Should not apply fix for template.
// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc'
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc'
// CHECK-FIXES: virtual void tfunk(T t);
};
TDerived<int> T1;
TDerived<double> T2;
// Should not fix macro definition
#define MACRO1 void funcM()
// CHECK-FIXES: #define MACRO1 void funcM()
#define MACRO2(m) void m()
// CHECK-FIXES: #define MACRO2(m) void m()
struct DerivedMacro : Base {
MACRO1;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::funcM' has {{.*}} 'Base::func'
// CHECK-FIXES: MACRO1;
MACRO2(func3);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::func3' has {{.*}} 'Base::func'
// CHECK-FIXES: MACRO2(func);
};
typedef Derived derived_type;
class Father {
public:
Father();
virtual void func();
virtual Father *create(int i);
virtual Base &&generate();
virtual Base *canonical(Derived D);
};
class Mother {
public:
Mother();
static void method();
virtual int method(int argc, const char **argv);
virtual int method(int argc) const;
virtual int decay(const char *str);
};
class Child : private Father, private Mother {
public:
Child();
virtual void func2();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::func2' has {{.*}} 'Father::func'
// CHECK-FIXES: virtual void func();
int methoe(int x, char **strs); // Should not warn: parameter types don't match.
int methoe(int x);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoe' has {{.*}} 'Mother::method'
// CHECK-FIXES: int method(int x);
void methof(int x, const char **strs); // Should not warn: return types don't match.
int methoh(int x, const char **strs);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoh' has {{.*}} 'Mother::method'
// CHECK-FIXES: int method(int x, const char **strs);
virtual Child *creat(int i);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::creat' has {{.*}} 'Father::create'
// CHECK-FIXES: virtual Child *create(int i);
virtual Derived &&generat();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::generat' has {{.*}} 'Father::generate'
// CHECK-FIXES: virtual Derived &&generate();
int decaz(const char str[]);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::decaz' has {{.*}} 'Mother::decay'
// CHECK-FIXES: int decay(const char str[]);
operator bool();
derived_type *canonica(derived_type D);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::canonica' has {{.*}} 'Father::canonical'
// CHECK-FIXES: derived_type *canonical(derived_type D);
private:
void funk();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::funk' has {{.*}} 'Father::func'
// CHECK-FIXES: void func();
};