1*034badb3SDmitry Mikulin // Test that virtual functions of the derived class can be called through 2*034badb3SDmitry Mikulin // pointers of both base classes without CFI errors. 3*034badb3SDmitry Mikulin // Related to Bugzilla 43390. 4*034badb3SDmitry Mikulin 5*034badb3SDmitry Mikulin // RUN: %clangxx_cfi -o %t1 %s 6*034badb3SDmitry Mikulin // RUN: %run %t1 2>&1 | FileCheck --check-prefix=CFI %s 7*034badb3SDmitry Mikulin 8*034badb3SDmitry Mikulin // CFI: In f1 9*034badb3SDmitry Mikulin // CFI: In f2 10*034badb3SDmitry Mikulin // CFI-NOT: control flow integrity check 11*034badb3SDmitry Mikulin 12*034badb3SDmitry Mikulin // REQUIRES: cxxabi 13*034badb3SDmitry Mikulin 14*034badb3SDmitry Mikulin #include <stdio.h> 15*034badb3SDmitry Mikulin 16*034badb3SDmitry Mikulin class A1 { 17*034badb3SDmitry Mikulin public: 18*034badb3SDmitry Mikulin virtual void f1() = 0; 19*034badb3SDmitry Mikulin }; 20*034badb3SDmitry Mikulin 21*034badb3SDmitry Mikulin class A2 { 22*034badb3SDmitry Mikulin public: 23*034badb3SDmitry Mikulin virtual void f2() = 0; 24*034badb3SDmitry Mikulin }; 25*034badb3SDmitry Mikulin 26*034badb3SDmitry Mikulin 27*034badb3SDmitry Mikulin class B : public A1, public A2 { 28*034badb3SDmitry Mikulin public: f2()29*034badb3SDmitry Mikulin void f2() final { fprintf(stderr, "In f2\n"); } f1()30*034badb3SDmitry Mikulin void f1() final { fprintf(stderr, "In f1\n"); } 31*034badb3SDmitry Mikulin }; 32*034badb3SDmitry Mikulin main()33*034badb3SDmitry Mikulinint main() { 34*034badb3SDmitry Mikulin B b; 35*034badb3SDmitry Mikulin 36*034badb3SDmitry Mikulin static_cast<A1*>(&b)->f1(); 37*034badb3SDmitry Mikulin static_cast<A2*>(&b)->f2(); 38*034badb3SDmitry Mikulin } 39