Index: virtualcall.cpp =================================================================== --- virtualcall.cpp +++ virtualcall.cpp @@ -1,15 +1,3 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s -// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s -// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s - -/* When INTERPROCEDURAL is set, we expect diagnostics in all functions reachable - from a constructor or destructor. If it is not set, we expect diagnostics - only in the constructor or destructor. - - When PUREONLY is set, we expect diagnostics only for calls to pure virtual - functions not to non-pure virtual functions. -*/ - class A { public: A(); @@ -17,13 +5,11 @@ ~A() {}; - virtual int foo() = 0; // from Sema: expected-note {{'foo' declared here}} - virtual void bar() = 0; + virtual int foo()=0; // from Sema: expected-note {{'foo' declared here}} + virtual void bar()=0; void f() { foo(); -#if INTERPROCEDURAL - // expected-warning-re@-2 {{{{^}}Call Path : foo <-- fCall to pure virtual function during construction has undefined behavior}} -#endif + // expected-warning:Call to virtual function during construction } }; @@ -31,22 +17,13 @@ public: B() { foo(); -#if !PUREONLY -#if INTERPROCEDURAL - // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}} -#else - // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}} -#endif -#endif - + // expected-warning:Call to virtual function during construction } ~B(); virtual int foo(); virtual void bar() { foo(); } -#if INTERPROCEDURAL - // expected-warning-re@-2 {{{{^}}Call Path : foo <-- barCall to virtual function during destruction will not dispatch to derived class}} -#endif + // expected-warning:Call to virtual function during destruction }; A::A() { @@ -55,25 +32,14 @@ A::A(int i) { foo(); // From Sema: expected-warning {{call to pure virtual member function 'foo' has undefined behavior}} -#if INTERPROCEDURAL - // expected-warning-re@-2 {{{{^}}Call Path : fooCall to pure virtual function during construction has undefined behavior}} -#else - // expected-warning-re@-4 {{{{^}}Call to pure virtual function during construction has undefined behavior}} -#endif + // expected-warning:Call to virtual function during construction } B::~B() { this->B::foo(); // no-warning this->B::bar(); this->foo(); -#if !PUREONLY -#if INTERPROCEDURAL - // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during destruction will not dispatch to derived class}} -#else - // expected-warning-re@-5 {{{{^}}Call to virtual function during destruction will not dispatch to derived class}} -#endif -#endif - + // expected-warning:Call to virtual function during destruction } class C : public B { @@ -87,13 +53,7 @@ C::C() { f(foo()); -#if !PUREONLY -#if INTERPROCEDURAL - // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}} -#else - // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}} -#endif -#endif + // expected-warning:Call to virtual function during construction } class D : public B { @@ -115,7 +75,6 @@ int foo() override; }; -// Regression test: don't crash when there's no direct callee. class F { public: F() { @@ -125,17 +84,65 @@ void foo(); }; -int main() { - A *a; - B *b; - C *c; - D *d; - E *e; - F *f; -} +class G { +public: + virtual void bar(); + void foo() { + bar(); + // no warning + } +}; -#include "virtualcall.h" +class H{ +public: + H() : initState(0) { init(); } + int initState; + virtual void f() const; + void init() { + if (initState) + f(); + // no warning + } -#define AS_SYSTEM -#include "virtualcall.h" -#undef AS_SYSTEM + H(int i) { + G g; + g.foo(); + g.bar(); + // no warning + f(); + // expected-warning:Call to virtual function during construction + H& h = *this; + h.f(); + // expected-warning:Call to virtual function during construction + } +}; + +class X { +public: + X() { + g(); + // expected-warning:Call to virtual function during construction + } + X(int i) { + if (i > 0) { + X x(i-1); + x.g(); + // no warning + } + g(); + // expected-warning:Call to virtual function during construction + } + virtual void g(); +}; + +int main() { + + B b; + C c; + D d; + E e; + F f; + G g; + H h; + X x; +}