1 // RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-output=text -verify -std=c++11 %s 2 3 // RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -analyzer-output=text -verify -std=c++11 %s 4 5 #include "virtualcall.h" 6 7 class A { 8 public: 9 A(); 10 11 ~A(){}; 12 13 virtual int foo() = 0; 14 virtual void bar() = 0; 15 void f() { 16 foo(); 17 // expected-warning-re@-1 {{{{^}}Call to pure virtual function during construction}} 18 // expected-note-re@-2 {{{{^}}Call to pure virtual function during construction}} 19 } 20 }; 21 22 class B : public A { 23 public: 24 B() { // expected-note {{Calling default constructor for 'A'}} 25 foo(); 26 #if !PUREONLY 27 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 28 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'B' has not returned when the virtual method was called}} 29 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 30 #endif 31 } 32 ~B(); 33 34 virtual int foo(); 35 virtual void bar() { 36 foo(); 37 #if !PUREONLY 38 // expected-warning-re@-2 {{{{^}}Call to virtual function during destruction}} 39 // expected-note-re@-3 {{{{^}}Call to virtual function during destruction}} 40 #endif 41 } 42 }; 43 44 A::A() { 45 f(); 46 // expected-note-re@-1 {{{{^}}This constructor of an object of type 'A' has not returned when the virtual method was called}} 47 // expected-note-re@-2 {{{{^}}Calling 'A::f'}} 48 } 49 50 B::~B() { 51 this->B::foo(); // no-warning 52 this->B::bar(); 53 #if !PUREONLY 54 // expected-note-re@-2 {{{{^}}This destructor of an object of type '~B' has not returned when the virtual method was called}} 55 // expected-note-re@-3 {{{{^}}Calling 'B::bar'}} 56 #endif 57 this->foo(); 58 #if !PUREONLY 59 // expected-warning-re@-2 {{{{^}}Call to virtual function during destruction}} 60 // expected-note-re@-3 {{{{^}}This destructor of an object of type '~B' has not returned when the virtual method was called}} 61 // expected-note-re@-4 {{{{^}}Call to virtual function during destruction}} 62 #endif 63 64 } 65 66 class C : public B { 67 public: 68 C(); 69 ~C(); 70 71 virtual int foo(); 72 void f(int i); 73 }; 74 75 C::C() { 76 f(foo()); 77 #if !PUREONLY 78 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 79 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'C' has not returned when the virtual method was called}} 80 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 81 #endif 82 } 83 84 class D : public B { 85 public: 86 D() { 87 foo(); // no-warning 88 } 89 ~D() { bar(); } 90 int foo() final; 91 void bar() final { foo(); } // no-warning 92 }; 93 94 class E final : public B { 95 public: 96 E() { 97 foo(); // no-warning 98 } 99 ~E() { bar(); } 100 #if !PUREONLY 101 // expected-note-re@-2 2{{{{^}}Calling '~B'}} 102 #endif 103 int foo() override; 104 }; 105 106 class F { 107 public: 108 F() { 109 void (F::*ptr)() = &F::foo; 110 (this->*ptr)(); 111 } 112 void foo(); 113 }; 114 115 class G { 116 public: 117 G() {} 118 virtual void bar(); 119 void foo() { 120 bar(); // no warning 121 } 122 }; 123 124 class H { 125 public: 126 H() : initState(0) { init(); } 127 int initState; 128 virtual void f() const; 129 void init() { 130 if (initState) 131 f(); // no warning 132 } 133 134 H(int i) { 135 G g; 136 g.foo(); 137 g.bar(); // no warning 138 f(); 139 #if !PUREONLY 140 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 141 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'H' has not returned when the virtual method was called}} 142 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 143 #endif 144 H &h = *this; 145 h.f(); 146 #if !PUREONLY 147 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 148 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'H' has not returned when the virtual method was called}} 149 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 150 #endif 151 } 152 }; 153 154 class X { 155 public: 156 X() { 157 g(); 158 #if !PUREONLY 159 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 160 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}} 161 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 162 #endif 163 } 164 X(int i) { 165 if (i > 0) { 166 #if !PUREONLY 167 // expected-note-re@-2 {{{{^}}'i' is > 0}} 168 // expected-note-re@-3 {{{{^}}Taking true branch}} 169 // expected-note-re@-4 {{{{^}}'i' is <= 0}} 170 // expected-note-re@-5 {{{{^}}Taking false branch}} 171 #endif 172 X x(i - 1); 173 #if !PUREONLY 174 // expected-note-re@-2 {{{{^}}Calling constructor for 'X'}} 175 #endif 176 x.g(); // no warning 177 } 178 g(); 179 #if !PUREONLY 180 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 181 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}} 182 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 183 #endif 184 } 185 virtual void g(); 186 }; 187 188 class M; 189 class N { 190 public: 191 virtual void virtualMethod(); 192 void callFooOfM(M *); 193 }; 194 class M { 195 public: 196 M() { 197 N n; 198 n.virtualMethod(); // no warning 199 n.callFooOfM(this); 200 #if !PUREONLY 201 // expected-note-re@-2 {{{{^}}This constructor of an object of type 'M' has not returned when the virtual method was called}} 202 // expected-note-re@-3 {{{{^}}Calling 'N::callFooOfM'}} 203 #endif 204 } 205 virtual void foo(); 206 }; 207 void N::callFooOfM(M *m) { 208 m->foo(); 209 #if !PUREONLY 210 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 211 // expected-note-re@-3 {{{{^}}Call to virtual function during construction}} 212 #endif 213 } 214 215 class Y { 216 public: 217 virtual void foobar(); 218 void fooY() { 219 F f1; 220 foobar(); 221 #if !PUREONLY 222 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 223 // expected-note-re@-3 {{{{^}}Call to virtual function during construction}} 224 #endif 225 } 226 Y() { fooY(); } 227 #if !PUREONLY 228 // expected-note-re@-2 {{{{^}}This constructor of an object of type 'Y' has not returned when the virtual method was called}} 229 // expected-note-re@-3 {{{{^}}Calling 'Y::fooY'}} 230 #endif 231 }; 232 233 int main() { 234 B b; 235 #if PUREONLY 236 //expected-note-re@-2 {{{{^}}Calling default constructor for 'B'}} 237 #else 238 //expected-note-re@-4 2{{{{^}}Calling default constructor for 'B'}} 239 #endif 240 C c; 241 #if !PUREONLY 242 //expected-note-re@-2 {{{{^}}Calling default constructor for 'C'}} 243 #endif 244 D d; 245 E e; 246 F f; 247 G g; 248 H h; 249 H h1(1); 250 #if !PUREONLY 251 //expected-note-re@-2 {{{{^}}Calling constructor for 'H'}} 252 //expected-note-re@-3 {{{{^}}Calling constructor for 'H'}} 253 #endif 254 X x; 255 #if !PUREONLY 256 //expected-note-re@-2 {{{{^}}Calling default constructor for 'X'}} 257 #endif 258 X x1(1); 259 #if !PUREONLY 260 //expected-note-re@-2 {{{{^}}Calling constructor for 'X'}} 261 #endif 262 M m; 263 #if !PUREONLY 264 //expected-note-re@-2 {{{{^}}Calling default constructor for 'M'}} 265 #endif 266 Y *y = new Y; 267 #if !PUREONLY 268 //expected-note-re@-2 {{{{^}}Calling default constructor for 'Y'}} 269 #endif 270 delete y; 271 header::Z z; 272 #if !PUREONLY 273 // expected-note-re@-2 {{{{^}}Calling default constructor for 'Z'}} 274 #endif 275 } 276 #if !PUREONLY 277 //expected-note-re@-2 2{{{{^}}Calling '~E'}} 278 #endif 279 280 namespace PR34451 { 281 struct a { 282 void b() { 283 a c[1]; 284 c->b(); 285 } 286 }; 287 288 class e { 289 public: 290 void b() const; 291 }; 292 293 class c { 294 void m_fn2() const; 295 e d[]; 296 }; 297 298 void c::m_fn2() const { d->b(); } 299 } 300