// -mretpoline does not work yet on Darwin.
// XFAIL: darwin

// RUN: %clangxx_cfi -o %t %s
// RUN: %run %t
// RUN: %clangxx_cfi -mretpoline -o %t2 %s
// RUN: %run %t2

// Tests that the CFI mechanism does not crash the program when making various
// kinds of valid calls involving classes with various different linkages and
// types of inheritance, and both virtual and non-virtual member functions.

#include "utils.h"

struct A {
  virtual void f();
  void g();
};

void A::f() {}
void A::g() {}

struct A2 : A {
  virtual void f();
  void g();
};

void A2::f() {}
void A2::g() {}

struct B {
  virtual void f() {}
  void g() {}
};

struct B2 : B {
  virtual void f() {}
  void g() {}
};

namespace {

struct C {
  virtual void f();
  void g();
};

void C::f() {}
void C::g() {}

struct C2 : C {
  virtual void f();
  void g();
};

void C2::f() {}
void C2::g() {}

struct D {
  virtual void f() {}
  void g() {}
};

struct D2 : D {
  virtual void f() {}
  void g() {}
};

}

struct E {
  virtual void f() {}
  void g() {}
};

struct E2 : virtual E {
  virtual void f() {}
  void g() {}
};

int main() {
  A *a = new A;
  break_optimization(a);
  a->f();
  a->g();
  a = new A2;
  break_optimization(a);
  a->f();
  a->g();

  B *b = new B;
  break_optimization(b);
  b->f();
  b->g();
  b = new B2;
  break_optimization(b);
  b->f();
  b->g();

  C *c = new C;
  break_optimization(c);
  c->f();
  c->g();
  c = new C2;
  break_optimization(c);
  c->f();
  c->g();

  D *d = new D;
  break_optimization(d);
  d->f();
  d->g();
  d = new D2;
  break_optimization(d);
  d->f();
  d->g();

  E *e = new E;
  break_optimization(e);
  e->f();
  e->g();
  e = new E2;
  break_optimization(e);
  e->f();
  e->g();
}
