// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.PolymorphicPointers -verify %s

class base {
public:
	virtual void func(void) {
	}
};

class derived : public base {
public:
	int i;
	derived() { i = 0; }

	void func(void) {
	}
};

class derived2 : public derived {
public:
  int j;
  derived2() { j = 0; }
};

void foo1(void) {
	derived d[3];

  // check for implicit cast to base pointer
  base *bp = d;  // expected-warning{{Using a base pointer to an array of a derived type is unsafe because of possible size differences.}}
}

void fum(base *);

void foo2(void) {
  base b[3];
  derived d[3];

  // verify that don't give error on base class
  fum(b);  // no-warning
  // check for implicit cast as base pointer argument
	fum(d);  // expected-warning{{Using a base pointer to an array of a derived type is unsafe because of possible size differences.}}
}

void foo3(void) {
  derived2 d2[3];

  // derived to previous
  derived *dp = d2;  // expected-warning{{Using a base pointer to an array of a derived type is unsafe because of possible size differences.}}
}

void foo4(void) {
  derived2 d2[3];

  // derived to true base
  base *bp = d2;  // expected-warning{{Using a base pointer to an array of a derived type is unsafe because of possible size differences.}}
}

