brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 82285b6 Raw
206 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.VirtualCall \2// RUN:                    -analyzer-checker=debug.ExprInspection \3// RUN:                    -std=c++11 -verify=impure %s4 5// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.PureVirtualCall \6// RUN:                    -analyzer-checker=debug.ExprInspection \7// RUN:                    -std=c++11 -verify=pure -std=c++11 %s8 9// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.PureVirtualCall \10// RUN:                    -analyzer-checker=optin.cplusplus.VirtualCall \11// RUN:                    -analyzer-checker=debug.ExprInspection \12// RUN:                    -std=c++11 -verify=pure,impure -std=c++11 %s13 14#include "virtualcall.h"15 16void clang_analyzer_warnIfReached();17 18class A {19public:20  A();21 22  ~A(){};23 24  virtual int foo() = 0;25  virtual void bar() = 0;26  void f() {27    foo(); // pure-warning{{Call to pure virtual method 'A::foo' during construction has undefined behavior}}28    clang_analyzer_warnIfReached(); // no-warning29  }30};31 32A::A() {33  f();34}35 36class B {37public:38  B() {39    foo(); // impure-warning {{Call to virtual method 'B::foo' during construction bypasses virtual dispatch}}40  }41  ~B();42 43  virtual int foo();44  virtual void bar() {45    foo(); // impure-warning {{Call to virtual method 'B::foo' during destruction bypasses virtual dispatch}}46  }47};48 49B::~B() {50  this->B::foo(); // no-warning51  this->B::bar();52  this->foo(); // impure-warning {{Call to virtual method 'B::foo' during destruction bypasses virtual dispatch}}53}54 55class C : public B {56public:57  C();58  ~C();59 60  virtual int foo();61  void f(int i);62};63 64C::C() {65  f(foo()); // impure-warning {{Call to virtual method 'C::foo' during construction bypasses virtual dispatch}}66}67 68class D : public B {69public:70  D() {71    foo(); // no-warning72  }73  ~D() { bar(); }74  int foo() final;75  void bar() final { foo(); } // no-warning76};77 78class E final : public B {79public:80  E() {81    foo(); // no-warning82  }83  ~E() { bar(); }84  int foo() override;85};86 87class F {88public:89  F() {90    void (F::*ptr)() = &F::foo;91    (this->*ptr)();92  }93  void foo();94};95 96class G {97public:98  G() {}99  virtual void bar();100  void foo() {101    bar(); // no warning102  }103};104 105class H {106public:107  H() : initState(0) { init(); }108  int initState;109  virtual void f() const;110  void init() {111    if (initState)112      f(); // no warning113  }114 115  H(int i) {116    G g;117    g.foo();118    g.bar(); // no warning119    f(); // impure-warning {{Call to virtual method 'H::f' during construction bypasses virtual dispatch}}120    H &h = *this;121    h.f(); // impure-warning {{Call to virtual method 'H::f' during construction bypasses virtual dispatch}}122  }123};124 125class X {126public:127  X() {128    g(); // impure-warning {{Call to virtual method 'X::g' during construction bypasses virtual dispatch}}129  }130  X(int i) {131    if (i > 0) {132      X x(i - 1);133      x.g(); // no warning134    }135    g(); // impure-warning {{Call to virtual method 'X::g' during construction bypasses virtual dispatch}}136  }137  virtual void g();138};139 140class M;141class N {142public:143  virtual void virtualMethod();144  void callFooOfM(M *);145};146class M {147public:148  M() {149    N n;150    n.virtualMethod(); // no warning151    n.callFooOfM(this);152  }153  virtual void foo();154};155void N::callFooOfM(M *m) {156  m->foo(); // impure-warning {{Call to virtual method 'M::foo' during construction bypasses virtual dispatch}}157}158 159class Y {160public:161  virtual void foobar();162  void fooY() {163    F f1;164    foobar(); // impure-warning {{Call to virtual method 'Y::foobar' during construction bypasses virtual dispatch}}165  }166  Y() { fooY(); }167};168 169int main() {170  B b;171  C c;172  D d;173  E e;174  F f;175  G g;176  H h;177  H h1(1);178  X x; 179  X x1(1);180  M m;181  Y *y = new Y;182  delete y;183  header::Z z;184}185 186namespace PR34451 {187struct a {188  void b() {189    a c[1];190    c->b();191  }192};193 194class e {195 public:196  void b() const;197};198 199class c {200  void m_fn2() const;201  e d[];202};203 204void c::m_fn2() const { d->b(); }205}206