multiple-inheritance.cpp revision 86277eb844c4983c81de62d7c050e92fe7155788
1// RUN: %clangxx_cfi -o %t %s 2// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 3// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s 4 5// RUN: %clangxx_cfi -DB32 -o %t %s 6// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 7// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s 8 9// RUN: %clangxx_cfi -DB64 -o %t %s 10// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 11// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s 12 13// RUN: %clangxx_cfi -DBM -o %t %s 14// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 15// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s 16 17// RUN: %clangxx -o %t %s 18// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s 19// RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s 20 21// Tests that the CFI mechanism is sensitive to multiple inheritance and only 22// permits calls via virtual tables for the correct base class. 23 24#include <stdio.h> 25#include "utils.h" 26 27struct A { 28 virtual void f() = 0; 29}; 30 31struct B { 32 virtual void g() = 0; 33}; 34 35struct C : A, B { 36 virtual void f(), g(); 37}; 38 39void C::f() {} 40void C::g() {} 41 42int main(int argc, char **argv) { 43#ifdef B32 44 break_optimization(new Deriver<A, 0>); 45 break_optimization(new Deriver<B, 0>); 46#endif 47 48#ifdef B64 49 break_optimization(new Deriver<A, 0>); 50 break_optimization(new Deriver<A, 1>); 51 break_optimization(new Deriver<B, 0>); 52 break_optimization(new Deriver<B, 1>); 53#endif 54 55#ifdef BM 56 break_optimization(new Deriver<A, 0>); 57 break_optimization(new Deriver<A, 1>); 58 break_optimization(new Deriver<A, 2>); 59 break_optimization(new Deriver<B, 0>); 60 break_optimization(new Deriver<B, 1>); 61 break_optimization(new Deriver<B, 2>); 62#endif 63 64 C *c = new C; 65 break_optimization(c); 66 67 // CFI: 1 68 // NCFI: 1 69 fprintf(stderr, "1\n"); 70 71 if (argc > 1) { 72 A *a = c; 73 ((B *)a)->g(); // UB here 74 } else { 75 B *b = c; 76 ((A *)b)->f(); // UB here 77 } 78 79 // CFI-NOT: 2 80 // NCFI: 2 81 fprintf(stderr, "2\n"); 82} 83