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 {{{{^}}Taking true branch}} 168 // expected-note-re@-3 {{{{^}}Taking false branch}} 169 #endif 170 X x(i - 1); 171 #if !PUREONLY 172 // expected-note-re@-2 {{{{^}}Calling constructor for 'X'}} 173 #endif 174 x.g(); // no warning 175 } 176 g(); 177 #if !PUREONLY 178 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 179 // expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}} 180 // expected-note-re@-4 {{{{^}}Call to virtual function during construction}} 181 #endif 182 } 183 virtual void g(); 184 }; 185 186 class M; 187 class N { 188 public: 189 virtual void virtualMethod(); 190 void callFooOfM(M *); 191 }; 192 class M { 193 public: 194 M() { 195 N n; 196 n.virtualMethod(); // no warning 197 n.callFooOfM(this); 198 #if !PUREONLY 199 // expected-note-re@-2 {{{{^}}This constructor of an object of type 'M' has not returned when the virtual method was called}} 200 // expected-note-re@-3 {{{{^}}Calling 'N::callFooOfM'}} 201 #endif 202 } 203 virtual void foo(); 204 }; 205 void N::callFooOfM(M *m) { 206 m->foo(); 207 #if !PUREONLY 208 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 209 // expected-note-re@-3 {{{{^}}Call to virtual function during construction}} 210 #endif 211 } 212 213 class Y { 214 public: 215 virtual void foobar(); 216 void fooY() { 217 F f1; 218 foobar(); 219 #if !PUREONLY 220 // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}} 221 // expected-note-re@-3 {{{{^}}Call to virtual function during construction}} 222 #endif 223 } 224 Y() { fooY(); } 225 #if !PUREONLY 226 // expected-note-re@-2 {{{{^}}This constructor of an object of type 'Y' has not returned when the virtual method was called}} 227 // expected-note-re@-3 {{{{^}}Calling 'Y::fooY'}} 228 #endif 229 }; 230 231 int main() { 232 B b; 233 #if PUREONLY 234 //expected-note-re@-2 {{{{^}}Calling default constructor for 'B'}} 235 #else 236 //expected-note-re@-4 2{{{{^}}Calling default constructor for 'B'}} 237 #endif 238 C c; 239 #if !PUREONLY 240 //expected-note-re@-2 {{{{^}}Calling default constructor for 'C'}} 241 #endif 242 D d; 243 E e; 244 F f; 245 G g; 246 H h; 247 H h1(1); 248 #if !PUREONLY 249 //expected-note-re@-2 {{{{^}}Calling constructor for 'H'}} 250 //expected-note-re@-3 {{{{^}}Calling constructor for 'H'}} 251 #endif 252 X x; 253 #if !PUREONLY 254 //expected-note-re@-2 {{{{^}}Calling default constructor for 'X'}} 255 #endif 256 X x1(1); 257 #if !PUREONLY 258 //expected-note-re@-2 {{{{^}}Calling constructor for 'X'}} 259 #endif 260 M m; 261 #if !PUREONLY 262 //expected-note-re@-2 {{{{^}}Calling default constructor for 'M'}} 263 #endif 264 Y *y = new Y; 265 delete y; 266 header::Z z; 267 #if !PUREONLY 268 // expected-note-re@-2 {{{{^}}Calling default constructor for 'Z'}} 269 #endif 270 } 271 #if !PUREONLY 272 //expected-note-re@-2 2{{{{^}}Calling '~E'}} 273 #endif 274 275 namespace PR34451 { 276 struct a { 277 void b() { 278 a c[1]; 279 c->b(); 280 } 281 }; 282 283 class e { 284 public: 285 void b() const; 286 }; 287 288 class c { 289 void m_fn2() const; 290 e d[]; 291 }; 292 293 void c::m_fn2() const { d->b(); } 294 } 295